Security

Stylus SFTP Server provides multiple layers of security: cryptographic algorithm configuration, host key management, IP-based access control, geographic blocking, connection rate limiting, account lockout, multi-factor authentication (MFA), the AI & MCP token surface, path traversal prevention, and license enforcement. This chapter covers each mechanism and its configuration.

SSH Algorithm Configuration

Ciphers, MACs, and key-exchange algorithms are configurable via allow-lists in the <security> block of sftp-server.xml. The default configuration ships with a modern-only set — no CBC ciphers and no SHA-1 MACs. The server also supports post-quantum key exchange via mlkem768x25519-sha256.

If an allow-list is left empty, built-in defaults apply. These include legacy algorithms and are not recommended for production.

Unknown or unsupported algorithm names are logged at WARN level and silently skipped — the server continues to start with the remaining valid algorithms.

Default Ciphers

Cipher Notes
chacha20-poly1305@openssh.com AEAD stream cipher; preferred
aes256-gcm@openssh.com AEAD block cipher
aes128-gcm@openssh.com AEAD block cipher
aes256-ctr Counter mode; widely supported
aes192-ctr Counter mode
aes128-ctr Counter mode

Default MACs

MAC Notes
hmac-sha2-256-etm@openssh.com Encrypt-then-MAC; preferred
hmac-sha2-512-etm@openssh.com Encrypt-then-MAC
hmac-sha2-256 Standard HMAC
hmac-sha2-512 Standard HMAC

Default Key Exchange Algorithms

Algorithm Notes
mlkem768x25519-sha256 Post-quantum hybrid key exchange
curve25519-sha256 Modern elliptic-curve DH
ecdh-sha2-nistp256 NIST P-256 curve
ecdh-sha2-nistp384 NIST P-384 curve
ecdh-sha2-nistp521 NIST P-521 curve
diffie-hellman-group14-sha256 DH group 14 (2048-bit)
diffie-hellman-group16-sha512 DH group 16 (4096-bit)
diffie-hellman-group18-sha512 DH group 18 (8192-bit)

Legacy Algorithms (Disabled by Default)

The following algorithms are disabled by default due to known weaknesses. They can be re-enabled by adding them to the appropriate allow-list in sftp-server.xml if required for backward compatibility with older clients.

Algorithm Type Vulnerability
aes128-cbc Cipher CBC padding-oracle vulnerability
aes192-cbc Cipher CBC padding-oracle vulnerability
aes256-cbc Cipher CBC padding-oracle vulnerability
hmac-sha1 MAC SHA-1 weakness
hmac-sha1-etm@openssh.com MAC SHA-1 weakness
Warning Enabling legacy algorithms weakens the security posture of the server. Only re-enable them if you have clients that cannot be upgraded and you accept the risk.

Host Keys

On first startup, Stylus SFTP Server automatically generates SSH host key pairs for all three supported key types:

Host key files are stored in the conf/ directory by default. The paths are configurable in sftp-server.xml.

Tip Host keys should be backed up and preserved across upgrades. If host keys change, SFTP clients will display a "host key mismatch" warning, which can disrupt automated file transfer workflows.

IP Block List

Static IP addresses and CIDR ranges can be blocked via the <block-list> element in sftp-server.xml. Both IPv4 and IPv6 are supported. Blocked clients are disconnected immediately before the SSH handshake begins, minimizing resource consumption.

<block-list>
    <entry>10.0.0.0/8</entry>
    <entry>192.168.1.100</entry>
    <entry>2001:db8::/32</entry>
</block-list>

Connection Rate Limiting

The connection rate limiter tracks connections per source IP using a sliding window. When a client exceeds the allowed threshold, its IP is automatically blacklisted for a configurable duration.

Setting Description Default
max-connections Maximum connections allowed within the interval. Set to 0 to disable rate limiting.
interval-seconds Length of the sliding window in seconds. 60
blacklist-duration-minutes Duration (in minutes) for which an offending IP is auto-blacklisted. 30

Auto-blacklisted IPs are treated identically to entries in the static block list — connections are refused before the SSH handshake.

Note Setting max-connections to 0 disables rate limiting entirely. The static block list remains active regardless of this setting.

GeoIP Country Blocking

Stylus SFTP Server can restrict connections by country of origin using a MaxMind GeoIP database. The server supports both .mmdb (binary) and .csv formats.

Setup

  1. Obtain a GeoIP database file from MaxMind (GeoLite2 Country or GeoIP2 Country).
  2. Place the .mmdb or .csv file in the geodb/ folder under the data directory.
  3. Configure the blocking mode and country list in sftp-server.xml.

Configuration

<geo-blocking>
    <mode>allow</mode>
    <countries>US, CA, GB</countries>
</geo-blocking>
Setting Description
mode allow (whitelist — only listed countries permitted) or deny (blacklist — listed countries blocked)
countries Comma-separated ISO 3166-1 alpha-2 country codes (e.g., US, CA, GB, DE)

CSV Format

If you do not have a MaxMind .mmdb file, you can provide a plain CSV file with three columns: ip_from, ip_to, and country_code.

ip_from,ip_to,country_code
"16777216","16777471","AU"
"16777472","16778239","CN"
"16778240","16779263","AU"
ColumnDescription
ip_from Start of IP range. Numeric (e.g. 16777216) or dotted-decimal (e.g. 1.0.0.0).
ip_to End of IP range (inclusive). Same format as ip_from.
country_code ISO 3166-1 alpha-2 country code (e.g. US, GB, DE). Must be exactly 2 characters.

Format rules:

Tip Free CSV GeoIP databases are available from providers such as DB-IP Lite and IP2Location LITE. Ensure the CSV has ip_from, ip_to, country_code columns (reorder or rename if needed).

How It Works

Tip MaxMind updates their GeoLite2 databases weekly. To update, simply replace the file in the geodb/ folder. The server detects the change and re-imports automatically.

Account Lockout

To protect against brute-force password attacks, Stylus SFTP Server tracks consecutive authentication failures per account. After the configured threshold is exceeded, the account is locked for a specified duration.

Enabled by default. Account lockout is on out of the box — 5 consecutive failures lock the account for 30 minutes, even when no <password-policy> block is present. Set lockout-threshold to 0 to disable it.
<password-policy>
    <lockout-threshold>5</lockout-threshold>
    <lockout-duration-minutes>30</lockout-duration-minutes>
</password-policy>
Setting Description Default
lockout-threshold Number of consecutive failed authentication attempts before lockout. 5
lockout-duration-minutes Duration (in minutes) the account remains locked. 30

Lockout state is tracked in the sftp_lockout database table, so it survives server restarts. A successful authentication resets the failure counter.

Administrator Unlock

An administrator can unlock a locked account immediately using the CLI tool:

admin unlock-user <username>

Multi-Factor Authentication (MFA)

TOTP-based multi-factor authentication adds a second verification step to password authentication. Configure MFA in the <mfa> block of sftp-server.xml:

MFA per protocol

The MFA policy is enforced on every protocol that supports interactive login, but the challenge-response shape differs by protocol:

Protocol Behavior when MFA is required
Web File Transfer Portal Two-step form — username + password on the login card, then a code prompt after a successful password. TOTP or a recovery code accepted. Self-service enrollment available from the Portal header.
Web Admin Console Same two-step flow. Governed by <admin-required> below — even when the SFTP <policy> is optional, admin MFA can be enforced independently.
SFTP Uses the SSH keyboard-interactive method. After a valid password the server issues a second prompt for the TOTP code. Public-key logins bypass MFA entirely (the key is already a second factor).
FTP / FTPS The FTP command sequence has no native second-factor prompt. When MFA is required for the user, the login command is rejected with a message directing the operator to log in via the Portal first. Automated FTPS clients should use a dedicated service-account with MFA excluded (typically via a group whose mfa_required flag is off).
WebDAV HTTP Basic Auth carries only a single credential, so WebDAV clients cannot answer a TOTP prompt. WebDAV honors MFA the same way FTP does — the connection is refused when the user's effective policy requires MFA. Use a per-account read-only service credential for automated WebDAV mounts.
<mfa>
    <policy>optional</policy>
    <issuer>Stylus SFTP Server</issuer>
    <window-size>1</window-size>
    <recovery-codes>8</recovery-codes>
    <admin-required>false</admin-required>
</mfa>
Element Description Default
<policy> MFA enforcement level: disabled, optional, or required. disabled
<issuer> Display name shown in authenticator apps (e.g., Google Authenticator) alongside the account label. Stylus SFTP Server
<window-size> Number of 30-second time steps to accept before and after the current step. A value of 1 means codes valid from −30s to +30s (a 90-second window total). 1
<recovery-codes> Number of one-time recovery codes generated per enrollment. 8
<admin-required> Whether web admin console users must also enroll in MFA. false

Enrollment and authenticator labels

SFTP users self-enroll from the File Transfer Portal header. Admin-console users enroll from the Admin Users tab of the Web Admin console: select the account and choose the enroll (shield) action to display the QR code and one-time recovery codes, then confirm with a code from the authenticator app to activate. The same operations are available from the CLI — mfa-admin-enroll, mfa-admin-disable, and mfa-admin-status for admin accounts, and mfa-enroll / mfa-reset / mfa-disable / mfa-status for SFTP users.

Telling multiple servers apart in your authenticator. When you enroll through the Web Admin console or CLI, the server automatically appends its host name to the issuer label stored in your authenticator app — for example Stylus SFTP Server (sftp.example.com). If you administer more than one Stylus SFTP Server instance, each enrollment therefore appears under a distinct entry instead of colliding as identical Stylus SFTP Server / admin rows. The host portion is derived from the address you used to reach the console, so enroll from the hostname you normally use for that server.

Database Tables

MFA state is stored in four auto-created database tables:

Table Purpose
sftp_user_mfa TOTP secret and enrollment status for SFTP users.
sftp_mfa_recovery BCrypt-hashed recovery codes for SFTP users.
sftp_admin_mfa TOTP secret and enrollment status for admin users.
sftp_admin_mfa_recovery BCrypt-hashed recovery codes for admin users.

Audit Events

All MFA operations generate audit events that are recorded by every enabled audit sink. See the Audit Trail chapter for the full event list.

Tip Start with optional policy to allow users to enroll at their own pace. Switch to required after all users have enrolled. Use the mfa-status admin command to check enrollment progress.

AI & MCP Token Surface

When AI Integration is enabled, the Knowledge Base exposes a Model Context Protocol (MCP) endpoint that AI assistants authenticate to with bearer tokens, entirely separate from the SFTP/FTPS/Portal login providers. This section summarizes the security properties of that surface; the operational walkthrough lives in Knowledge Base → Connecting AI Assistants.

Path Traversal Prevention

All filesystem operations enforce strict path confinement. After resolving a requested path (including symbolic links), the server verifies that the resolved path starts with the user's home directory:

resolved.startsWith(home)

Any attempt to escape the home directory — whether via ../ sequences, symbolic links, or absolute paths — is denied.

Additionally, the UsernameValidator rejects usernames containing .. sequences, preventing directory traversal attacks during home directory creation.

The Web File Transfer Portal applies the same path confinement checks, ensuring consistent security across both SFTP and browser-based access.

Activation Key

Stylus SFTP Server requires a valid activation key to operate. The key is cryptographically signed and verified at startup and periodically at runtime.

Property Value
Signature algorithm ECDSA P-256 (SHA256withECDSA)
Maximum validity 366 days
Hot-reload interval Hourly — no restart needed for key renewal
Expiry warning Logged 30 days before expiration
Audit event LICENSE_REJECTED on key missing, expired, tampered, or corrupt

Place the activation.key file in the root of the data directory (${STYLUS_SFTPSERVER_DATA}/activation.key).

Warning The server refuses to start without a valid activation key. A LICENSE_REJECTED audit event is emitted before shutdown. The hourly runtime enforcer also checks key validity — if the key expires or the file is removed while the server is running, it will shut down after emitting the audit event.

Database Encryption at Rest

The internal H2 database is encrypted with AES (Advanced Encryption Standard) from the moment it is created. The database file on disk contains no readable data — table names, usernames, password hashes, audit records, and all other content are stored as AES-encrypted ciphertext.

How It Works

H2 supports transparent file-level encryption via the CIPHER=AES parameter in the JDBC connection URL. When enabled, H2 encrypts every page written to the .mv.db file using a file encryption password that is separate from the SQL authentication password.

Password Purpose Stored In
File encryption password Encrypts the database file on disk (AES). Required to open the .mv.db file at all. credentials.p12 as db.cipher-password
SQL user password Authenticates SQL connections (standard H2 authentication). credentials.p12 as db.password

Both passwords are randomly generated during installation (24 and 32 alphanumeric characters respectively) and stored in the PKCS12 credential store. They are never displayed, logged, or written to configuration files.

What This Protects Against

JDBC URL

The installer automatically adds ;CIPHER=AES to the JDBC URL in sftp-server.xml and admin-console.xml:

jdbc:h2:${STYLUS_SFTPSERVER_DATA}/db/sftpdb;AUTO_SERVER=TRUE;CIPHER=AES

At connection time, the server reads both passwords from the credential store and composes them in the format H2 expects: filePassword userPassword (space-separated). This is handled automatically — no manual configuration is needed.

Note Database encryption is enabled by default on all new installations using the built-in H2 database. External databases (MySQL, PostgreSQL) use their own encryption mechanisms and are not affected by this setting.
Warning If credentials.p12 or master.key is lost, the encrypted database cannot be recovered. Ensure these files are included in your backup strategy. See Credential Store for details.

Credential Store

Stylus SFTP Server stores sensitive credentials (database passwords, LDAP bind passwords, SMTP passwords) in a PKCS12 keystore file rather than in plain text inside XML configuration files.

Files

File Purpose
conf/credentials.p12 PKCS12 keystore containing encrypted credentials (DB username, DB password, LDAP bind password, SMTP password, keystore password).
conf/master.key Password that unlocks credentials.p12. Can also contain a cloud vault URI instead of the actual password.

Both files are created automatically during installation. The installer generates random passwords and sets the database password via ALTER USER. On upgrade, existing plain-text passwords are migrated from the XML files into the keystore.

Note When credentials.p12 does not exist, the server falls back to reading passwords from the XML configuration files as before. No manual migration is required.

Well-Known Credential Keys

Key Description
db.usernameDatabase username
db.passwordDatabase password
ldap.bind-passwordLDAP bind password
smtp.passwordSMTP authentication password
keystore.passwordFTP/TLS keystore password

Windows Group ACL

On Windows, the installer can protect master.key and credentials.p12 with NTFS access control lists (ACLs) tied to a Windows security group. This allows multiple accounts (the service account, the administrator, etc.) to access the credentials without requiring individual per-file ACL entries.

Installer Options

Option Description
Use an existing group Select a local or Active Directory group from the tree. The installer applies ACLs using this group and adds the current user and the service account (NT AUTHORITY\LOCAL SERVICE) as members.
Create a new group Creates a local Windows group with the specified name, adds the current user and service account, and applies ACLs.
Skip No group-based ACL. Credentials are protected by the default NTFS inheritance from the data directory.

ACL Applied

When a group is selected or created, the installer runs:

icacls master.key /inheritance:r
icacls master.key /grant "GroupName:(R)"
icacls master.key /grant "BUILTIN\Administrators:(F)"

This removes inherited permissions, grants read access to the group, and grants full control to local administrators. The same ACL is applied to credentials.p12.

Tip To add or remove accounts after installation, use net localgroup GroupName AccountName /add or /delete. No file ACL changes are needed.
Warning Group creation and ACL modification require Administrator privileges. Run the installer elevated (right-click → "Run as administrator") to use this feature.

Cloud Vault Integration

Instead of storing the master key password on disk, it can be stored in a cloud secret management service. When vault integration is enabled, the master.key file contains a vault URI instead of the actual password. At startup, the server resolves the URI to retrieve the password.

How It Works

Server
starts
Read
master.key
Starts with
vault: ?
YES
Call cloud
provider API
Get password
from vault
NO
Use file content
as password
Unlock
credentials.p12

Figure: Credential resolution flow at server startup. The master.key file is read once. If it contains a vault: URI, the password is fetched from the cloud provider using the VM's managed identity. Otherwise, the file content is used directly as the keystore password.

Supported Providers

Provider URI Format Authentication
Azure Key Vault vault:azure:https://myvault.vault.azure.net/secrets/name Managed identity via Azure IMDS
AWS Secrets Manager vault:aws:us-east-1:secret-name EC2 instance role via IMDSv2 + SigV4
Google Cloud Secret Manager vault:gcp:project-id/secret-name Compute Engine service account via metadata server

Setup

  1. During installation, the installer generates a random master key password and displays it on the Cloud Vault wizard page.
  2. Copy the password and create a secret in your vault provider with this value.
  3. Enter the vault URI in the installer and click Verify to confirm the round-trip.
  4. The installer writes the vault URI into master.key instead of the plain password.
Prerequisite The server must run on a VM with a managed identity (Azure), instance role (AWS), or service account (GCP) that has read access to the secret. No SDKs or additional libraries are required — authentication uses the cloud provider's instance metadata service, which is only accessible from the VM itself.

Manual Configuration

To enable vault integration on an existing installation, replace the contents of conf/master.key with the vault URI:

vault:azure:https://myvault.vault.azure.net/secrets/sss-master-key

The server detects the vault: prefix at startup and resolves the secret automatically.

GCP Version Pinning

For Google Cloud, append a version number to access a specific secret version instead of latest:

vault:gcp:my-project-123/sss-master-key/3