Skip to content

Commit 969e8f9

Browse files
Use deny policies rather than conditions to reject insecure access (#21)
* Remove policy around TLS version S3 already only accepts TLS 1.2+
1 parent 5c5ac6b commit 969e8f9

File tree

1 file changed

+18
-22
lines changed

1 file changed

+18
-22
lines changed

buckup/bucket_creator.py

Lines changed: 18 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,6 @@
1616

1717
POLICY_NAME_FORMAT = "{bucket_name}-owner-policy"
1818

19-
REQUIRE_HTTPS_CONDITION = {
20-
"Bool": {
21-
# Require HTTPS
22-
"aws:SecureTransport": "true"
23-
},
24-
"NumericGreaterThanEquals": {
25-
# Require TLS >= 1.2
26-
"s3:TlsVersion": ["1.2"]
27-
},
28-
}
29-
3019

3120
class BucketCreator:
3221
def __init__(self, profile_name=None, region_name=None):
@@ -77,11 +66,22 @@ def format_path(path):
7766
"Principal": "*",
7867
"Action": ["s3:GetObject"],
7968
"Resource": paths_resources,
80-
# Require HTTPS for public requests
81-
"Condition": REQUIRE_HTTPS_CONDITION,
8269
}
8370

8471
def get_bucket_policy_statements_for_user_access(self, bucket, user):
72+
# Deny access which isn't over HTTPS
73+
yield {
74+
"Sid": "DenyInsecureTransport",
75+
"Effect": "Deny",
76+
"Principal": "*",
77+
"Action": "s3:*",
78+
"Resource": [
79+
f"arn:aws:s3:::{bucket.name}",
80+
f"arn:aws:s3:::{bucket.name}/*",
81+
],
82+
"Condition": {"Bool": {"aws:SecureTransport": "false"}},
83+
}
84+
8585
# Create policy statement giving the created user access to
8686
# non-destructive actions on the bucket.
8787
yield {
@@ -95,8 +95,6 @@ def get_bucket_policy_statements_for_user_access(self, bucket, user):
9595
"s3:ListBucketVersions",
9696
],
9797
"Resource": "arn:aws:s3:::{bucket_name}".format(bucket_name=bucket.name),
98-
# Require HTTPS for API
99-
"Condition": REQUIRE_HTTPS_CONDITION,
10098
}
10199
# Create policy statement giving the created user full access over the
102100
# objects.
@@ -106,14 +104,11 @@ def get_bucket_policy_statements_for_user_access(self, bucket, user):
106104
"Principal": {"AWS": user.arn},
107105
"Action": "s3:*",
108106
"Resource": "arn:aws:s3:::{bucket_name}/*".format(bucket_name=bucket.name),
109-
# Require HTTPS for API
110-
"Condition": REQUIRE_HTTPS_CONDITION,
111107
}
112108

113109
def set_bucket_policy(
114110
self, bucket, user, allow_public_acls, public_get_object_paths=None
115111
):
116-
policy_statement = []
117112
public_access = bool(public_get_object_paths)
118113

119114
# NB: This API doesn't exist on a `Bucket`
@@ -129,15 +124,16 @@ def set_bucket_policy(
129124
if public_access or allow_public_acls:
130125
print("Configured public access to bucket.")
131126

127+
policy_statement = list(
128+
self.get_bucket_policy_statements_for_user_access(bucket, user)
129+
)
130+
132131
if public_access:
133132
policy_statement.append(
134133
self.get_bucket_policy_statement_for_get_object(
135134
bucket, public_get_object_paths
136135
)
137136
)
138-
policy_statement.extend(
139-
list(self.get_bucket_policy_statements_for_user_access(bucket, user))
140-
)
141137
policy = json.dumps(
142138
{
143139
"Version": "2012-10-17",
@@ -148,7 +144,7 @@ def set_bucket_policy(
148144
try:
149145
bucket.Policy().put(Policy=policy)
150146
except ClientError as e:
151-
if e.response["Error"]["Code"] == "MalformedPolicy":
147+
if e.response["Error"]["Message"] == "Invalid principal in policy":
152148
print(
153149
"Waiting for the user to be available to be "
154150
"attached to the policy (wait 5s)."

0 commit comments

Comments
 (0)