1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
| "use strict";
|
| const MIMEType = require("whatwg-mimetype");
|
| const PRIVILEGED_NO_CORS_REQUEST = new Set(["range"]);
| function isPrivilegedNoCORSRequest(name) {
| return PRIVILEGED_NO_CORS_REQUEST.has(name.toLowerCase());
| }
|
| const NO_CORS_SAFELISTED_REQUEST = new Set([
| `accept`,
| `accept-language`,
| `content-language`,
| `content-type`
| ]);
| function isNoCORSSafelistedRequest(name) {
| return NO_CORS_SAFELISTED_REQUEST.has(name.toLowerCase());
| }
|
| const FORBIDDEN = new Set([
| `accept-charset`,
| `accept-encoding`,
| `access-control-request-headers`,
| `access-control-request-method`,
| `connection`,
| `content-length`,
| `cookie`,
| `cookie2`,
| `date`,
| `dnt`,
| `expect`,
| `host`,
| `keep-alive`,
| `origin`,
| `referer`,
| `te`,
| `trailer`,
| `transfer-encoding`,
| `upgrade`,
| `via`
| ]);
| function isForbidden(name) {
| name = name.toLowerCase();
| return (
| FORBIDDEN.has(name) || name.startsWith("proxy-") || name.startsWith("sec-")
| );
| }
|
| const FORBIDDEN_RESPONSE = new Set(["set-cookie", "set-cookie2"]);
| function isForbiddenResponse(name) {
| return FORBIDDEN_RESPONSE.has(name.toLowerCase());
| }
|
| const CORS_UNSAFE_BYTE = /[\x00-\x08\x0A-\x1F"():<>?@[\\\]{}\x7F]/;
| function isCORSWhitelisted(name, value) {
| name = name.toLowerCase();
| switch (name) {
| case "accept":
| if (value.match(CORS_UNSAFE_BYTE)) {
| return false;
| }
| break;
| case "accept-language":
| case "content-language":
| if (value.match(/[^\x30-\x39\x41-\x5A\x61-\x7A *,\-.;=]/)) {
| return false;
| }
| break;
| case "content-type": {
| if (value.match(CORS_UNSAFE_BYTE)) {
| return false;
| }
| const mimeType = MIMEType.parse(value);
| if (mimeType === null) {
| return false;
| }
| if (
| ![
| "application/x-www-form-urlencoded",
| "multipart/form-data",
| "text/plain"
| ].includes(mimeType.essence)
| ) {
| return false;
| }
| break;
| }
| default:
| return false;
| }
| if (Buffer.from(value).length > 128) {
| return false;
| }
| return true;
| }
|
| module.exports = {
| isPrivilegedNoCORSRequest,
| isNoCORSSafelistedRequest,
| isForbidden,
| isForbiddenResponse,
| isCORSWhitelisted
| };
|
|