Skip to content

Commit 46def44

Browse files
committed
additional validation and tests for CORS configuration files
1 parent f77e49c commit 46def44

File tree

5 files changed

+102
-0
lines changed

5 files changed

+102
-0
lines changed

lib/cors.js

+12
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ const xml2js = require("xml2js");
55

66
const templateBuilder = require("./xml-template-builder");
77

8+
// https://docs.aws.amazon.com/AmazonS3/latest/dev/cors.html#cors-allowed-methods
9+
const corsAllowedMethods = ["GET", "PUT", "POST", "DELETE", "HEAD"];
10+
811
function createWildcardRegExp(str, flags = "") {
912
const parts = str.split("*");
1013
if (parts.length > 2)
@@ -32,6 +35,15 @@ module.exports = function cors(config) {
3235
);
3336
}
3437

38+
for (const method of rule.AllowedMethod) {
39+
if (!corsAllowedMethods.includes(method)) {
40+
throw new Error(
41+
"Found unsupported HTTP method in CORS config. Unsupported method is " +
42+
method
43+
);
44+
}
45+
}
46+
3547
// Keep track if the rule has the plain wildcard '*' origin since S3 responds with '*'
3648
// instead of echoing back the request origin in this case
3749
rule.hasWildcardOrigin = rule.AllowedOrigin.includes("*");

test/resources/cors_invalid1.xml

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<CORSConfiguration>
2+
<CORSRule>
3+
<!-- Only one wildcard is allowed -->
4+
<AllowedOrigin>https://*.*</AllowedOrigin>
5+
<AllowedMethod>HEAD</AllowedMethod>
6+
<AllowedMethod>GET</AllowedMethod>
7+
<MaxAgeSeconds>3000</MaxAgeSeconds>
8+
<AllowedHeader>*</AllowedHeader>
9+
</CORSRule>
10+
</CORSConfiguration>

test/resources/cors_invalid2.xml

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<CORSConfiguration>
2+
<CORSRule>
3+
<AllowedOrigin>*</AllowedOrigin>
4+
<!-- Method must be one of GET, PUT, POST, DELETE, HEAD -->
5+
<AllowedMethod>*</AllowedMethod>
6+
<MaxAgeSeconds>3000</MaxAgeSeconds>
7+
<AllowedHeader>*</AllowedHeader>
8+
</CORSRule>
9+
</CORSConfiguration>

test/resources/cors_invalid3.xml

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<CORSConfiguration>
2+
<CORSRule>
3+
<!-- At least one AllowedOrigin or AllowedMethod must be specified -->
4+
<MaxAgeSeconds>3000</MaxAgeSeconds>
5+
<AllowedHeader>*</AllowedHeader>
6+
</CORSRule>
7+
</CORSConfiguration>

test/test.js

+64
Original file line numberDiff line numberDiff line change
@@ -1117,6 +1117,70 @@ describe("S3rver CORS Policy Tests", function() {
11171117
}
11181118
});
11191119

1120+
it("should fail to initialize a configuration with multiple wildcard characters", function*() {
1121+
let error;
1122+
try {
1123+
let server;
1124+
yield thunkToPromise(done => {
1125+
server = new S3rver({
1126+
port: 4569,
1127+
hostname: "localhost",
1128+
silent: true,
1129+
cors: fs.readFileSync("./test/resources/cors_invalid1.xml")
1130+
}).run(done);
1131+
});
1132+
yield thunkToPromise(done => server.close(done));
1133+
} catch (err) {
1134+
error = err;
1135+
}
1136+
expect(error).to.exist;
1137+
expect(error.message).to.include(" can not have more than one wildcard.");
1138+
});
1139+
1140+
it("should fail to initialize a configuration with an illegal AllowedMethod", function*() {
1141+
let error;
1142+
try {
1143+
let server;
1144+
yield thunkToPromise(done => {
1145+
server = new S3rver({
1146+
port: 4569,
1147+
hostname: "localhost",
1148+
silent: true,
1149+
cors: fs.readFileSync("./test/resources/cors_invalid2.xml")
1150+
}).run(done);
1151+
});
1152+
yield thunkToPromise(done => server.close(done));
1153+
} catch (err) {
1154+
error = err;
1155+
}
1156+
expect(error).to.exist;
1157+
expect(error.message).to.include(
1158+
"Found unsupported HTTP method in CORS config."
1159+
);
1160+
});
1161+
1162+
it("should fail to initialize a configuration with missing required fields", function*() {
1163+
let error;
1164+
try {
1165+
let server;
1166+
yield thunkToPromise(done => {
1167+
server = new S3rver({
1168+
port: 4569,
1169+
hostname: "localhost",
1170+
silent: true,
1171+
cors: fs.readFileSync("./test/resources/cors_invalid3.xml")
1172+
}).run(done);
1173+
});
1174+
yield thunkToPromise(done => server.close(done));
1175+
} catch (err) {
1176+
error = err;
1177+
}
1178+
expect(error).to.exist;
1179+
expect(error.message).to.include(
1180+
"CORSRule must have at least one AllowedOrigin and AllowedMethod"
1181+
);
1182+
});
1183+
11201184
it("should add the Access-Control-Allow-Origin header for default (wildcard) configurations", function*() {
11211185
const origin = "http://a-test.example.com";
11221186
const params = { Bucket: bucket, Key: "image" };

0 commit comments

Comments
 (0)