From 8be23f7afe3f499400712ebff4da84e142fc00d0 Mon Sep 17 00:00:00 2001 From: shirady <57721533+shirady@users.noreply.github.com> Date: Mon, 24 Nov 2025 16:01:07 +0200 Subject: [PATCH] IAM | Principal in Bucket Policy of the Account Root User When the Requesting Account Is IAM User 1. Add additional check after the check of bucket policy by principal ARN of the user to also check the permission in account level. 2. Fix permission_by_arn call to has_bucket_policy_permission so the last argument will be an object. Signed-off-by: shirady <57721533+shirady@users.noreply.github.com> --- src/endpoint/s3/s3_rest.js | 20 +++++++++++++++++--- src/server/common_services/auth_server.js | 14 +++++++++++++- 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/src/endpoint/s3/s3_rest.js b/src/endpoint/s3/s3_rest.js index 2f3bbda40f..9781bffb9e 100755 --- a/src/endpoint/s3/s3_rest.js +++ b/src/endpoint/s3/s3_rest.js @@ -250,7 +250,7 @@ async function authorize_request_policy(req) { } const account = req.object_sdk.requesting_account; - const is_nc_deployment = req.object_sdk.nsfs_config_root; + const is_nc_deployment = Boolean(req.object_sdk.nsfs_config_root); const account_identifier_name = is_nc_deployment ? account.name.unwrap() : account.email.unwrap(); const account_identifier_id = is_nc_deployment ? account._id : undefined; const account_identifier_arn = s3_bucket_policy_utils.get_bucket_policy_principal_arn(account); @@ -296,6 +296,7 @@ async function authorize_request_policy(req) { let permission_by_id; let permission_by_name; let permission_by_arn; + let permission_by_arn_owner; // In NC, we allow principal to be: // 1. account name (for backwards compatibility) @@ -321,13 +322,26 @@ async function authorize_request_policy(req) { // Policy permission is validated by account arn if (!account_identifier_id) { permission_by_arn = await s3_bucket_policy_utils.has_bucket_policy_permission( - s3_policy, account_identifier_arn, method, arn_path, req, public_access_block?.restrict_public_buckets + s3_policy, account_identifier_arn, method, arn_path, req, + { disallow_public_access: public_access_block?.restrict_public_buckets } ); dbg.log3('authorize_request_policy: permission_by_arn', permission_by_arn); } if (permission_by_arn === "DENY") throw new S3Error(S3Error.AccessDenied); - if ((permission_by_id === "ALLOW" || permission_by_name === "ALLOW" || permission_by_arn === "ALLOW") || is_owner) return; + // ARN check for users under the account + // ARN check is not implemented in NC yet + if (!is_nc_deployment && account.owner !== undefined) { + const owner_account_identifier_arn = s3_bucket_policy_utils.create_arn_for_root(account.owner); + permission_by_arn_owner = await s3_bucket_policy_utils.has_bucket_policy_permission( + s3_policy, owner_account_identifier_arn, method, arn_path, req, + { disallow_public_access: public_access_block?.restrict_public_buckets } + ); + dbg.log3('authorize_request_policy permission_by_arn_owner', permission_by_arn_owner); + if (permission_by_arn_owner === "DENY") throw new S3Error(S3Error.AccessDenied); + } + if ((permission_by_id === "ALLOW" || permission_by_name === "ALLOW" || + permission_by_arn === "ALLOW" || permission_by_arn_owner === "ALLOW") || is_owner) return; throw new S3Error(S3Error.AccessDenied); } diff --git a/src/server/common_services/auth_server.js b/src/server/common_services/auth_server.js index c672a80ad1..ca2bc1480c 100644 --- a/src/server/common_services/auth_server.js +++ b/src/server/common_services/auth_server.js @@ -640,7 +640,19 @@ async function has_bucket_action_permission(bucket, account, action, req_query, if (result === 'DENY') return false; - return has_owner_access || result === 'ALLOW'; + let permission_by_arn_owner; + if (account.owner) { + const owner_account_identifier_arn = s3_bucket_policy_utils.create_arn_for_root(account.owner._id.toString()); + permission_by_arn_owner = await s3_bucket_policy_utils.has_bucket_policy_permission( + bucket_policy, + owner_account_identifier_arn, + action, + `arn:aws:s3:::${bucket.name.unwrap()}${bucket_path}`, + req_query, + ); + if (permission_by_arn_owner === 'DENY') return false; + } + return has_owner_access || result === 'ALLOW' || permission_by_arn_owner === 'ALLOW'; } /**