Skip to content

Commit f97e991

Browse files
committed
CLDSRV-674: check x-amz-tagging-count permissions in bucket policies
1 parent 268b2c8 commit f97e991

File tree

3 files changed

+24
-5
lines changed

3 files changed

+24
-5
lines changed

lib/api/api.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -152,8 +152,6 @@ const api = {
152152
log.trace('get object authorization denial from Vault');
153153
return errors.AccessDenied;
154154
}
155-
// TODO add support for returnTagCount in the bucket policy
156-
// checks
157155
isImplicitDeny[authResults[0].action] = authResults[0].isImplicit;
158156
// second item checks s3:GetObject(Version)Tagging action
159157
if (!authResults[1].isAllowed) {
@@ -281,6 +279,9 @@ const api = {
281279
sourceObject, sourceVersionId, log, callback);
282280
}
283281
if (apiMethod === 'objectGet') {
282+
// remove objectGetTagging/objectGetTaggingVersion from apiMethods, these where added by
283+
// prepareRequestContexts to determine the value of returnTagCount.
284+
request.apiMethods = request.apiMethods.filter(methodName => !methodName.includes('Tagging'));
284285
return this[apiMethod](userInfo, request, returnTagCount, log, callback);
285286
}
286287
return this[apiMethod](userInfo, request, log, callback);

lib/api/objectGet.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ function objectGet(authInfo, request, returnTagCount, log, callback) {
5151
getDeleteMarker: true,
5252
requestType: request.apiMethods || 'objectGet',
5353
request,
54+
returnTagCount,
5455
};
5556

5657
return standardMetadataValidateBucketAndObj(mdValParams, request.actionImplicitDenies, log,
@@ -97,7 +98,8 @@ function objectGet(authInfo, request, returnTagCount, log, callback) {
9798
return callback(headerValResult.error, null, corsHeaders);
9899
}
99100
const responseMetaHeaders = collectResponseHeaders(objMD,
100-
corsHeaders, verCfg, returnTagCount);
101+
corsHeaders, verCfg,
102+
returnTagCount && objMD.returnTagCount); // IAM and Bucket policy should both authorize tagging.
101103

102104
setExpirationHeaders(responseMetaHeaders, {
103105
lifecycleConfig: bucket.getLifecycleConfiguration(),

lib/metadata/metadataUtils.js

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -230,13 +230,29 @@ function standardMetadataValidateBucketAndObj(params, actionImplicitDenies, log,
230230
return next(null, bucket, objMD);
231231
},
232232
(bucket, objMD, next) => {
233+
const objMetadata = objMD;
233234
const canonicalID = authInfo.getCanonicalID();
234-
if (!isObjAuthorized(bucket, objMD, requestType, canonicalID, authInfo, log, request,
235+
if (!isObjAuthorized(bucket, objMetadata, requestType, canonicalID, authInfo, log, request,
235236
actionImplicitDenies)) {
236237
log.debug('access denied for user on object', { requestType });
237238
return next(errors.AccessDenied, bucket);
238239
}
239-
return next(null, bucket, objMD);
240+
241+
let returnTagCount = false;
242+
if (params.returnTagCount) {
243+
// If returnTagCount is true we know that Vault athorized the request so it is not an implicitDeny.
244+
const implicitDeny = false;
245+
if (requestType.some(r => r === 'objectGet')) {
246+
returnTagCount = isObjAuthorized(bucket, objMetadata, ['objectGetTagging'], canonicalID, authInfo,
247+
log, request, implicitDeny);
248+
} else if (requestType.some(r => r === 'objectGetVersion')) {
249+
returnTagCount = returnTagCount && isObjAuthorized(bucket, objMetadata, ['objectGetTaggingVersion'],
250+
canonicalID, authInfo, log, request, implicitDeny);
251+
}
252+
253+
objMetadata.returnTagCount = returnTagCount;
254+
}
255+
return next(null, bucket, objMetadata);
240256
},
241257
], (err, bucket, objMD) => {
242258
if (err) {

0 commit comments

Comments
 (0)