@middy/http-security-headers 6.1.6 → 6.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/index.d.ts +56 -56
  2. package/index.js +257 -255
  3. package/package.json +71 -74
package/index.d.ts CHANGED
@@ -1,62 +1,62 @@
1
- import middy from '@middy/core'
1
+ import type middy from "@middy/core";
2
2
 
3
3
  interface Options {
4
- dnsPrefetchControl?: {
5
- allow?: boolean
6
- }
7
- frameOptions?: {
8
- action?: string
9
- }
10
- poweredBy?: {
11
- server: string
12
- }
13
- strictTransportSecurity?: {
14
- maxAge?: number
15
- includeSubDomains?: boolean
16
- preload?: boolean
17
- }
18
- downloadOptions?: {
19
- action?: string
20
- }
21
- contentTypeOptions?: {
22
- action?: string
23
- }
24
- originAgentCluster?: boolean
25
- referrerPolicy?: {
26
- policy?: string
27
- }
28
- xssProtection?: {
29
- reportUri?: string
30
- }
31
- contentSecurityPolicy?: Record<string, string>
32
- contentSecurityPolicyReportOnly?: boolean
33
- crossOriginEmbedderPolicy?: {
34
- policy?: string
35
- }
36
- crossOriginOpenerPolicy?: {
37
- policy?: string
38
- }
39
- crossOriginResourcePolicy?: {
40
- policy?: string
41
- }
42
- permissionsPolicy?: Record<string, string>
43
- permittedCrossDomainPolicies?: {
44
- policy?: string
45
- }
46
- reportTo?: {
47
- maxAge?: number
48
- default?: string
49
- includeSubdomains?: boolean
50
- csp?: string
51
- staple?: string
52
- xss?: string
53
- }
4
+ dnsPrefetchControl?: {
5
+ allow?: boolean;
6
+ };
7
+ frameOptions?: {
8
+ action?: string;
9
+ };
10
+ poweredBy?: {
11
+ server: string;
12
+ };
13
+ strictTransportSecurity?: {
14
+ maxAge?: number;
15
+ includeSubDomains?: boolean;
16
+ preload?: boolean;
17
+ };
18
+ downloadOptions?: {
19
+ action?: string;
20
+ };
21
+ contentTypeOptions?: {
22
+ action?: string;
23
+ };
24
+ originAgentCluster?: boolean;
25
+ referrerPolicy?: {
26
+ policy?: string;
27
+ };
28
+ xssProtection?: {
29
+ reportUri?: string;
30
+ };
31
+ contentSecurityPolicy?: Record<string, string>;
32
+ contentSecurityPolicyReportOnly?: boolean;
33
+ crossOriginEmbedderPolicy?: {
34
+ policy?: string;
35
+ };
36
+ crossOriginOpenerPolicy?: {
37
+ policy?: string;
38
+ };
39
+ crossOriginResourcePolicy?: {
40
+ policy?: string;
41
+ };
42
+ permissionsPolicy?: Record<string, string>;
43
+ permittedCrossDomainPolicies?: {
44
+ policy?: string;
45
+ };
46
+ reportTo?: {
47
+ maxAge?: number;
48
+ default?: string;
49
+ includeSubdomains?: boolean;
50
+ csp?: string;
51
+ staple?: string;
52
+ xss?: string;
53
+ };
54
54
  }
55
55
 
56
- type WithBoolValues<T> = { [K in keyof T]: T[K] | boolean }
56
+ type WithBoolValues<T> = { [K in keyof T]: T[K] | boolean };
57
57
 
58
- declare function httpSecurityHeaders (
59
- options?: WithBoolValues<Options>
60
- ): middy.MiddlewareObj
58
+ declare function httpSecurityHeaders(
59
+ options?: WithBoolValues<Options>,
60
+ ): middy.MiddlewareObj;
61
61
 
62
- export default httpSecurityHeaders
62
+ export default httpSecurityHeaders;
package/index.js CHANGED
@@ -1,316 +1,318 @@
1
- import { normalizeHttpResponse } from '@middy/util'
1
+ import { normalizeHttpResponse } from "@middy/util";
2
2
 
3
3
  // Code and Defaults heavily based off https://helmetjs.github.io/
4
4
 
5
5
  const defaults = {
6
- contentSecurityPolicy: {
7
- // Fetch directives
8
- // 'child-src': '', // fallback default-src
9
- // 'connect-src': '', // fallback default-src
10
- 'default-src': "'none'",
11
- // 'font-src':'', // fallback default-src
12
- // 'frame-src':'', // fallback child-src > default-src
13
- // 'img-src':'', // fallback default-src
14
- // 'manifest-src':'', // fallback default-src
15
- // 'media-src':'', // fallback default-src
16
- // 'object-src':'', // fallback default-src
17
- // 'prefetch-src':'', // fallback default-src
18
- // 'script-src':'', // fallback default-src
19
- // 'script-src-elem':'', // fallback script-src > default-src
20
- // 'script-src-attr':'', // fallback script-src > default-src
21
- // 'style-src':'', // fallback default-src
22
- // 'style-src-elem':'', // fallback style-src > default-src
23
- // 'style-src-attr':'', // fallback style-src > default-src
24
- // 'worker-src':'', // fallback child-src > script-src > default-src
25
- // Document directives
26
- 'base-uri': "'none'",
27
- sandbox: '',
28
- // Navigation directives
29
- 'form-action': "'none'",
30
- 'frame-ancestors': "'none'",
31
- 'navigate-to': "'none'",
32
- // Reporting directives
33
- 'report-to': 'csp',
34
- // Other directives
35
- 'require-trusted-types-for': "'script'",
36
- 'trusted-types': "'none'",
37
- 'upgrade-insecure-requests': ''
38
- },
39
- contentSecurityPolicyReportOnly: false,
40
- contentTypeOptions: {
41
- action: 'nosniff'
42
- },
43
- crossOriginEmbedderPolicy: {
44
- policy: 'require-corp'
45
- },
46
- crossOriginOpenerPolicy: {
47
- policy: 'same-origin'
48
- },
49
- crossOriginResourcePolicy: {
50
- policy: 'same-origin'
51
- },
52
- dnsPrefetchControl: {
53
- allow: false
54
- },
55
- downloadOptions: {
56
- action: 'noopen'
57
- },
58
- frameOptions: {
59
- action: 'deny'
60
- },
61
- originAgentCluster: {},
62
- permissionsPolicy: {
63
- // Standard
64
- accelerometer: '',
65
- 'ambient-light-sensor': '',
66
- autoplay: '',
67
- battery: '',
68
- camera: '',
69
- 'cross-origin-isolated': '',
70
- 'display-capture': '',
71
- 'document-domain': '',
72
- 'encrypted-media': '',
73
- 'execution-while-not-rendered': '',
74
- 'execution-while-out-of-viewport': '',
75
- fullscreen: '',
76
- geolocation: '',
77
- gyroscope: '',
78
- 'keyboard-map': '',
79
- magnetometer: '',
80
- microphone: '',
81
- midi: '',
82
- 'navigation-override': '',
83
- payment: '',
84
- 'picture-in-picture': '',
85
- 'publickey-credentials-get': '',
86
- 'screen-wake-lock': '',
87
- 'sync-xhr': '',
88
- usb: '',
89
- 'web-share': '',
90
- 'xr-spatial-tracking': '',
91
- // Proposed
92
- 'clipboard-read': '',
93
- 'clipboard-write': '',
94
- gamepad: '',
95
- 'speaker-selection': '',
96
- // Experimental
97
- 'conversion-measurement': '',
98
- 'focus-without-user-activation': '',
99
- hid: '',
100
- 'idle-detection': '',
101
- 'interest-cohort': '',
102
- serial: '',
103
- 'sync-script': '',
104
- 'trust-token-redemption': '',
105
- 'window-placement': '',
106
- 'vertical-scroll': ''
107
- },
108
- permittedCrossDomainPolicies: {
109
- policy: 'none' // none, master-only, by-content-type, by-ftp-filename, all
110
- },
111
- poweredBy: {
112
- server: ''
113
- },
114
- referrerPolicy: {
115
- policy: 'no-referrer'
116
- },
117
- reportingEndpoints: {},
118
- reportTo: {
119
- maxAge: 365 * 24 * 60 * 60,
120
- // default: '',
121
- includeSubdomains: true
122
- // csp: '',
123
- // permissions: '',
124
- // staple: '',
125
- // xss: ''
126
- },
127
- strictTransportSecurity: {
128
- maxAge: 180 * 24 * 60 * 60,
129
- includeSubDomains: true,
130
- preload: true
131
- },
132
- xssProtection: {
133
- reportTo: 'xss'
134
- }
135
- }
6
+ contentSecurityPolicy: {
7
+ // Fetch directives
8
+ // 'child-src': '', // fallback default-src
9
+ // 'connect-src': '', // fallback default-src
10
+ "default-src": "'none'",
11
+ // 'font-src':'', // fallback default-src
12
+ // 'frame-src':'', // fallback child-src > default-src
13
+ // 'img-src':'', // fallback default-src
14
+ // 'manifest-src':'', // fallback default-src
15
+ // 'media-src':'', // fallback default-src
16
+ // 'object-src':'', // fallback default-src
17
+ // 'prefetch-src':'', // fallback default-src
18
+ // 'script-src':'', // fallback default-src
19
+ // 'script-src-elem':'', // fallback script-src > default-src
20
+ // 'script-src-attr':'', // fallback script-src > default-src
21
+ // 'style-src':'', // fallback default-src
22
+ // 'style-src-elem':'', // fallback style-src > default-src
23
+ // 'style-src-attr':'', // fallback style-src > default-src
24
+ // 'worker-src':'', // fallback child-src > script-src > default-src
25
+ // Document directives
26
+ "base-uri": "'none'",
27
+ sandbox: "",
28
+ // Navigation directives
29
+ "form-action": "'none'",
30
+ "frame-ancestors": "'none'",
31
+ "navigate-to": "'none'",
32
+ // Reporting directives
33
+ "report-to": "csp",
34
+ // Other directives
35
+ "require-trusted-types-for": "'script'",
36
+ "trusted-types": "'none'",
37
+ "upgrade-insecure-requests": "",
38
+ },
39
+ contentSecurityPolicyReportOnly: false,
40
+ contentTypeOptions: {
41
+ action: "nosniff",
42
+ },
43
+ crossOriginEmbedderPolicy: {
44
+ policy: "require-corp",
45
+ },
46
+ crossOriginOpenerPolicy: {
47
+ policy: "same-origin",
48
+ },
49
+ crossOriginResourcePolicy: {
50
+ policy: "same-origin",
51
+ },
52
+ dnsPrefetchControl: {
53
+ allow: false,
54
+ },
55
+ downloadOptions: {
56
+ action: "noopen",
57
+ },
58
+ frameOptions: {
59
+ action: "deny",
60
+ },
61
+ originAgentCluster: {},
62
+ permissionsPolicy: {
63
+ // Standard
64
+ accelerometer: "",
65
+ "ambient-light-sensor": "",
66
+ autoplay: "",
67
+ battery: "",
68
+ camera: "",
69
+ "cross-origin-isolated": "",
70
+ "display-capture": "",
71
+ "document-domain": "",
72
+ "encrypted-media": "",
73
+ "execution-while-not-rendered": "",
74
+ "execution-while-out-of-viewport": "",
75
+ fullscreen: "",
76
+ geolocation: "",
77
+ gyroscope: "",
78
+ "keyboard-map": "",
79
+ magnetometer: "",
80
+ microphone: "",
81
+ midi: "",
82
+ "navigation-override": "",
83
+ payment: "",
84
+ "picture-in-picture": "",
85
+ "publickey-credentials-get": "",
86
+ "screen-wake-lock": "",
87
+ "sync-xhr": "",
88
+ usb: "",
89
+ "web-share": "",
90
+ "xr-spatial-tracking": "",
91
+ // Proposed
92
+ "clipboard-read": "",
93
+ "clipboard-write": "",
94
+ gamepad: "",
95
+ "speaker-selection": "",
96
+ // Experimental
97
+ "conversion-measurement": "",
98
+ "focus-without-user-activation": "",
99
+ hid: "",
100
+ "idle-detection": "",
101
+ "interest-cohort": "",
102
+ serial: "",
103
+ "sync-script": "",
104
+ "trust-token-redemption": "",
105
+ "window-placement": "",
106
+ "vertical-scroll": "",
107
+ },
108
+ permittedCrossDomainPolicies: {
109
+ policy: "none", // none, master-only, by-content-type, by-ftp-filename, all
110
+ },
111
+ poweredBy: {
112
+ server: "",
113
+ },
114
+ referrerPolicy: {
115
+ policy: "no-referrer",
116
+ },
117
+ reportingEndpoints: {},
118
+ reportTo: {
119
+ maxAge: 365 * 24 * 60 * 60,
120
+ // default: '',
121
+ includeSubdomains: true,
122
+ // csp: '',
123
+ // permissions: '',
124
+ // staple: '',
125
+ // xss: ''
126
+ },
127
+ strictTransportSecurity: {
128
+ maxAge: 180 * 24 * 60 * 60,
129
+ includeSubDomains: true,
130
+ preload: true,
131
+ },
132
+ xssProtection: {
133
+ reportTo: "xss",
134
+ },
135
+ };
136
136
 
137
- const helmet = {}
138
- const helmetHtmlOnly = {}
137
+ const helmet = {};
138
+ const helmetHtmlOnly = {};
139
139
 
140
140
  // *** https://github.com/helmetjs/helmet/tree/main/middlewares *** //
141
141
  // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy
142
142
  helmetHtmlOnly.contentSecurityPolicy = (reportOnly) => (headers, config) => {
143
- let header = Object.keys(config)
144
- .map((policy) => (config[policy] ? `${policy} ${config[policy]}` : ''))
145
- .filter((str) => str)
146
- .join('; ')
147
- if (config.sandbox === '') {
148
- header += '; sandbox'
149
- }
150
- if (config['upgrade-insecure-requests'] === '') {
151
- header += '; upgrade-insecure-requests'
152
- }
143
+ let header = Object.keys(config)
144
+ .map((policy) => (config[policy] ? `${policy} ${config[policy]}` : ""))
145
+ .filter((str) => str)
146
+ .join("; ");
147
+ if (config.sandbox === "") {
148
+ header += "; sandbox";
149
+ }
150
+ if (config["upgrade-insecure-requests"] === "") {
151
+ header += "; upgrade-insecure-requests";
152
+ }
153
153
 
154
- const cspHeaderName = reportOnly
155
- ? 'Content-Security-Policy-Report-Only'
156
- : 'Content-Security-Policy'
157
- headers[cspHeaderName] = header
158
- }
154
+ const cspHeaderName = reportOnly
155
+ ? "Content-Security-Policy-Report-Only"
156
+ : "Content-Security-Policy";
157
+ headers[cspHeaderName] = header;
158
+ };
159
159
  // crossdomain - N/A - for Adobe products
160
160
  helmetHtmlOnly.crossOriginEmbedderPolicy = (headers, config) => {
161
- headers['Cross-Origin-Embedder-Policy'] = config.policy
162
- }
161
+ headers["Cross-Origin-Embedder-Policy"] = config.policy;
162
+ };
163
163
  helmetHtmlOnly.crossOriginOpenerPolicy = (headers, config) => {
164
- headers['Cross-Origin-Opener-Policy'] = config.policy
165
- }
164
+ headers["Cross-Origin-Opener-Policy"] = config.policy;
165
+ };
166
166
  helmetHtmlOnly.crossOriginResourcePolicy = (headers, config) => {
167
- headers['Cross-Origin-Resource-Policy'] = config.policy
168
- }
167
+ headers["Cross-Origin-Resource-Policy"] = config.policy;
168
+ };
169
169
 
170
170
  // DEPRECATED: expectCt
171
171
  // DEPRECATED: hpkp
172
172
 
173
173
  // https://www.permissionspolicy.com/
174
174
  helmetHtmlOnly.permissionsPolicy = (headers, config) => {
175
- headers['Permissions-Policy'] = Object.keys(config)
176
- .map(
177
- (policy) =>
178
- `${policy}=${config[policy] === '*' ? '*' : '(' + config[policy] + ')'}`
179
- )
180
- .join(', ')
181
- }
175
+ headers["Permissions-Policy"] = Object.keys(config)
176
+ .map(
177
+ (policy) =>
178
+ `${policy}=${config[policy] === "*" ? "*" : `(${config[policy]})`}`,
179
+ )
180
+ .join(", ");
181
+ };
182
182
 
183
183
  helmet.originAgentCluster = (headers, config) => {
184
- headers['Origin-Agent-Cluster'] = '?1'
185
- }
184
+ headers["Origin-Agent-Cluster"] = "?1";
185
+ };
186
186
 
187
187
  // https://github.com/helmetjs/referrer-policy
188
188
  helmet.referrerPolicy = (headers, config) => {
189
- headers['Referrer-Policy'] = config.policy
190
- }
189
+ headers["Referrer-Policy"] = config.policy;
190
+ };
191
191
 
192
192
  // DEPRECATED by reportingEndpoints
193
193
  helmetHtmlOnly.reportTo = (headers, config) => {
194
- headers['Report-To'] = Object.keys(config)
195
- .map((group) => {
196
- if (group === 'includeSubdomains' || group === 'maxAge') return ''
197
- const includeSubdomains =
198
- group === 'default'
199
- ? `, "include_subdomains": ${config.includeSubdomains}`
200
- : ''
201
- return config[group] && group !== 'includeSubdomains'
202
- ? `{ "group": "default", "max_age": ${config.maxAge}, "endpoints": [ { "url": "${config[group]}" } ]${includeSubdomains} }`
203
- : ''
204
- })
205
- .filter((str) => str)
206
- .join(', ')
207
- }
194
+ headers["Report-To"] = "";
195
+ const keys = Object.keys(config);
196
+ headers["Report-To"] = keys
197
+ .map((group) => {
198
+ if (group === "includeSubdomains" || group === "maxAge") return "";
199
+ const includeSubdomains =
200
+ group === "default"
201
+ ? `, "include_subdomains": ${config.includeSubdomains}`
202
+ : "";
203
+ return config[group] && group !== "includeSubdomains"
204
+ ? `{ "group": "default", "max_age": ${config.maxAge}, "endpoints": [ { "url": "${config[group]}" } ]${includeSubdomains} }`
205
+ : "";
206
+ })
207
+ .filter((str) => str)
208
+ .join(", ");
209
+ };
208
210
 
209
211
  helmet.reportingEndpoints = (headers, config) => {
210
- headers['Reporting-Endpoints'] = ''
211
- const keys = Object.keys(config)
212
- for (let i = 0, l = keys.length; i < l; i++) {
213
- if (i) headers['Reporting-Endpoints'] += ', '
214
- const key = keys[i]
215
- headers['Reporting-Endpoints'] += key + '="' + config[key] + '"'
216
- }
217
- }
212
+ headers["Reporting-Endpoints"] = "";
213
+ const keys = Object.keys(config);
214
+ for (let i = 0, l = keys.length; i < l; i++) {
215
+ if (i) headers["Reporting-Endpoints"] += ", ";
216
+ const key = keys[i];
217
+ headers["Reporting-Endpoints"] += `${key}="${config[key]}"`;
218
+ }
219
+ };
218
220
 
219
221
  // https://github.com/helmetjs/hsts
220
222
  helmet.strictTransportSecurity = (headers, config) => {
221
- let header = 'max-age=' + Math.round(config.maxAge)
222
- if (config.includeSubDomains) {
223
- header += '; includeSubDomains'
224
- }
225
- if (config.preload) {
226
- header += '; preload'
227
- }
228
- headers['Strict-Transport-Security'] = header
229
- }
223
+ let header = `max-age=${Math.round(config.maxAge)}`;
224
+ if (config.includeSubDomains) {
225
+ header += "; includeSubDomains";
226
+ }
227
+ if (config.preload) {
228
+ header += "; preload";
229
+ }
230
+ headers["Strict-Transport-Security"] = header;
231
+ };
230
232
 
231
233
  // noCache - N/A - separate middleware
232
234
 
233
235
  // X-* //
234
236
  // https://github.com/helmetjs/dont-sniff-mimetype
235
237
  helmet.contentTypeOptions = (headers, config) => {
236
- headers['X-Content-Type-Options'] = config.action
237
- }
238
+ headers["X-Content-Type-Options"] = config.action;
239
+ };
238
240
 
239
241
  // https://github.com/helmetjs/dns-Prefetch-control
240
242
  helmet.dnsPrefetchControl = (headers, config) => {
241
- headers['X-DNS-Prefetch-Control'] = config.allow ? 'on' : 'off'
242
- }
243
+ headers["X-DNS-Prefetch-Control"] = config.allow ? "on" : "off";
244
+ };
243
245
 
244
246
  // https://github.com/helmetjs/ienoopen
245
247
  helmet.downloadOptions = (headers, config) => {
246
- headers['X-Download-Options'] = config.action
247
- }
248
+ headers["X-Download-Options"] = config.action;
249
+ };
248
250
 
249
251
  // https://github.com/helmetjs/frameOptions
250
252
  helmetHtmlOnly.frameOptions = (headers, config) => {
251
- headers['X-Frame-Options'] = config.action.toUpperCase()
252
- }
253
+ headers["X-Frame-Options"] = config.action.toUpperCase();
254
+ };
253
255
 
254
256
  // https://github.com/helmetjs/crossdomain
255
257
  helmet.permittedCrossDomainPolicies = (headers, config) => {
256
- headers['X-Permitted-Cross-Domain-Policies'] = config.policy
257
- }
258
+ headers["X-Permitted-Cross-Domain-Policies"] = config.policy;
259
+ };
258
260
 
259
261
  // https://github.com/helmetjs/hide-powered-by
260
262
  helmet.poweredBy = (headers, config) => {
261
- if (config.server) {
262
- headers['X-Powered-By'] = config.server
263
- } else {
264
- delete headers.Server
265
- delete headers['X-Powered-By']
266
- }
267
- }
263
+ if (config.server) {
264
+ headers["X-Powered-By"] = config.server;
265
+ } else {
266
+ headers.Server = undefined;
267
+ headers["X-Powered-By"] = undefined;
268
+ }
269
+ };
268
270
 
269
271
  // https://github.com/helmetjs/x-xss-protection
270
272
  helmetHtmlOnly.xssProtection = (headers, config) => {
271
- let header = '1; mode=block'
272
- if (config.reportTo) {
273
- header += '; report=' + config.reportTo
274
- }
275
- headers['X-XSS-Protection'] = header
276
- }
273
+ let header = "1; mode=block";
274
+ if (config.reportTo) {
275
+ header += `; report=${config.reportTo}`;
276
+ }
277
+ headers["X-XSS-Protection"] = header;
278
+ };
277
279
 
278
280
  const httpSecurityHeadersMiddleware = (opts = {}) => {
279
- const options = { ...defaults, ...opts }
281
+ const options = { ...defaults, ...opts };
280
282
 
281
- const httpSecurityHeadersMiddlewareAfter = async (request) => {
282
- normalizeHttpResponse(request)
283
+ const httpSecurityHeadersMiddlewareAfter = async (request) => {
284
+ normalizeHttpResponse(request);
283
285
 
284
- Object.keys(helmet).forEach((key) => {
285
- if (!options[key]) return
286
- const config = { ...defaults[key], ...options[key] }
287
- helmet[key](request.response.headers, config)
288
- })
289
- const contentTypeHeader =
290
- request.response.headers['Content-Type'] ??
291
- request.response.headers['content-type']
292
- if (contentTypeHeader?.includes('text/html')) {
293
- Object.keys(helmetHtmlOnly).forEach((key) => {
294
- if (!options[key]) return
295
- const config = { ...defaults[key], ...options[key] }
296
- if (key === 'contentSecurityPolicy') {
297
- helmetHtmlOnly[key](options.contentSecurityPolicyReportOnly)(
298
- request.response.headers,
299
- config
300
- )
301
- } else {
302
- helmetHtmlOnly[key](request.response.headers, config)
303
- }
304
- })
305
- }
306
- }
307
- const httpSecurityHeadersMiddlewareOnError = async (request) => {
308
- if (request.response === undefined) return
309
- await httpSecurityHeadersMiddlewareAfter(request)
310
- }
311
- return {
312
- after: httpSecurityHeadersMiddlewareAfter,
313
- onError: httpSecurityHeadersMiddlewareOnError
314
- }
315
- }
316
- export default httpSecurityHeadersMiddleware
286
+ for (const key of Object.keys(helmet)) {
287
+ if (!options[key]) continue;
288
+ const config = { ...defaults[key], ...options[key] };
289
+ helmet[key](request.response.headers, config);
290
+ }
291
+ const contentTypeHeader =
292
+ request.response.headers["Content-Type"] ??
293
+ request.response.headers["content-type"];
294
+ if (contentTypeHeader?.includes("text/html")) {
295
+ for (const key of Object.keys(helmetHtmlOnly)) {
296
+ if (!options[key]) continue;
297
+ const config = { ...defaults[key], ...options[key] };
298
+ if (key === "contentSecurityPolicy") {
299
+ helmetHtmlOnly[key](options.contentSecurityPolicyReportOnly)(
300
+ request.response.headers,
301
+ config,
302
+ );
303
+ } else {
304
+ helmetHtmlOnly[key](request.response.headers, config);
305
+ }
306
+ }
307
+ }
308
+ };
309
+ const httpSecurityHeadersMiddlewareOnError = async (request) => {
310
+ if (request.response === undefined) return;
311
+ await httpSecurityHeadersMiddlewareAfter(request);
312
+ };
313
+ return {
314
+ after: httpSecurityHeadersMiddlewareAfter,
315
+ onError: httpSecurityHeadersMiddlewareOnError,
316
+ };
317
+ };
318
+ export default httpSecurityHeadersMiddleware;
package/package.json CHANGED
@@ -1,76 +1,73 @@
1
1
  {
2
- "name": "@middy/http-security-headers",
3
- "version": "6.1.6",
4
- "description": "Applies best practice security headers to responses. It's a simplified port of HelmetJS",
5
- "type": "module",
6
- "engines": {
7
- "node": ">=20"
8
- },
9
- "engineStrict": true,
10
- "publishConfig": {
11
- "access": "public"
12
- },
13
- "module": "./index.js",
14
- "exports": {
15
- ".": {
16
- "import": {
17
- "types": "./index.d.ts",
18
- "default": "./index.js"
19
- },
20
- "require": {
21
- "default": "./index.js"
22
- }
23
- }
24
- },
25
- "types": "index.d.ts",
26
- "files": [
27
- "index.js",
28
- "index.d.ts"
29
- ],
30
- "scripts": {
31
- "test": "npm run test:unit && npm run test:fuzz",
32
- "test:unit": "node --test __tests__/index.js",
33
- "test:fuzz": "node --test __tests__/fuzz.js",
34
- "test:benchmark": "node __benchmarks__/index.js"
35
- },
36
- "license": "MIT",
37
- "keywords": [
38
- "Lambda",
39
- "Middleware",
40
- "Serverless",
41
- "Framework",
42
- "AWS",
43
- "AWS Lambda",
44
- "Middy",
45
- "HTTP",
46
- "API",
47
- "Header",
48
- "Headers",
49
- "Helmet",
50
- "Security"
51
- ],
52
- "author": {
53
- "name": "Middy contributors",
54
- "url": "https://github.com/middyjs/middy/graphs/contributors"
55
- },
56
- "repository": {
57
- "type": "git",
58
- "url": "git+https://github.com/middyjs/middy.git",
59
- "directory": "packages/http-security-headers"
60
- },
61
- "bugs": {
62
- "url": "https://github.com/middyjs/middy/issues"
63
- },
64
- "homepage": "https://middy.js.org",
65
- "funding": {
66
- "type": "github",
67
- "url": "https://github.com/sponsors/willfarrell"
68
- },
69
- "gitHead": "7a6c0fbb8ab71d6a2171e678697de9f237568431",
70
- "dependencies": {
71
- "@middy/util": "6.1.6"
72
- },
73
- "devDependencies": {
74
- "@middy/core": "6.1.6"
75
- }
2
+ "name": "@middy/http-security-headers",
3
+ "version": "6.2.1",
4
+ "description": "Applies best practice security headers to responses. It's a simplified port of HelmetJS",
5
+ "type": "module",
6
+ "engines": {
7
+ "node": ">=20"
8
+ },
9
+ "engineStrict": true,
10
+ "publishConfig": {
11
+ "access": "public"
12
+ },
13
+ "module": "./index.js",
14
+ "exports": {
15
+ ".": {
16
+ "import": {
17
+ "types": "./index.d.ts",
18
+ "default": "./index.js"
19
+ },
20
+ "require": {
21
+ "default": "./index.js"
22
+ }
23
+ }
24
+ },
25
+ "types": "index.d.ts",
26
+ "files": ["index.js", "index.d.ts"],
27
+ "scripts": {
28
+ "test": "npm run test:unit && npm run test:fuzz",
29
+ "test:unit": "node --test",
30
+ "test:fuzz": "node --test index.fuzz.js",
31
+ "test:perf": "node --test index.perf.js"
32
+ },
33
+ "license": "MIT",
34
+ "keywords": [
35
+ "Lambda",
36
+ "Middleware",
37
+ "Serverless",
38
+ "Framework",
39
+ "AWS",
40
+ "AWS Lambda",
41
+ "Middy",
42
+ "HTTP",
43
+ "API",
44
+ "Header",
45
+ "Headers",
46
+ "Helmet",
47
+ "Security"
48
+ ],
49
+ "author": {
50
+ "name": "Middy contributors",
51
+ "url": "https://github.com/middyjs/middy/graphs/contributors"
52
+ },
53
+ "repository": {
54
+ "type": "git",
55
+ "url": "git+https://github.com/middyjs/middy.git",
56
+ "directory": "packages/http-security-headers"
57
+ },
58
+ "bugs": {
59
+ "url": "https://github.com/middyjs/middy/issues"
60
+ },
61
+ "homepage": "https://middy.js.org",
62
+ "funding": {
63
+ "type": "github",
64
+ "url": "https://github.com/sponsors/willfarrell"
65
+ },
66
+ "gitHead": "7a6c0fbb8ab71d6a2171e678697de9f237568431",
67
+ "dependencies": {
68
+ "@middy/util": "6.2.1"
69
+ },
70
+ "devDependencies": {
71
+ "@middy/core": "6.2.1"
72
+ }
76
73
  }