@middy/http-security-headers 7.1.1 → 7.1.3
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.
- package/README.md +17 -0
- package/index.d.ts +3 -9
- package/index.js +38 -57
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -31,6 +31,23 @@
|
|
|
31
31
|
<p>You can read the documentation at: <a href="https://middy.js.org/docs/middlewares/http-security-headers">https://middy.js.org/docs/middlewares/http-security-headers</a></p>
|
|
32
32
|
</div>
|
|
33
33
|
|
|
34
|
+
## Install
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
npm install --save @middy/http-security-headers
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
## Documentation and examples
|
|
42
|
+
|
|
43
|
+
For documentation and examples, refer to the main [Middy monorepo on GitHub](https://github.com/middyjs/middy) or [Middy official website](https://middy.js.org/docs/middlewares/http-security-headers).
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
## Contributing
|
|
47
|
+
|
|
48
|
+
Everyone is very welcome to contribute to this repository. Feel free to [raise issues](https://github.com/middyjs/middy/issues) or to [submit Pull Requests](https://github.com/middyjs/middy/pulls).
|
|
49
|
+
|
|
50
|
+
|
|
34
51
|
## License
|
|
35
52
|
|
|
36
53
|
Licensed under [MIT License](LICENSE). Copyright (c) 2017-2026 [will Farrell](https://github.com/willfarrell), [Luciano Mammino](https://github.com/lmammino), and [Middy contributors](https://github.com/middyjs/middy/graphs/contributors).
|
package/index.d.ts
CHANGED
|
@@ -9,11 +9,7 @@ export interface Options {
|
|
|
9
9
|
frameOptions?: {
|
|
10
10
|
action?: string;
|
|
11
11
|
};
|
|
12
|
-
poweredBy?:
|
|
13
|
-
| {
|
|
14
|
-
server: string;
|
|
15
|
-
}
|
|
16
|
-
| boolean;
|
|
12
|
+
poweredBy?: boolean;
|
|
17
13
|
strictTransportSecurity?: {
|
|
18
14
|
maxAge?: number;
|
|
19
15
|
includeSubDomains?: boolean;
|
|
@@ -29,9 +25,7 @@ export interface Options {
|
|
|
29
25
|
referrerPolicy?: {
|
|
30
26
|
policy?: string;
|
|
31
27
|
};
|
|
32
|
-
xssProtection?:
|
|
33
|
-
reportUri?: string;
|
|
34
|
-
};
|
|
28
|
+
xssProtection?: boolean;
|
|
35
29
|
contentSecurityPolicy?: Record<string, string>;
|
|
36
30
|
contentSecurityPolicyReportOnly?: boolean;
|
|
37
31
|
crossOriginEmbedderPolicy?: {
|
|
@@ -62,6 +56,6 @@ type WithBoolValues<T> = { [K in keyof T]: T[K] | boolean };
|
|
|
62
56
|
|
|
63
57
|
declare function httpSecurityHeaders(
|
|
64
58
|
options?: WithBoolValues<Options>,
|
|
65
|
-
): middy.MiddlewareObj
|
|
59
|
+
): middy.MiddlewareObj<unknown, unknown, Error>;
|
|
66
60
|
|
|
67
61
|
export default httpSecurityHeaders;
|
package/index.js
CHANGED
|
@@ -128,11 +128,10 @@ const defaults = {
|
|
|
128
128
|
};
|
|
129
129
|
|
|
130
130
|
const helmet = {};
|
|
131
|
-
const helmetHtmlOnly = {};
|
|
132
131
|
|
|
133
132
|
// *** https://github.com/helmetjs/helmet/tree/main/middlewares *** //
|
|
134
133
|
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy
|
|
135
|
-
|
|
134
|
+
helmet.contentSecurityPolicy = (reportOnly) => (headers, config) => {
|
|
136
135
|
let header = Object.keys(config)
|
|
137
136
|
.map((policy) => (config[policy] ? `${policy} ${config[policy]}` : ""))
|
|
138
137
|
.filter((str) => str)
|
|
@@ -150,13 +149,13 @@ helmetHtmlOnly.contentSecurityPolicy = (reportOnly) => (headers, config) => {
|
|
|
150
149
|
headers[cspHeaderName] = header;
|
|
151
150
|
};
|
|
152
151
|
// crossdomain - N/A - for Adobe products
|
|
153
|
-
|
|
152
|
+
helmet.crossOriginEmbedderPolicy = (headers, config) => {
|
|
154
153
|
headers["Cross-Origin-Embedder-Policy"] = config.policy;
|
|
155
154
|
};
|
|
156
|
-
|
|
155
|
+
helmet.crossOriginOpenerPolicy = (headers, config) => {
|
|
157
156
|
headers["Cross-Origin-Opener-Policy"] = config.policy;
|
|
158
157
|
};
|
|
159
|
-
|
|
158
|
+
helmet.crossOriginResourcePolicy = (headers, config) => {
|
|
160
159
|
headers["Cross-Origin-Resource-Policy"] = config.policy;
|
|
161
160
|
};
|
|
162
161
|
|
|
@@ -164,7 +163,7 @@ helmetHtmlOnly.crossOriginResourcePolicy = (headers, config) => {
|
|
|
164
163
|
// DEPRECATED: hpkp
|
|
165
164
|
|
|
166
165
|
// https://www.permissionspolicy.com/
|
|
167
|
-
|
|
166
|
+
helmet.permissionsPolicy = (headers, config) => {
|
|
168
167
|
headers["Permissions-Policy"] = Object.keys(config)
|
|
169
168
|
.map(
|
|
170
169
|
(policy) =>
|
|
@@ -173,7 +172,7 @@ helmetHtmlOnly.permissionsPolicy = (headers, config) => {
|
|
|
173
172
|
.join(", ");
|
|
174
173
|
};
|
|
175
174
|
|
|
176
|
-
helmet.originAgentCluster = (headers
|
|
175
|
+
helmet.originAgentCluster = (headers) => {
|
|
177
176
|
headers["Origin-Agent-Cluster"] = "?1";
|
|
178
177
|
};
|
|
179
178
|
|
|
@@ -183,8 +182,7 @@ helmet.referrerPolicy = (headers, config) => {
|
|
|
183
182
|
};
|
|
184
183
|
|
|
185
184
|
// DEPRECATED by reportingEndpoints
|
|
186
|
-
|
|
187
|
-
headers["Report-To"] = "";
|
|
185
|
+
helmet.reportTo = (headers, config) => {
|
|
188
186
|
const keys = Object.keys(config);
|
|
189
187
|
headers["Report-To"] = keys
|
|
190
188
|
.map((group) => {
|
|
@@ -202,13 +200,10 @@ helmetHtmlOnly.reportTo = (headers, config) => {
|
|
|
202
200
|
};
|
|
203
201
|
|
|
204
202
|
helmet.reportingEndpoints = (headers, config) => {
|
|
205
|
-
headers["Reporting-Endpoints"] = "";
|
|
206
203
|
const keys = Object.keys(config);
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
headers["Reporting-Endpoints"] += `${key}="${config[key]}"`;
|
|
211
|
-
}
|
|
204
|
+
headers["Reporting-Endpoints"] = keys
|
|
205
|
+
.map((key) => `${key}="${config[key]}"`)
|
|
206
|
+
.join(", ");
|
|
212
207
|
};
|
|
213
208
|
|
|
214
209
|
// https://github.com/helmetjs/hsts
|
|
@@ -242,7 +237,7 @@ helmet.downloadOptions = (headers, config) => {
|
|
|
242
237
|
};
|
|
243
238
|
|
|
244
239
|
// https://github.com/helmetjs/frameOptions
|
|
245
|
-
|
|
240
|
+
helmet.frameOptions = (headers, config) => {
|
|
246
241
|
headers["X-Frame-Options"] = config.action.toUpperCase();
|
|
247
242
|
};
|
|
248
243
|
|
|
@@ -252,57 +247,43 @@ helmet.permittedCrossDomainPolicies = (headers, config) => {
|
|
|
252
247
|
};
|
|
253
248
|
|
|
254
249
|
// https://github.com/helmetjs/hide-powered-by
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
delete headers["X-Powered-By"];
|
|
258
|
-
};
|
|
250
|
+
// Removal handled in after hook via delete to avoid undefined cleanup loop
|
|
251
|
+
helmet.poweredBy = () => {};
|
|
259
252
|
|
|
260
253
|
// https://github.com/helmetjs/x-xss-protection
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
headers["X-XSS-Protection"] = header;
|
|
254
|
+
helmet.xssProtection = (headers, config) => {
|
|
255
|
+
headers["X-XSS-Protection"] = "0";
|
|
264
256
|
};
|
|
265
257
|
|
|
266
258
|
const httpSecurityHeadersMiddleware = (opts = {}) => {
|
|
267
259
|
const options = { ...defaults, ...opts };
|
|
268
260
|
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
helmet[key](
|
|
261
|
+
// Pre-compute all static header values once at initialization
|
|
262
|
+
const precomputedHeaders = {};
|
|
263
|
+
for (const key of Object.keys(helmet)) {
|
|
264
|
+
if (!options[key]) continue;
|
|
265
|
+
const config = { ...defaults[key], ...options[key] };
|
|
266
|
+
if (key === "contentSecurityPolicy") {
|
|
267
|
+
helmet[key](options.contentSecurityPolicyReportOnly)(
|
|
268
|
+
precomputedHeaders,
|
|
269
|
+
config,
|
|
270
|
+
);
|
|
271
|
+
} else {
|
|
272
|
+
helmet[key](precomputedHeaders, config);
|
|
276
273
|
}
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
helmetHtmlOnly[key](options.contentSecurityPolicyReportOnly)(
|
|
286
|
-
request.response.headers,
|
|
287
|
-
config,
|
|
288
|
-
);
|
|
289
|
-
} else {
|
|
290
|
-
helmetHtmlOnly[key](request.response.headers, config);
|
|
291
|
-
}
|
|
292
|
-
}
|
|
293
|
-
}
|
|
294
|
-
// Clean up headers removals
|
|
295
|
-
const headers = {};
|
|
296
|
-
for (const key of Object.keys(request.response.headers)) {
|
|
297
|
-
if (typeof request.response.headers[key] !== "undefined") {
|
|
298
|
-
headers[key] = request.response.headers[key];
|
|
299
|
-
}
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
const httpSecurityHeadersMiddlewareAfter = (request) => {
|
|
277
|
+
normalizeHttpResponse(request);
|
|
278
|
+
Object.assign(request.response.headers, precomputedHeaders);
|
|
279
|
+
if (options.poweredBy) {
|
|
280
|
+
delete request.response.headers.Server;
|
|
281
|
+
delete request.response.headers["X-Powered-By"];
|
|
300
282
|
}
|
|
301
|
-
request.response.headers = headers;
|
|
302
283
|
};
|
|
303
|
-
const httpSecurityHeadersMiddlewareOnError =
|
|
304
|
-
if (request.response === undefined) return;
|
|
305
|
-
|
|
284
|
+
const httpSecurityHeadersMiddlewareOnError = (request) => {
|
|
285
|
+
if (typeof request.response === "undefined") return;
|
|
286
|
+
httpSecurityHeadersMiddlewareAfter(request);
|
|
306
287
|
};
|
|
307
288
|
return {
|
|
308
289
|
after: httpSecurityHeadersMiddlewareAfter,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@middy/http-security-headers",
|
|
3
|
-
"version": "7.1.
|
|
3
|
+
"version": "7.1.3",
|
|
4
4
|
"description": "Applies best practice security headers to responses. It's a simplified port of HelmetJS",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
@@ -67,12 +67,12 @@
|
|
|
67
67
|
"type": "github",
|
|
68
68
|
"url": "https://github.com/sponsors/willfarrell"
|
|
69
69
|
},
|
|
70
|
-
"gitHead": "7a6c0fbb8ab71d6a2171e678697de9f237568431",
|
|
71
70
|
"dependencies": {
|
|
72
|
-
"@middy/util": "7.1.
|
|
71
|
+
"@middy/util": "7.1.3"
|
|
73
72
|
},
|
|
74
73
|
"devDependencies": {
|
|
75
|
-
"@middy/core": "7.1.
|
|
76
|
-
"@types/aws-lambda": "^8.0.0"
|
|
74
|
+
"@middy/core": "7.1.3",
|
|
75
|
+
"@types/aws-lambda": "^8.0.0",
|
|
76
|
+
"@types/node": "^22.0.0"
|
|
77
77
|
}
|
|
78
78
|
}
|