This issue has been assessed as high severity. Review affected configurations immediately.
AWS Transfer Family is a managed SFTP, FTPS, and FTP service that lets organisations expose a file-transfer endpoint without running their own server. The backend is typically Amazon S3. That combination — internet-facing file transfer with cloud storage backend — creates a specific set of misconfiguration patterns that security teams frequently miss, primarily because the Trust Family console makes the initial setup easy enough that the IAM implications receive little scrutiny.
This article covers the three most common misconfiguration paths in Transfer Family SFTP deployments and the hardening steps that address each.
How Transfer Family SFTP Permissions Work
Every Transfer Family user is associated with an IAM role. When the user authenticates and executes a file operation — upload, download, directory listing — Transfer Family calls the S3 API using that IAM role’s credentials. The role determines what the user can actually do in S3.
Users can also have a scope-down policy: an inline policy applied at authentication time that restricts the role’s permissions further for that specific session. The role establishes the ceiling of what is possible; the scope-down policy can only reduce it.
The misconfiguration patterns cluster around two areas: roles that grant more than the user needs, and scope-down policies that are missing or incorrectly constructed.
Misconfiguration 1: Roles That Grant Access to the Entire Bucket
The AWS documentation example for a Transfer Family IAM role grants s3:GetObject, s3:PutObject, s3:DeleteObject, and s3:ListBucket on arn:aws:s3:::my-bucket and arn:aws:s3:::my-bucket/*. That policy grants the authenticated user access to every object in the bucket — including prefixes intended for other users or other systems.
In a multi-tenant SFTP deployment — where multiple external partners or users share the same Transfer Family server — this is a significant oversharing risk. A user who authenticates as partner-a can enumerate and download files uploaded by partner-b if both use the same role and bucket without path restrictions.
How it manifests in practice: Transfer Family creates a logical home directory for each user, typically /bucket-name/username/. If the IAM role grants access to the full bucket, the home directory restriction is only enforced by the server’s path presentation — not by S3 access controls. A user who issues SFTP commands like cd / or attempts path traversal can potentially access paths outside their home directory.
Fix: Restrict IAM role resource blocks to the user-specific prefix:
{
"Effect": "Allow",
"Action": ["s3:GetObject", "s3:PutObject", "s3:DeleteObject"],
"Resource": "arn:aws:s3:::my-bucket/home/${transfer:UserName}/*"
},
{
"Effect": "Allow",
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::my-bucket",
"Condition": {
"StringLike": {
"s3:prefix": ["home/${transfer:UserName}/*", "home/${transfer:UserName}"]
}
}
}
The ${transfer:UserName} variable is substituted at evaluation time with the authenticated username. This is the correct pattern for multi-user deployments. The ListBucket condition is equally important: without it, users can enumerate bucket contents outside their prefix using the SFTP ls command.
Misconfiguration 2: Scope-Down Policy Omission
Scope-down policies are optional in Transfer Family. Many deployments do not use them. The problem is that once a Transfer Family IAM role grants access, any user mapped to that role inherits the full permissions — regardless of whether their intended access is narrower.
Scope-down policies are attached per-user and evaluated at session time. They can restrict operations to specific prefixes, deny deletions while allowing uploads, or enforce IP-based conditions. Without them, the role’s permissions are the effective permissions.
Attack path: In a deployment where a read-only partner is mapped to a shared IAM role that includes write access, that partner can upload or modify files in any path the role allows. If the role grants s3:DeleteObject for operational reasons, the read-only partner can delete files.
Fix: Apply scope-down policies for every user whose intended access differs from the full role. For a read-only user:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["s3:GetObject", "s3:ListBucket"],
"Resource": [
"arn:aws:s3:::my-bucket",
"arn:aws:s3:::my-bucket/home/${transfer:UserName}/*"
]
}
]
}
Note that scope-down policies cannot grant permissions the role does not already have — they can only restrict. If a role lacks s3:PutObject, a scope-down policy cannot add it.
Misconfiguration 3: S3 Bucket Policies That Undo IAM Restrictions
IAM role policies are one layer; S3 bucket policies are another. When both are present, S3 evaluates both and applies the intersection of allow statements — unless an explicit deny is present.
The complication in Transfer Family deployments is bucket policies inherited from other use cases. A bucket originally used for application logs may have a bucket policy with a broad allow for a service account or a legacy IAM user. When Transfer Family is pointed at the same bucket, the SFTP users operate within that context. If the bucket policy includes an Effect: Allow for s3:* on arn:aws:s3:::my-bucket/*, the bucket policy is not restricting anything — the IAM role policy becomes the sole constraint.
More dangerous: a bucket policy with a resource-wide deny can block legitimate Transfer Family operations entirely, sending teams scrambling to diagnose connection failures without realising the deny is coming from the bucket policy rather than the Transfer Family configuration.
What to check:
aws s3api get-bucket-policy --bucket my-bucket --query Policy --output text | python3 -m json.tool
Review the bucket policy for:
- Broad
Allowstatements that override intended role restrictions - Principal wildcards (
"Principal": "*") with no condition block - Legacy IAM user ARNs that should no longer have direct S3 access
- Missing explicit denies for sensitive operations like
s3:DeleteBucketors3:PutBucketPolicy
Additional Hardening: Logging and Server Configuration
Enable CloudTrail data events for the S3 bucket. Transfer Family operations appear in CloudTrail as S3 API calls made by the IAM role. Without data event logging, there is no audit trail of which files were accessed or modified. Data events are not enabled by default.
aws cloudtrail put-event-selectors \
--trail-name my-trail \
--event-selectors '[{
"ReadWriteType": "All",
"IncludeManagementEvents": true,
"DataResources": [{
"Type": "AWS::S3::Object",
"Values": ["arn:aws:s3:::my-bucket/"]
}]
}]'
Enable Transfer Family structured logging. The Transfer Family server can log to CloudWatch Logs with structured JSON output, including session identifiers, source IP addresses, authentication method, and file operation details. This is separate from CloudTrail and provides the SFTP-level view of activity.
Restrict server endpoint access. If the SFTP server is used by a known set of partner IP ranges, apply IP allow-listing at the endpoint configuration level. Transfer Family VPC endpoints allow security group rules to restrict inbound connections without exposing the server to the public internet.
Disable unused protocols. Transfer Family supports SFTP, FTPS, and FTP on the same server endpoint. If only SFTP is required, disable FTPS and FTP at the server configuration level — FTP in particular transmits credentials in plaintext and should never be enabled unless there is a specific compatibility requirement.
Detecting Misconfiguration with CloudTrail Insights
For production environments, the following patterns in CloudTrail data events warrant investigation:
- An SFTP user making
ListObjectsV2calls with a prefix outside their home directory — indicates path traversal or over-broad ListBucket access - A Transfer Family IAM role making API calls at unusual hours or from unexpected source IPs — credentials used outside normal file transfer sessions
DeleteObjectcalls from a role or user that should be read-only — indicates missing scope-down policy enforcementPutObjectcalls to prefixes outside the user’s designated home directory — indicates over-broad PutObject permissions
The simplest policy improvement for most Transfer Family deployments is adding the ${transfer:UserName} path variable to both IAM role resource blocks and scope-down policies. It is a five-minute change that closes the cross-user access path in multi-tenant deployments and is the most common misconfiguration seen in Transfer Family security reviews.