Back to Checks
aws

AWS Transfer Family server uses a post-quantum hybrid SSH key exchange security policy

transfer_server_pqc_ssh_kex_enabled
Service: transferSeverity: low
OfficialBuilt-inVerified
Categories:encryption
Resource Type:AwsTransferServer

AWS Transfer Family servers (SFTP, FTPS, AS2) are assessed for use of an approved post-quantum (PQ) hybrid SSH key exchange security policy. Servers whose SecurityPolicyName is not in the configured allowlist of PQ-ready Transfer Family security policies leave file-transfer sessions exposed to harvest-now, decrypt-later attacks.

Risk

Without a PQ-ready security policy, SSH/SFTP traffic captured today can be stored and decrypted in the future once a cryptographically relevant quantum computer is available. This threatens long-term confidentiality of transferred files, credentials, and metadata.

Run this check with Prowler

Run in Prowler Cloud
Run
prowler aws --checks transfer_server_pqc_ssh_kex_enabled

Recommendation

Migrate AWS Transfer Family servers to a post-quantum security policy (e.g., TransferSecurityPolicy-2025-03, TransferSecurityPolicy-FIPS-2025-03, TransferSecurityPolicy-AS2Restricted-2025-07) that adds ML-KEM hybrid SSH key exchange. Avoid deprecated *-PQ-SSH-Experimental-2023-04 policies. Review allowed policies regularly as AWS publishes new PQ-ready options.

Remediation

CLI

aws transfer update-server --server-id <server_id> --security-policy-name TransferSecurityPolicy-2025-03

Terraform

resource "aws_transfer_server" "<example_resource_name>" {
  protocols              = ["SFTP"]
  security_policy_name   = "TransferSecurityPolicy-2025-03" # FIX: post-quantum hybrid SSH KEX policy
  endpoint_type          = "PUBLIC"
}

NativeIaC

Resources:
  <example_resource_name>:
    Type: AWS::Transfer::Server
    Properties:
      Protocols:
        - SFTP
      SecurityPolicyName: TransferSecurityPolicy-2025-03  # FIX: post-quantum hybrid SSH KEX policy

Other

1In the AWS Console, go to AWS Transfer Family > Servers
2Select the server and choose Edit on the Additional details panel
3Set Cryptographic algorithm options (Security policy) to TransferSecurityPolicy-2025-03 (or another approved PQ policy)
4Save the changes

Check Code

from prowler.lib.check.models import Check, Check_Report_AWS
from prowler.providers.aws.services.transfer.transfer_client import transfer_client

PQC_TRANSFER_POLICIES_DEFAULT = [
    "TransferSecurityPolicy-2025-03",
    "TransferSecurityPolicy-FIPS-2025-03",
    "TransferSecurityPolicy-AS2Restricted-2025-07",
]


class transfer_server_pqc_ssh_kex_enabled(Check):
    """Verify that every AWS Transfer Family server uses a post-quantum security policy.

    A Transfer Family server PASSES when its ``SecurityPolicyName`` is in the
    configured allowlist of policies that enable hybrid ML-KEM SSH key exchange.
    """

    def execute(self) -> list[Check_Report_AWS]:
        """Check whether Transfer Family servers use approved PQ SSH KEX policies.

        Iterates through discovered AWS Transfer Family servers and compares each
        server's ``SecurityPolicyName`` with the configured allowlist of
        post-quantum hybrid SSH key exchange security policies.

        Returns:
            list[Check_Report_AWS]: A list of reports for each Transfer Family
            server, including the evaluated security policy context.
        """
        findings = []
        pqc_policies = transfer_client.audit_config.get(
            "transfer_pqc_ssh_allowed_policies", PQC_TRANSFER_POLICIES_DEFAULT
        )
        for server in transfer_client.servers.values():
            report = Check_Report_AWS(metadata=self.metadata(), resource=server)
            policy = server.security_policy_name or "<none>"
            if server.security_policy_name in pqc_policies:
                report.status = "PASS"
                report.status_extended = (
                    f"Transfer Server {server.id} uses post-quantum security policy "
                    f"{policy}."
                )
            else:
                report.status = "FAIL"
                report.status_extended = (
                    f"Transfer Server {server.id} uses security policy {policy}, "
                    "which does not enable post-quantum hybrid SSH key exchange."
                )
            findings.append(report)

        return findings