From faca32f854b525071ea9b615f22e751bb4e328a3 Mon Sep 17 00:00:00 2001 From: Will Toozs Date: Fri, 25 Aug 2023 15:23:37 +0200 Subject: [PATCH] CLDSRV-426: update ACL permission checks for implicitDeny logic --- .../authorization/permissionChecks.js | 49 ++++++++++++++----- 1 file changed, 37 insertions(+), 12 deletions(-) diff --git a/lib/api/apiUtils/authorization/permissionChecks.js b/lib/api/apiUtils/authorization/permissionChecks.js index 13cefee9f3..2fb83e0aa8 100644 --- a/lib/api/apiUtils/authorization/permissionChecks.js +++ b/lib/api/apiUtils/authorization/permissionChecks.js @@ -8,13 +8,32 @@ const { allAuthedUsersId, bucketOwnerActions, logId, publicId, const publicReadBuckets = process.env.ALLOW_PUBLIC_READ_BUCKETS ? process.env.ALLOW_PUBLIC_READ_BUCKETS.split(',') : []; -function checkBucketAcls(bucket, requestType, canonicalID) { +function checkBucketAcls(bucket, requestType, canonicalID, mainApiCall) { + // Same logic applies on the Versioned APIs, so let's simplify it. + const requestTypeParsed = requestType.endsWith('Version') ? + requestType.slice(0, -7) : requestType; if (bucket.getOwner() === canonicalID) { return true; } + // Backward compatibility + const arrayOfAllowed = [ + 'objectPutTagging', + 'objectPutLegalHold', + 'objectPutRetention', + ]; + if (mainApiCall === 'objectGet') { + if (requestTypeParsed === 'objectGetTagging') { + return true; + } + } + if (mainApiCall === 'objectPut') { + if (arrayOfAllowed.includes(requestTypeParsed)) { + return true; + } + } const bucketAcl = bucket.getAcl(); - if (requestType === 'bucketGet' || requestType === 'bucketHead') { + if (requestTypeParsed === 'bucketGet' || requestTypeParsed === 'bucketHead') { if (bucketAcl.Canned === 'public-read' || bucketAcl.Canned === 'public-read-write' || (bucketAcl.Canned === 'authenticated-read' @@ -32,7 +51,7 @@ function checkBucketAcls(bucket, requestType, canonicalID) { return true; } } - if (requestType === 'bucketGetACL') { + if (requestTypeParsed === 'bucketGetACL') { if ((bucketAcl.Canned === 'log-delivery-write' && canonicalID === logId) || bucketAcl.FULL_CONTROL.indexOf(canonicalID) > -1 @@ -48,7 +67,7 @@ function checkBucketAcls(bucket, requestType, canonicalID) { } } - if (requestType === 'bucketPutACL') { + if (requestTypeParsed === 'bucketPutACL') { if (bucketAcl.FULL_CONTROL.indexOf(canonicalID) > -1 || bucketAcl.WRITE_ACP.indexOf(canonicalID) > -1) { return true; @@ -62,11 +81,7 @@ function checkBucketAcls(bucket, requestType, canonicalID) { } } - if (requestType === 'bucketDelete' && bucket.getOwner() === canonicalID) { - return true; - } - - if (requestType === 'objectDelete' || requestType === 'objectPut') { + if (requestTypeParsed === 'objectDelete' || requestTypeParsed === 'objectPut') { if (bucketAcl.Canned === 'public-read-write' || bucketAcl.FULL_CONTROL.indexOf(canonicalID) > -1 || bucketAcl.WRITE.indexOf(canonicalID) > -1) { @@ -86,11 +101,12 @@ function checkBucketAcls(bucket, requestType, canonicalID) { // objectPutACL, objectGetACL, objectHead or objectGet, the bucket // authorization check should just return true so can move on to check // rights at the object level. - return (requestType === 'objectPutACL' || requestType === 'objectGetACL' || - requestType === 'objectGet' || requestType === 'objectHead'); + return (requestTypeParsed === 'objectPutACL' || requestTypeParsed === 'objectGetACL' || + requestTypeParsed === 'objectGet' || requestTypeParsed === 'objectHead'); } -function checkObjectAcls(bucket, objectMD, requestType, canonicalID) { +function checkObjectAcls(bucket, objectMD, requestType, canonicalID, requesterIsNotUser, + isUserUnauthenticated, mainApiCall) { const bucketOwner = bucket.getOwner(); // acls don't distinguish between users and accounts, so both should be allowed if (bucketOwnerActions.includes(requestType) @@ -100,6 +116,15 @@ function checkObjectAcls(bucket, objectMD, requestType, canonicalID) { if (objectMD['owner-id'] === canonicalID) { return true; } + + // Backward compatibility + if (mainApiCall === 'objectGet') { + if ((isUserUnauthenticated || (requesterIsNotUser && bucketOwner === objectMD['owner-id'])) + && requestType === 'objectGetTagging') { + return true; + } + } + if (!objectMD.acl) { return false; }