mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-10-29 16:30:44 +01:00
fix(s3api): evaluate aws:SourceIp from the direct TCP peer, not forwarded headers (#11231)
* fix(s3api): use direct peer IP for aws:SourceIp in bucket policy engine extractSourceIP in the bucket-policy engine trusted X-Forwarded-For and X-Real-Ip whenever the TCP peer looked private (loopback/RFC1918/link-local), with no configurable trusted-proxy allowlist. In containerized deployments the gateway peer is almost always private, so any caller reaching it directly or from a co-located workload could spoof aws:SourceIp and bypass IpAddress/NotIpAddress bucket-policy restrictions. Always return the direct peer address (r.RemoteAddr), matching AWS S3 semantics. Remove the now-unused isPrivateIP helper and header-trust branch. Update TestExtractConditionValuesFromRequestSourceIPPrecedence to assert the peer IP is used regardless of forwarding headers, and add regression tests TestExtractSourceIP_IgnoresForwardedHeaders and TestExtractSourceIP_EnforcesIPRestrictionPolicy. * fix(s3api): use direct peer IP for aws:SourceIp in IAM role/session policies The IAM middleware's extractSourceIP trusted X-Forwarded-For and X-Real-IP whenever the TCP peer looked private (loopback/RFC1918/link-local), with no configurable trusted-proxy allowlist. In containerized deployments the gateway peer is almost always private, so any caller reaching it directly or from a co-located workload could spoof aws:SourceIp and bypass IpAddress/NotIpAddress conditions on role and session policies (IsPrincipalActionExplicitlyDenied). Always return the direct peer address (r.RemoteAddr), matching AWS S3 semantics. Remove the now-unused isPrivateIP helper, privateNetworks table, and its init(). Update TestRequestContextExtraction and TestIPBasedPolicyEnforcement to assert the peer IP is enforced regardless of forwarding headers, and add regression test TestUserInlinePolicySourceIpCondition_IgnoresForwardedHeaders.
This commit is contained in:
1 parent
557fffa350
commit
b88156fe6b
5 files changed
+99
-153
No files matched your search
@@ -123,6 +123,35 @@ func TestUserInlinePolicySourceIpCondition_Allows(t *testing.T) {
|
||||
"PutObject from 127.0.0.1 must be allowed: the user inline policy's aws:SourceIp condition (127.0.0.0/8) matches")
|
||||
}
|
||||
|
||||
// TestUserInlinePolicySourceIpCondition_IgnoresForwardedHeaders proves that a
|
||||
// spoofed X-Forwarded-For cannot satisfy an aws:SourceIp condition: the policy
|
||||
// requires 198.51.100.0/24, the peer is 127.0.0.1, and the header claims
|
||||
// 198.51.100.5. The condition must be evaluated against the peer, not the
|
||||
// header, so the request is denied.
|
||||
func TestUserInlinePolicySourceIpCondition_IgnoresForwardedHeaders(t *testing.T) {
|
||||
api := NewEmbeddedIamApiForTest()
|
||||
api.mockConfig = &iam_pb.S3ApiConfiguration{}
|
||||
seedInlineCondUser(t, api)
|
||||
|
||||
_, iamErr := api.PutUserPolicy(api.mockConfig, url.Values{
|
||||
"UserName": {"alice"},
|
||||
"PolicyName": {"OnlyFromTestNet"},
|
||||
"PolicyDocument": {inlineCondPolicyDoc("198.51.100.0/24")},
|
||||
})
|
||||
require.Nil(t, iamErr, "PutUserPolicy must succeed")
|
||||
require.NoError(t, api.PutS3ApiConfiguration(api.mockConfig))
|
||||
require.NoError(t, api.iam.LoadS3ApiConfigurationFromCredentialManager())
|
||||
|
||||
ident := api.iam.lookupByIdentityName("alice")
|
||||
require.NotNil(t, ident)
|
||||
|
||||
req := inlineCondRequest(t, http.MethodPut)
|
||||
req.Header.Set("X-Forwarded-For", "198.51.100.5")
|
||||
got := api.iam.VerifyActionPermission(req, ident, s3_constants.ACTION_WRITE, inlineCondTestBucket, "obj")
|
||||
assert.Equal(t, s3err.ErrAccessDenied, got,
|
||||
"PutObject from 127.0.0.1 must be denied despite X-Forwarded-For claiming 198.51.100.5: aws:SourceIp is the peer, not the header")
|
||||
}
|
||||
|
||||
// TestGroupInlinePolicy_PutAndEnforce verifies that PutGroupPolicy is supported
|
||||
// (no longer returns NotImplemented) and that an aws:SourceIp condition on the
|
||||
// resulting inline policy is honored for group members.
|
||||
|
||||
Reference in new issue
Block a user