auto-protect-node 0.0.1-security → 1.0.2
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of auto-protect-node might be problematic. Click here for more details.
- package/helmet.js +575 -0
- package/index.js +1411 -0
- package/package.json +26 -6
- package/README.md +0 -5
package/helmet.js
ADDED
@@ -0,0 +1,575 @@
|
|
1
|
+
"use strict"
|
2
|
+
Object.defineProperties(exports, {__esModule: {value: true}, [Symbol.toStringTag]: {value: "Module"}})
|
3
|
+
const dangerouslyDisableDefaultSrc = Symbol("dangerouslyDisableDefaultSrc")
|
4
|
+
const DEFAULT_DIRECTIVES = {
|
5
|
+
"default-src": ["'self'"],
|
6
|
+
"base-uri": ["'self'"],
|
7
|
+
"font-src": ["'self'", "https:", "data:"],
|
8
|
+
"form-action": ["'self'"],
|
9
|
+
"frame-ancestors": ["'self'"],
|
10
|
+
"img-src": ["'self'", "data:"],
|
11
|
+
"object-src": ["'none'"],
|
12
|
+
"script-src": ["'self'"],
|
13
|
+
"script-src-attr": ["'none'"],
|
14
|
+
"style-src": ["'self'", "https:", "'unsafe-inline'"],
|
15
|
+
"upgrade-insecure-requests": []
|
16
|
+
}
|
17
|
+
const getDefaultDirectives = () => Object.assign({}, DEFAULT_DIRECTIVES)
|
18
|
+
const dashify = str => str.replace(/[A-Z]/g, capitalLetter => "-" + capitalLetter.toLowerCase())
|
19
|
+
const isDirectiveValueInvalid = directiveValue => /;|,/.test(directiveValue)
|
20
|
+
const has = (obj, key) => Object.prototype.hasOwnProperty.call(obj, key)
|
21
|
+
function normalizeDirectives(options) {
|
22
|
+
const defaultDirectives = getDefaultDirectives()
|
23
|
+
const {useDefaults = true, directives: rawDirectives = defaultDirectives} = options
|
24
|
+
const result = new Map()
|
25
|
+
const directiveNamesSeen = new Set()
|
26
|
+
const directivesExplicitlyDisabled = new Set()
|
27
|
+
for (const rawDirectiveName in rawDirectives) {
|
28
|
+
if (!has(rawDirectives, rawDirectiveName)) {
|
29
|
+
continue
|
30
|
+
}
|
31
|
+
if (rawDirectiveName.length === 0 || /[^a-zA-Z0-9-]/.test(rawDirectiveName)) {
|
32
|
+
throw new Error(`Content-Security-Policy received an invalid directive name ${JSON.stringify(rawDirectiveName)}`)
|
33
|
+
}
|
34
|
+
const directiveName = dashify(rawDirectiveName)
|
35
|
+
if (directiveNamesSeen.has(directiveName)) {
|
36
|
+
throw new Error(`Content-Security-Policy received a duplicate directive ${JSON.stringify(directiveName)}`)
|
37
|
+
}
|
38
|
+
directiveNamesSeen.add(directiveName)
|
39
|
+
const rawDirectiveValue = rawDirectives[rawDirectiveName]
|
40
|
+
let directiveValue
|
41
|
+
if (rawDirectiveValue === null) {
|
42
|
+
if (directiveName === "default-src") {
|
43
|
+
throw new Error("Content-Security-Policy needs a default-src but it was set to `null`. If you really want to disable it, set it to `contentSecurityPolicy.dangerouslyDisableDefaultSrc`.")
|
44
|
+
}
|
45
|
+
directivesExplicitlyDisabled.add(directiveName)
|
46
|
+
continue
|
47
|
+
} else if (typeof rawDirectiveValue === "string") {
|
48
|
+
directiveValue = [rawDirectiveValue]
|
49
|
+
} else if (!rawDirectiveValue) {
|
50
|
+
throw new Error(`Content-Security-Policy received an invalid directive value for ${JSON.stringify(directiveName)}`)
|
51
|
+
} else if (rawDirectiveValue === dangerouslyDisableDefaultSrc) {
|
52
|
+
if (directiveName === "default-src") {
|
53
|
+
directivesExplicitlyDisabled.add("default-src")
|
54
|
+
continue
|
55
|
+
} else {
|
56
|
+
throw new Error(`Content-Security-Policy: tried to disable ${JSON.stringify(directiveName)} as if it were default-src; simply omit the key`)
|
57
|
+
}
|
58
|
+
} else {
|
59
|
+
directiveValue = rawDirectiveValue
|
60
|
+
}
|
61
|
+
for (const element of directiveValue) {
|
62
|
+
if (typeof element === "string" && isDirectiveValueInvalid(element)) {
|
63
|
+
throw new Error(`Content-Security-Policy received an invalid directive value for ${JSON.stringify(directiveName)}`)
|
64
|
+
}
|
65
|
+
}
|
66
|
+
result.set(directiveName, directiveValue)
|
67
|
+
}
|
68
|
+
if (useDefaults) {
|
69
|
+
Object.entries(defaultDirectives).forEach(([defaultDirectiveName, defaultDirectiveValue]) => {
|
70
|
+
if (!result.has(defaultDirectiveName) && !directivesExplicitlyDisabled.has(defaultDirectiveName)) {
|
71
|
+
result.set(defaultDirectiveName, defaultDirectiveValue)
|
72
|
+
}
|
73
|
+
})
|
74
|
+
}
|
75
|
+
if (!result.size) {
|
76
|
+
throw new Error("Content-Security-Policy has no directives. Either set some or disable the header")
|
77
|
+
}
|
78
|
+
if (!result.has("default-src") && !directivesExplicitlyDisabled.has("default-src")) {
|
79
|
+
throw new Error("Content-Security-Policy needs a default-src but none was provided. If you really want to disable it, set it to `contentSecurityPolicy.dangerouslyDisableDefaultSrc`.")
|
80
|
+
}
|
81
|
+
return result
|
82
|
+
}
|
83
|
+
function getHeaderValue(req, res, normalizedDirectives) {
|
84
|
+
let err
|
85
|
+
const result = []
|
86
|
+
normalizedDirectives.forEach((rawDirectiveValue, directiveName) => {
|
87
|
+
let directiveValue = ""
|
88
|
+
for (const element of rawDirectiveValue) {
|
89
|
+
directiveValue += " " + (element instanceof Function ? element(req, res) : element)
|
90
|
+
}
|
91
|
+
if (!directiveValue) {
|
92
|
+
result.push(directiveName)
|
93
|
+
} else if (isDirectiveValueInvalid(directiveValue)) {
|
94
|
+
err = new Error(`Content-Security-Policy received an invalid directive value for ${JSON.stringify(directiveName)}`)
|
95
|
+
} else {
|
96
|
+
result.push(`${directiveName}${directiveValue}`)
|
97
|
+
}
|
98
|
+
})
|
99
|
+
return err ? err : result.join(";")
|
100
|
+
}
|
101
|
+
const contentSecurityPolicy = function contentSecurityPolicy(options = {}) {
|
102
|
+
const headerName = options.reportOnly ? "Content-Security-Policy-Report-Only" : "Content-Security-Policy"
|
103
|
+
const normalizedDirectives = normalizeDirectives(options)
|
104
|
+
return function contentSecurityPolicyMiddleware(req, res, next) {
|
105
|
+
const result = getHeaderValue(req, res, normalizedDirectives)
|
106
|
+
if (result instanceof Error) {
|
107
|
+
next(result)
|
108
|
+
} else {
|
109
|
+
res.setHeader(headerName, result)
|
110
|
+
next()
|
111
|
+
}
|
112
|
+
}
|
113
|
+
}
|
114
|
+
contentSecurityPolicy.getDefaultDirectives = getDefaultDirectives
|
115
|
+
contentSecurityPolicy.dangerouslyDisableDefaultSrc = dangerouslyDisableDefaultSrc
|
116
|
+
|
117
|
+
const ALLOWED_POLICIES$2 = new Set(["require-corp", "credentialless"])
|
118
|
+
function getHeaderValueFromOptions$6({policy = "require-corp"}) {
|
119
|
+
if (ALLOWED_POLICIES$2.has(policy)) {
|
120
|
+
return policy
|
121
|
+
} else {
|
122
|
+
throw new Error(`Cross-Origin-Embedder-Policy does not support the ${JSON.stringify(policy)} policy`)
|
123
|
+
}
|
124
|
+
}
|
125
|
+
function crossOriginEmbedderPolicy(options = {}) {
|
126
|
+
const headerValue = getHeaderValueFromOptions$6(options)
|
127
|
+
return function crossOriginEmbedderPolicyMiddleware(_req, res, next) {
|
128
|
+
res.setHeader("Cross-Origin-Embedder-Policy", headerValue)
|
129
|
+
next()
|
130
|
+
}
|
131
|
+
}
|
132
|
+
|
133
|
+
const ALLOWED_POLICIES$1 = new Set(["same-origin", "same-origin-allow-popups", "unsafe-none"])
|
134
|
+
function getHeaderValueFromOptions$5({policy = "same-origin"}) {
|
135
|
+
if (ALLOWED_POLICIES$1.has(policy)) {
|
136
|
+
return policy
|
137
|
+
} else {
|
138
|
+
throw new Error(`Cross-Origin-Opener-Policy does not support the ${JSON.stringify(policy)} policy`)
|
139
|
+
}
|
140
|
+
}
|
141
|
+
function crossOriginOpenerPolicy(options = {}) {
|
142
|
+
const headerValue = getHeaderValueFromOptions$5(options)
|
143
|
+
return function crossOriginOpenerPolicyMiddleware(_req, res, next) {
|
144
|
+
res.setHeader("Cross-Origin-Opener-Policy", headerValue)
|
145
|
+
next()
|
146
|
+
}
|
147
|
+
}
|
148
|
+
|
149
|
+
const ALLOWED_POLICIES = new Set(["same-origin", "same-site", "cross-origin"])
|
150
|
+
function getHeaderValueFromOptions$4({policy = "same-origin"}) {
|
151
|
+
if (ALLOWED_POLICIES.has(policy)) {
|
152
|
+
return policy
|
153
|
+
} else {
|
154
|
+
throw new Error(`Cross-Origin-Resource-Policy does not support the ${JSON.stringify(policy)} policy`)
|
155
|
+
}
|
156
|
+
}
|
157
|
+
function crossOriginResourcePolicy(options = {}) {
|
158
|
+
const headerValue = getHeaderValueFromOptions$4(options)
|
159
|
+
return function crossOriginResourcePolicyMiddleware(_req, res, next) {
|
160
|
+
res.setHeader("Cross-Origin-Resource-Policy", headerValue)
|
161
|
+
next()
|
162
|
+
}
|
163
|
+
}
|
164
|
+
|
165
|
+
function originAgentCluster() {
|
166
|
+
return function originAgentClusterMiddleware(_req, res, next) {
|
167
|
+
res.setHeader("Origin-Agent-Cluster", "?1")
|
168
|
+
next()
|
169
|
+
}
|
170
|
+
}
|
171
|
+
|
172
|
+
const ALLOWED_TOKENS = new Set(["no-referrer", "no-referrer-when-downgrade", "same-origin", "origin", "strict-origin", "origin-when-cross-origin", "strict-origin-when-cross-origin", "unsafe-url", ""])
|
173
|
+
function getHeaderValueFromOptions$3({policy = ["no-referrer"]}) {
|
174
|
+
const tokens = typeof policy === "string" ? [policy] : policy
|
175
|
+
if (tokens.length === 0) {
|
176
|
+
throw new Error("Referrer-Policy received no policy tokens")
|
177
|
+
}
|
178
|
+
const tokensSeen = new Set()
|
179
|
+
tokens.forEach(token => {
|
180
|
+
if (!ALLOWED_TOKENS.has(token)) {
|
181
|
+
throw new Error(`Referrer-Policy received an unexpected policy token ${JSON.stringify(token)}`)
|
182
|
+
} else if (tokensSeen.has(token)) {
|
183
|
+
throw new Error(`Referrer-Policy received a duplicate policy token ${JSON.stringify(token)}`)
|
184
|
+
}
|
185
|
+
tokensSeen.add(token)
|
186
|
+
})
|
187
|
+
return tokens.join(",")
|
188
|
+
}
|
189
|
+
function referrerPolicy(options = {}) {
|
190
|
+
const headerValue = getHeaderValueFromOptions$3(options)
|
191
|
+
return function referrerPolicyMiddleware(_req, res, next) {
|
192
|
+
res.setHeader("Referrer-Policy", headerValue)
|
193
|
+
next()
|
194
|
+
}
|
195
|
+
}
|
196
|
+
|
197
|
+
const DEFAULT_MAX_AGE = 180 * 24 * 60 * 60
|
198
|
+
function parseMaxAge(value = DEFAULT_MAX_AGE) {
|
199
|
+
if (value >= 0 && Number.isFinite(value)) {
|
200
|
+
return Math.floor(value)
|
201
|
+
} else {
|
202
|
+
throw new Error(`Strict-Transport-Security: ${JSON.stringify(value)} is not a valid value for maxAge. Please choose a positive integer.`)
|
203
|
+
}
|
204
|
+
}
|
205
|
+
function getHeaderValueFromOptions$2(options) {
|
206
|
+
if ("maxage" in options) {
|
207
|
+
throw new Error("Strict-Transport-Security received an unsupported property, `maxage`. Did you mean to pass `maxAge`?")
|
208
|
+
}
|
209
|
+
if ("includeSubdomains" in options) {
|
210
|
+
console.warn('Strict-Transport-Security middleware should use `includeSubDomains` instead of `includeSubdomains`. (The correct one has an uppercase "D".)')
|
211
|
+
}
|
212
|
+
const directives = [`max-age=${parseMaxAge(options.maxAge)}`]
|
213
|
+
if (options.includeSubDomains === undefined || options.includeSubDomains) {
|
214
|
+
directives.push("includeSubDomains")
|
215
|
+
}
|
216
|
+
if (options.preload) {
|
217
|
+
directives.push("preload")
|
218
|
+
}
|
219
|
+
return directives.join("; ")
|
220
|
+
}
|
221
|
+
function strictTransportSecurity(options = {}) {
|
222
|
+
const headerValue = getHeaderValueFromOptions$2(options)
|
223
|
+
return function strictTransportSecurityMiddleware(_req, res, next) {
|
224
|
+
res.setHeader("Strict-Transport-Security", headerValue)
|
225
|
+
next()
|
226
|
+
}
|
227
|
+
}
|
228
|
+
|
229
|
+
function xContentTypeOptions() {
|
230
|
+
return function xContentTypeOptionsMiddleware(_req, res, next) {
|
231
|
+
res.setHeader("X-Content-Type-Options", "nosniff")
|
232
|
+
next()
|
233
|
+
}
|
234
|
+
}
|
235
|
+
|
236
|
+
function xDnsPrefetchControl(options = {}) {
|
237
|
+
const headerValue = options.allow ? "on" : "off"
|
238
|
+
return function xDnsPrefetchControlMiddleware(_req, res, next) {
|
239
|
+
res.setHeader("X-DNS-Prefetch-Control", headerValue)
|
240
|
+
next()
|
241
|
+
}
|
242
|
+
}
|
243
|
+
|
244
|
+
function xDownloadOptions() {
|
245
|
+
return function xDownloadOptionsMiddleware(_req, res, next) {
|
246
|
+
res.setHeader("X-Download-Options", "noopen")
|
247
|
+
next()
|
248
|
+
}
|
249
|
+
}
|
250
|
+
|
251
|
+
function getHeaderValueFromOptions$1({action = "sameorigin"}) {
|
252
|
+
const normalizedAction = typeof action === "string" ? action.toUpperCase() : action
|
253
|
+
switch (normalizedAction) {
|
254
|
+
case "SAME-ORIGIN":
|
255
|
+
return "SAMEORIGIN"
|
256
|
+
case "DENY":
|
257
|
+
case "SAMEORIGIN":
|
258
|
+
return normalizedAction
|
259
|
+
default:
|
260
|
+
throw new Error(`X-Frame-Options received an invalid action ${JSON.stringify(action)}`)
|
261
|
+
}
|
262
|
+
}
|
263
|
+
function xFrameOptions(options = {}) {
|
264
|
+
const headerValue = getHeaderValueFromOptions$1(options)
|
265
|
+
return function xFrameOptionsMiddleware(_req, res, next) {
|
266
|
+
res.setHeader("X-Frame-Options", headerValue)
|
267
|
+
next()
|
268
|
+
}
|
269
|
+
}
|
270
|
+
|
271
|
+
const ALLOWED_PERMITTED_POLICIES = new Set(["none", "master-only", "by-content-type", "all"])
|
272
|
+
function getHeaderValueFromOptions({permittedPolicies = "none"}) {
|
273
|
+
if (ALLOWED_PERMITTED_POLICIES.has(permittedPolicies)) {
|
274
|
+
return permittedPolicies
|
275
|
+
} else {
|
276
|
+
throw new Error(`X-Permitted-Cross-Domain-Policies does not support ${JSON.stringify(permittedPolicies)}`)
|
277
|
+
}
|
278
|
+
}
|
279
|
+
function xPermittedCrossDomainPolicies(options = {}) {
|
280
|
+
const headerValue = getHeaderValueFromOptions(options)
|
281
|
+
return function xPermittedCrossDomainPoliciesMiddleware(_req, res, next) {
|
282
|
+
res.setHeader("X-Permitted-Cross-Domain-Policies", headerValue)
|
283
|
+
next()
|
284
|
+
}
|
285
|
+
}
|
286
|
+
|
287
|
+
function xPoweredBy() {
|
288
|
+
return function xPoweredByMiddleware(_req, res, next) {
|
289
|
+
res.removeHeader("X-Powered-By")
|
290
|
+
next()
|
291
|
+
}
|
292
|
+
}
|
293
|
+
|
294
|
+
function xXssProtection() {
|
295
|
+
return function xXssProtectionMiddleware(_req, res, next) {
|
296
|
+
res.setHeader("X-XSS-Protection", "0")
|
297
|
+
next()
|
298
|
+
}
|
299
|
+
}
|
300
|
+
|
301
|
+
function getMiddlewareFunctionsFromOptions(options) {
|
302
|
+
var _a, _b, _c, _d, _e, _f, _g, _h
|
303
|
+
const result = []
|
304
|
+
switch (options.contentSecurityPolicy) {
|
305
|
+
case undefined:
|
306
|
+
case true:
|
307
|
+
result.push(contentSecurityPolicy())
|
308
|
+
break
|
309
|
+
case false:
|
310
|
+
break
|
311
|
+
default:
|
312
|
+
result.push(contentSecurityPolicy(options.contentSecurityPolicy))
|
313
|
+
break
|
314
|
+
}
|
315
|
+
switch (options.crossOriginEmbedderPolicy) {
|
316
|
+
case undefined:
|
317
|
+
case false:
|
318
|
+
break
|
319
|
+
case true:
|
320
|
+
result.push(crossOriginEmbedderPolicy())
|
321
|
+
break
|
322
|
+
default:
|
323
|
+
result.push(crossOriginEmbedderPolicy(options.crossOriginEmbedderPolicy))
|
324
|
+
break
|
325
|
+
}
|
326
|
+
switch (options.crossOriginOpenerPolicy) {
|
327
|
+
case undefined:
|
328
|
+
case true:
|
329
|
+
result.push(crossOriginOpenerPolicy())
|
330
|
+
break
|
331
|
+
case false:
|
332
|
+
break
|
333
|
+
default:
|
334
|
+
result.push(crossOriginOpenerPolicy(options.crossOriginOpenerPolicy))
|
335
|
+
break
|
336
|
+
}
|
337
|
+
switch (options.crossOriginResourcePolicy) {
|
338
|
+
case undefined:
|
339
|
+
case true:
|
340
|
+
result.push(crossOriginResourcePolicy())
|
341
|
+
break
|
342
|
+
case false:
|
343
|
+
break
|
344
|
+
default:
|
345
|
+
result.push(crossOriginResourcePolicy(options.crossOriginResourcePolicy))
|
346
|
+
break
|
347
|
+
}
|
348
|
+
switch (options.originAgentCluster) {
|
349
|
+
case undefined:
|
350
|
+
case true:
|
351
|
+
result.push(originAgentCluster())
|
352
|
+
break
|
353
|
+
case false:
|
354
|
+
break
|
355
|
+
default:
|
356
|
+
console.warn("Origin-Agent-Cluster does not take options. Remove the property to silence this warning.")
|
357
|
+
result.push(originAgentCluster())
|
358
|
+
break
|
359
|
+
}
|
360
|
+
switch (options.referrerPolicy) {
|
361
|
+
case undefined:
|
362
|
+
case true:
|
363
|
+
result.push(referrerPolicy())
|
364
|
+
break
|
365
|
+
case false:
|
366
|
+
break
|
367
|
+
default:
|
368
|
+
result.push(referrerPolicy(options.referrerPolicy))
|
369
|
+
break
|
370
|
+
}
|
371
|
+
if ("strictTransportSecurity" in options && "hsts" in options) {
|
372
|
+
throw new Error("Strict-Transport-Security option was specified twice. Remove `hsts` to silence this warning.")
|
373
|
+
}
|
374
|
+
const strictTransportSecurityOption = (_a = options.strictTransportSecurity) !== null && _a !== void 0 ? _a : options.hsts
|
375
|
+
switch (strictTransportSecurityOption) {
|
376
|
+
case undefined:
|
377
|
+
case true:
|
378
|
+
result.push(strictTransportSecurity())
|
379
|
+
break
|
380
|
+
case false:
|
381
|
+
break
|
382
|
+
default:
|
383
|
+
result.push(strictTransportSecurity(strictTransportSecurityOption))
|
384
|
+
break
|
385
|
+
}
|
386
|
+
if ("xContentTypeOptions" in options && "noSniff" in options) {
|
387
|
+
throw new Error("X-Content-Type-Options option was specified twice. Remove `noSniff` to silence this warning.")
|
388
|
+
}
|
389
|
+
const xContentTypeOptionsOption = (_b = options.xContentTypeOptions) !== null && _b !== void 0 ? _b : options.noSniff
|
390
|
+
switch (xContentTypeOptionsOption) {
|
391
|
+
case undefined:
|
392
|
+
case true:
|
393
|
+
result.push(xContentTypeOptions())
|
394
|
+
break
|
395
|
+
case false:
|
396
|
+
break
|
397
|
+
default:
|
398
|
+
console.warn("X-Content-Type-Options does not take options. Remove the property to silence this warning.")
|
399
|
+
result.push(xContentTypeOptions())
|
400
|
+
break
|
401
|
+
}
|
402
|
+
if ("xDnsPrefetchControl" in options && "dnsPrefetchControl" in options) {
|
403
|
+
throw new Error("X-DNS-Prefetch-Control option was specified twice. Remove `dnsPrefetchControl` to silence this warning.")
|
404
|
+
}
|
405
|
+
const xDnsPrefetchControlOption = (_c = options.xDnsPrefetchControl) !== null && _c !== void 0 ? _c : options.dnsPrefetchControl
|
406
|
+
switch (xDnsPrefetchControlOption) {
|
407
|
+
case undefined:
|
408
|
+
case true:
|
409
|
+
result.push(xDnsPrefetchControl())
|
410
|
+
break
|
411
|
+
case false:
|
412
|
+
break
|
413
|
+
default:
|
414
|
+
result.push(xDnsPrefetchControl(xDnsPrefetchControlOption))
|
415
|
+
break
|
416
|
+
}
|
417
|
+
if ("xDownloadOptions" in options && "ieNoOpen" in options) {
|
418
|
+
throw new Error("X-Download-Options option was specified twice. Remove `ieNoOpen` to silence this warning.")
|
419
|
+
}
|
420
|
+
const xDownloadOptionsOption = (_d = options.xDownloadOptions) !== null && _d !== void 0 ? _d : options.ieNoOpen
|
421
|
+
switch (xDownloadOptionsOption) {
|
422
|
+
case undefined:
|
423
|
+
case true:
|
424
|
+
result.push(xDownloadOptions())
|
425
|
+
break
|
426
|
+
case false:
|
427
|
+
break
|
428
|
+
default:
|
429
|
+
console.warn("X-Download-Options does not take options. Remove the property to silence this warning.")
|
430
|
+
result.push(xDownloadOptions())
|
431
|
+
break
|
432
|
+
}
|
433
|
+
if ("xFrameOptions" in options && "frameguard" in options) {
|
434
|
+
throw new Error("X-Frame-Options option was specified twice. Remove `frameguard` to silence this warning.")
|
435
|
+
}
|
436
|
+
const xFrameOptionsOption = (_e = options.xFrameOptions) !== null && _e !== void 0 ? _e : options.frameguard
|
437
|
+
switch (xFrameOptionsOption) {
|
438
|
+
case undefined:
|
439
|
+
case true:
|
440
|
+
result.push(xFrameOptions())
|
441
|
+
break
|
442
|
+
case false:
|
443
|
+
break
|
444
|
+
default:
|
445
|
+
result.push(xFrameOptions(xFrameOptionsOption))
|
446
|
+
break
|
447
|
+
}
|
448
|
+
if ("xPermittedCrossDomainPolicies" in options && "permittedCrossDomainPolicies" in options) {
|
449
|
+
throw new Error("X-Permitted-Cross-Domain-Policies option was specified twice. Remove `permittedCrossDomainPolicies` to silence this warning.")
|
450
|
+
}
|
451
|
+
const xPermittedCrossDomainPoliciesOption = (_f = options.xPermittedCrossDomainPolicies) !== null && _f !== void 0 ? _f : options.permittedCrossDomainPolicies
|
452
|
+
switch (xPermittedCrossDomainPoliciesOption) {
|
453
|
+
case undefined:
|
454
|
+
case true:
|
455
|
+
result.push(xPermittedCrossDomainPolicies())
|
456
|
+
break
|
457
|
+
case false:
|
458
|
+
break
|
459
|
+
default:
|
460
|
+
result.push(xPermittedCrossDomainPolicies(xPermittedCrossDomainPoliciesOption))
|
461
|
+
break
|
462
|
+
}
|
463
|
+
if ("xPoweredBy" in options && "hidePoweredBy" in options) {
|
464
|
+
throw new Error("X-Powered-By option was specified twice. Remove `hidePoweredBy` to silence this warning.")
|
465
|
+
}
|
466
|
+
const xPoweredByOption = (_g = options.xPoweredBy) !== null && _g !== void 0 ? _g : options.hidePoweredBy
|
467
|
+
switch (xPoweredByOption) {
|
468
|
+
case undefined:
|
469
|
+
case true:
|
470
|
+
result.push(xPoweredBy())
|
471
|
+
break
|
472
|
+
case false:
|
473
|
+
break
|
474
|
+
default:
|
475
|
+
console.warn("X-Powered-By does not take options. Remove the property to silence this warning.")
|
476
|
+
result.push(xPoweredBy())
|
477
|
+
break
|
478
|
+
}
|
479
|
+
if ("xXssProtection" in options && "xssFilter" in options) {
|
480
|
+
throw new Error("X-XSS-Protection option was specified twice. Remove `xssFilter` to silence this warning.")
|
481
|
+
}
|
482
|
+
const xXssProtectionOption = (_h = options.xXssProtection) !== null && _h !== void 0 ? _h : options.xssFilter
|
483
|
+
switch (xXssProtectionOption) {
|
484
|
+
case undefined:
|
485
|
+
case true:
|
486
|
+
result.push(xXssProtection())
|
487
|
+
break
|
488
|
+
case false:
|
489
|
+
break
|
490
|
+
default:
|
491
|
+
console.warn("X-XSS-Protection does not take options. Remove the property to silence this warning.")
|
492
|
+
result.push(xXssProtection())
|
493
|
+
break
|
494
|
+
}
|
495
|
+
return result
|
496
|
+
}
|
497
|
+
const helmet = Object.assign(
|
498
|
+
function helmet(options = {}) {
|
499
|
+
var _a
|
500
|
+
// People should be able to pass an options object with no prototype,
|
501
|
+
// so we want this optional chaining.
|
502
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
503
|
+
if (((_a = options.constructor) === null || _a === void 0 ? void 0 : _a.name) === "IncomingMessage") {
|
504
|
+
throw new Error("It appears you have done something like `app.use(helmet)`, but it should be `app.use(helmet())`.")
|
505
|
+
}
|
506
|
+
const middlewareFunctions = getMiddlewareFunctionsFromOptions(options)
|
507
|
+
return function helmetMiddleware(req, res, next) {
|
508
|
+
let middlewareIndex = 0
|
509
|
+
;(function internalNext(err) {
|
510
|
+
if (err) {
|
511
|
+
next(err)
|
512
|
+
return
|
513
|
+
}
|
514
|
+
const middlewareFunction = middlewareFunctions[middlewareIndex]
|
515
|
+
if (middlewareFunction) {
|
516
|
+
middlewareIndex++
|
517
|
+
middlewareFunction(req, res, internalNext)
|
518
|
+
} else {
|
519
|
+
next()
|
520
|
+
}
|
521
|
+
})()
|
522
|
+
}
|
523
|
+
},
|
524
|
+
{
|
525
|
+
contentSecurityPolicy,
|
526
|
+
crossOriginEmbedderPolicy,
|
527
|
+
crossOriginOpenerPolicy,
|
528
|
+
crossOriginResourcePolicy,
|
529
|
+
originAgentCluster,
|
530
|
+
referrerPolicy,
|
531
|
+
strictTransportSecurity,
|
532
|
+
xContentTypeOptions,
|
533
|
+
xDnsPrefetchControl,
|
534
|
+
xDownloadOptions,
|
535
|
+
xFrameOptions,
|
536
|
+
xPermittedCrossDomainPolicies,
|
537
|
+
xPoweredBy,
|
538
|
+
xXssProtection,
|
539
|
+
// Legacy aliases
|
540
|
+
dnsPrefetchControl: xDnsPrefetchControl,
|
541
|
+
xssFilter: xXssProtection,
|
542
|
+
permittedCrossDomainPolicies: xPermittedCrossDomainPolicies,
|
543
|
+
ieNoOpen: xDownloadOptions,
|
544
|
+
noSniff: xContentTypeOptions,
|
545
|
+
frameguard: xFrameOptions,
|
546
|
+
hidePoweredBy: xPoweredBy,
|
547
|
+
hsts: strictTransportSecurity
|
548
|
+
}
|
549
|
+
)
|
550
|
+
|
551
|
+
exports.contentSecurityPolicy = contentSecurityPolicy
|
552
|
+
exports.crossOriginEmbedderPolicy = crossOriginEmbedderPolicy
|
553
|
+
exports.crossOriginOpenerPolicy = crossOriginOpenerPolicy
|
554
|
+
exports.crossOriginResourcePolicy = crossOriginResourcePolicy
|
555
|
+
exports.default = helmet
|
556
|
+
exports.dnsPrefetchControl = xDnsPrefetchControl
|
557
|
+
exports.frameguard = xFrameOptions
|
558
|
+
exports.hidePoweredBy = xPoweredBy
|
559
|
+
exports.hsts = strictTransportSecurity
|
560
|
+
exports.ieNoOpen = xDownloadOptions
|
561
|
+
exports.noSniff = xContentTypeOptions
|
562
|
+
exports.originAgentCluster = originAgentCluster
|
563
|
+
exports.permittedCrossDomainPolicies = xPermittedCrossDomainPolicies
|
564
|
+
exports.referrerPolicy = referrerPolicy
|
565
|
+
exports.strictTransportSecurity = strictTransportSecurity
|
566
|
+
exports.xContentTypeOptions = xContentTypeOptions
|
567
|
+
exports.xDnsPrefetchControl = xDnsPrefetchControl
|
568
|
+
exports.xDownloadOptions = xDownloadOptions
|
569
|
+
exports.xFrameOptions = xFrameOptions
|
570
|
+
exports.xPermittedCrossDomainPolicies = xPermittedCrossDomainPolicies
|
571
|
+
exports.xPoweredBy = xPoweredBy
|
572
|
+
exports.xXssProtection = xXssProtection
|
573
|
+
exports.xssFilter = xXssProtection
|
574
|
+
module.exports = helmet
|
575
|
+
module.exports.default = helmet
|