Skip to content

Commit 81b41c0

Browse files
author
Will Toozs
committed
fixup: update for content-type checking
1 parent 2a41094 commit 81b41c0

File tree

2 files changed

+975
-340
lines changed

2 files changed

+975
-340
lines changed

lib/api/apiUtils/apiCallers/callPostObject.js

+48-7
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,56 @@ const os = require('os');
99
const MAX_FIELD_SIZE = 20 * 1024; // 20KB
1010
/** @see doc: https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-keys.html */
1111
const MAX_KEY_SIZE = 1024;
12+
const POST_OBJECT_OPTIONAL_FIELDS = [
13+
'acl',
14+
'awsaccesskeyid',
15+
'bucket',
16+
'cache-control',
17+
'content-disposition',
18+
'content-encoding',
19+
'content-type',
20+
'expires',
21+
'policy',
22+
'redirect',
23+
'tagging',
24+
'success_action_redirect',
25+
'success_action_status',
26+
'x-amz-meta-',
27+
'x-amz-storage-class',
28+
'x-amz-security-token',
29+
'x-amz-signgnature',
30+
'x-amz-website-redirect-location',
31+
];
1232

1333
async function authenticateRequest(request, requestContexts, log) {
1434
return new Promise(resolve => {
1535
// TODO RING-45960 remove ignore for POST object here
36+
// if (err) {
37+
// log.trace('authentication error', { error: err });
38+
// return reject(err);
39+
// }
1640
auth.server.doAuth(request, log, (err, userInfo, authorizationResults, streamingV4Params) =>
1741
resolve({ userInfo, authorizationResults, streamingV4Params }), 's3', requestContexts);
1842
});
1943
}
2044

2145
async function parseFormData(request, response, requestContexts, log) {
2246
/* eslint-disable no-param-reassign */
23-
const formDataParser = busboy({ headers: request.headers });
47+
let formDataParser;
48+
if (!request.headers
49+
|| !request.headers['content-type']
50+
|| !request.headers['content-type'].startsWith('multipart/form-data')) {
51+
return Promise.reject(errors.PreconditionFailed
52+
.customizeDescription('Bucket POST must be of the enclosure-type multipart/form-data'));
53+
}
54+
try {
55+
formDataParser = busboy({ headers: request.headers });
56+
} catch (err) {
57+
log.trace('Error creating form data parser', { error: err.toString() });
58+
return Promise.reject(errors.PreconditionFailed);
59+
}
60+
61+
// formDataParser = busboy({ headers: request.headers });
2462
writeContinue(request, response);
2563

2664
return new Promise((resolve, reject) => {
@@ -37,20 +75,28 @@ async function parseFormData(request, response, requestContexts, log) {
3775
const formParserFinishedPromise = new Promise((res) => { formParserFinishedPromiseResolve = res; });
3876

3977
formDataParser.on('field', (fieldname, val) => {
78+
// Check if we have exceeded the max size allowed for all fields
4079
totalFieldSize += Buffer.byteLength(val, 'utf8');
4180
if (totalFieldSize > MAX_FIELD_SIZE) {
4281
return reject(errors.MaxPostPreDataLengthExceeded);
4382
}
83+
84+
// validate the fieldname
4485
const lowerFieldname = fieldname.toLowerCase();
86+
// special handling for key field
4587
if (lowerFieldname === 'key') {
4688
if (val.length > MAX_KEY_SIZE) {
4789
return reject(errors.KeyTooLong);
4890
} else if (val.length === 0) {
4991
return reject(errors.InvalidArgument
5092
.customizeDescription('User key must have a length greater than 0.'));
5193
}
94+
request.formData[lowerFieldname] = val;
95+
}
96+
// add only the recognized fields to the formData object
97+
if (POST_OBJECT_OPTIONAL_FIELDS.some(field => lowerFieldname.startsWith(field))) {
98+
request.formData[lowerFieldname] = val;
5299
}
53-
request.formData[lowerFieldname] = val;
54100
return undefined;
55101
});
56102

@@ -140,11 +186,6 @@ function getFileStat(filePath, log) {
140186
}
141187

142188
async function processPostForm(request, response, requestContexts, log, callback) {
143-
if (!request.headers || !request.headers['content-type'].includes('multipart/form-data')) {
144-
const contentTypeError = errors.PreconditionFailed
145-
.customizeDescription('Bucket POST must be of the enclosure-type multipart/form-data');
146-
return process.nextTick(callback, contentTypeError);
147-
}
148189
try {
149190
const { userInfo, authorizationResults, streamingV4Params } =
150191
await parseFormData(request, response, requestContexts, log);

0 commit comments

Comments
 (0)