Skip to content

Commit 2f8a64c

Browse files
committed
Account with NotPrincipal should explicitly provide permission
The is the bucket policy with below combination Effect : DENY, Action: $OPERATION, NotPrincipal: $ACCOUNT The permission on the "Action" for the $ACCOUNT mentioned in the "NotPrincipal" should be explicitly given. Example: For "Action: get_object", if we want to DENY permission for * (all accounts) and we want to give explicit permission to any one or few accounts, then we can include that account as part of part of "NotPrincipal" Check DFBUGS-1519 for steps to reproduce the issue Fixes: https://issues.redhat.com/browse/DFBUGS-1519 Signed-off-by: Vinayakswami Hariharmath <[email protected]>
1 parent b487b1a commit 2f8a64c

File tree

2 files changed

+60
-6
lines changed

2 files changed

+60
-6
lines changed

src/endpoint/s3/s3_rest.js

+14-6
Original file line numberDiff line numberDiff line change
@@ -293,16 +293,24 @@ async function authorize_request_policy(req) {
293293
s3_policy, account_identifier_id, method, arn_path, req, public_access_block_cfg?.public_access_block?.restrict_public_buckets);
294294
dbg.log3('authorize_request_policy: permission_by_id', permission_by_id);
295295
}
296-
if (permission_by_id === "DENY") throw new S3Error(S3Error.AccessDenied);
297296

298-
if ((!account_identifier_id || permission_by_id !== "DENY") && account.owner === undefined) {
297+
if (account_identifier_name && permission_by_id !== "ALLOW") {
298+
// we check the name only if the id check is not ALLOW
299+
// this is to avoid double checking the same permission
300+
// and to make sure we are not checking the same permission twice
301+
// in case of NC account (which is not unique)
299302
permission_by_name = await s3_bucket_policy_utils.has_bucket_policy_permission(
300-
s3_policy, account_identifier_name, method, arn_path, req, public_access_block_cfg?.public_access_block?.restrict_public_buckets
301-
);
303+
s3_policy,
304+
account_identifier_name,
305+
method,
306+
arn_path,
307+
req,
308+
public_access_block_cfg?.public_access_block?.restrict_public_buckets);
302309
dbg.log3('authorize_request_policy: permission_by_name', permission_by_name);
303310
}
304-
if (permission_by_name === "DENY") throw new S3Error(S3Error.AccessDenied);
305-
if ((permission_by_id === "ALLOW" || permission_by_name === "ALLOW") || is_owner) return;
311+
312+
if (permission_by_id === "DENY" && permission_by_name === "DENY") throw new S3Error(S3Error.AccessDenied);
313+
if (permission_by_id === "ALLOW" || permission_by_name === "ALLOW" || is_owner) return;
306314

307315
throw new S3Error(S3Error.AccessDenied);
308316
}

src/test/unit_tests/test_s3_bucket_policy.js

+46
Original file line numberDiff line numberDiff line change
@@ -1645,6 +1645,52 @@ mocha.describe('s3_bucket_policy', function() {
16451645
Bucket: BKT,
16461646
Key: KEY,
16471647
}));
1648+
1649+
});
1650+
1651+
mocha.it('should be able to use notPrincipal with Effect Deny', async function() {
1652+
const self = this; // eslint-disable-line no-invalid-this
1653+
self.timeout(15000);
1654+
const auth_put_policy = {
1655+
Version: '2012-10-17',
1656+
Statement: [
1657+
{
1658+
Effect: 'Allow',
1659+
Principal: { AWS: [user_a, user_b] },
1660+
Action: ['s3:*'],
1661+
Resource: [`arn:aws:s3:::${BKT}/*`]
1662+
},
1663+
{
1664+
Effect: 'Deny',
1665+
NotPrincipal: { AWS: user_a },
1666+
Action: ['s3:GetObject'],
1667+
Resource: [`arn:aws:s3:::${BKT}/*`]
1668+
}
1669+
]};
1670+
let res = await s3_owner.putBucketPolicy({
1671+
Bucket: BKT,
1672+
Policy: JSON.stringify(auth_put_policy)
1673+
});
1674+
assert.equal(res.$metadata.httpStatusCode, 200);
1675+
1676+
res = await s3_a.putObject({
1677+
Body: BODY,
1678+
Bucket: BKT,
1679+
Key: KEY,
1680+
});
1681+
assert.equal(res.$metadata.httpStatusCode, 200);
1682+
1683+
res = await s3_a.getObject({
1684+
Bucket: BKT,
1685+
Key: KEY,
1686+
});
1687+
assert.equal(res.$metadata.httpStatusCode, 200);
1688+
assert.equal(res.Body.toString(), BODY);
1689+
1690+
await assert_throws_async(s3_b.getObject({
1691+
Bucket: BKT,
1692+
Key: KEY,
1693+
}));
16481694
});
16491695

16501696
mocha.it('should be able to use notResource', async function() {

0 commit comments

Comments
 (0)