Comparing version 4.3.1 to 4.4.0
# Changelog | ||
## 4.4.0 - 2021-01-17 | ||
### Added | ||
- `helmet.originAgentCluster`: a new middleware for the `Origin-Agent-Cluster` middleware, disabled by default | ||
## 4.3.1 - 2020-12-27 | ||
@@ -4,0 +10,0 @@ |
/// <reference types="node" /> | ||
import { IncomingMessage, ServerResponse } from "http"; | ||
import contentSecurityPolicy, { ContentSecurityPolicyOptions } from "./middlewares/content-security-policy"; | ||
import expectCt, { ExpectCtOptions } from "./middlewares/expect-ct"; | ||
import referrerPolicy, { ReferrerPolicyOptions } from "./middlewares/referrer-policy"; | ||
import strictTransportSecurity, { StrictTransportSecurityOptions } from "./middlewares/strict-transport-security"; | ||
import xContentTypeOptions from "./middlewares/x-content-type-options"; | ||
import xDnsPrefetchControl, { XDnsPrefetchControlOptions } from "./middlewares/x-dns-prefetch-control"; | ||
import xDownloadOptions from "./middlewares/x-download-options"; | ||
import xFrameOptions, { XFrameOptionsOptions } from "./middlewares/x-frame-options"; | ||
import xPermittedCrossDomainPolicies, { XPermittedCrossDomainPoliciesOptions } from "./middlewares/x-permitted-cross-domain-policies"; | ||
import xPoweredBy from "./middlewares/x-powered-by"; | ||
import xXssProtection from "./middlewares/x-xss-protection"; | ||
import { IncomingMessage, ServerResponse } from "http" | ||
import contentSecurityPolicy, { ContentSecurityPolicyOptions } from "./middlewares/content-security-policy" | ||
import expectCt, { ExpectCtOptions } from "./middlewares/expect-ct" | ||
import originAgentCluster from "./middlewares/origin-agent-cluster" | ||
import referrerPolicy, { ReferrerPolicyOptions } from "./middlewares/referrer-policy" | ||
import strictTransportSecurity, { StrictTransportSecurityOptions } from "./middlewares/strict-transport-security" | ||
import xContentTypeOptions from "./middlewares/x-content-type-options" | ||
import xDnsPrefetchControl, { XDnsPrefetchControlOptions } from "./middlewares/x-dns-prefetch-control" | ||
import xDownloadOptions from "./middlewares/x-download-options" | ||
import xFrameOptions, { XFrameOptionsOptions } from "./middlewares/x-frame-options" | ||
import xPermittedCrossDomainPolicies, { XPermittedCrossDomainPoliciesOptions } from "./middlewares/x-permitted-cross-domain-policies" | ||
import xPoweredBy from "./middlewares/x-powered-by" | ||
import xXssProtection from "./middlewares/x-xss-protection" | ||
interface HelmetOptions { | ||
contentSecurityPolicy?: MiddlewareOption<ContentSecurityPolicyOptions>; | ||
dnsPrefetchControl?: MiddlewareOption<XDnsPrefetchControlOptions>; | ||
expectCt?: MiddlewareOption<ExpectCtOptions>; | ||
frameguard?: MiddlewareOption<XFrameOptionsOptions>; | ||
hidePoweredBy?: MiddlewareOption<never>; | ||
hsts?: MiddlewareOption<StrictTransportSecurityOptions>; | ||
ieNoOpen?: MiddlewareOption<never>; | ||
noSniff?: MiddlewareOption<never>; | ||
permittedCrossDomainPolicies?: MiddlewareOption<XPermittedCrossDomainPoliciesOptions>; | ||
referrerPolicy?: MiddlewareOption<ReferrerPolicyOptions>; | ||
xssFilter?: MiddlewareOption<never>; | ||
contentSecurityPolicy?: MiddlewareOption<ContentSecurityPolicyOptions> | ||
dnsPrefetchControl?: MiddlewareOption<XDnsPrefetchControlOptions> | ||
expectCt?: MiddlewareOption<ExpectCtOptions> | ||
frameguard?: MiddlewareOption<XFrameOptionsOptions> | ||
hidePoweredBy?: MiddlewareOption<never> | ||
hsts?: MiddlewareOption<StrictTransportSecurityOptions> | ||
ieNoOpen?: MiddlewareOption<never> | ||
noSniff?: MiddlewareOption<never> | ||
originAgentCluster?: boolean | ||
permittedCrossDomainPolicies?: MiddlewareOption<XPermittedCrossDomainPoliciesOptions> | ||
referrerPolicy?: MiddlewareOption<ReferrerPolicyOptions> | ||
xssFilter?: MiddlewareOption<never> | ||
} | ||
declare type MiddlewareOption<T> = false | T; | ||
declare type MiddlewareOption<T> = false | T | ||
interface Helmet { | ||
(options?: Readonly<HelmetOptions>): (req: IncomingMessage, res: ServerResponse, next: (err?: unknown) => void) => void; | ||
contentSecurityPolicy: typeof contentSecurityPolicy; | ||
dnsPrefetchControl: typeof xDnsPrefetchControl; | ||
expectCt: typeof expectCt; | ||
frameguard: typeof xFrameOptions; | ||
hidePoweredBy: typeof xPoweredBy; | ||
hsts: typeof strictTransportSecurity; | ||
ieNoOpen: typeof xDownloadOptions; | ||
noSniff: typeof xContentTypeOptions; | ||
permittedCrossDomainPolicies: typeof xPermittedCrossDomainPolicies; | ||
referrerPolicy: typeof referrerPolicy; | ||
xssFilter: typeof xXssProtection; | ||
featurePolicy: () => never; | ||
hpkp: () => never; | ||
noCache: () => never; | ||
(options?: Readonly<HelmetOptions>): (req: IncomingMessage, res: ServerResponse, next: (err?: unknown) => void) => void | ||
contentSecurityPolicy: typeof contentSecurityPolicy | ||
dnsPrefetchControl: typeof xDnsPrefetchControl | ||
expectCt: typeof expectCt | ||
frameguard: typeof xFrameOptions | ||
hidePoweredBy: typeof xPoweredBy | ||
hsts: typeof strictTransportSecurity | ||
ieNoOpen: typeof xDownloadOptions | ||
noSniff: typeof xContentTypeOptions | ||
permittedCrossDomainPolicies: typeof xPermittedCrossDomainPolicies | ||
referrerPolicy: typeof referrerPolicy | ||
xssFilter: typeof xXssProtection | ||
originAgentCluster: typeof originAgentCluster | ||
featurePolicy: () => never | ||
hpkp: () => never | ||
noCache: () => never | ||
} | ||
declare const helmet: Helmet; | ||
export = helmet; | ||
declare const helmet: Helmet | ||
export = helmet |
@@ -1,109 +0,118 @@ | ||
"use strict"; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
const content_security_policy_1 = __importDefault(require("./middlewares/content-security-policy")); | ||
const expect_ct_1 = __importDefault(require("./middlewares/expect-ct")); | ||
const referrer_policy_1 = __importDefault(require("./middlewares/referrer-policy")); | ||
const strict_transport_security_1 = __importDefault(require("./middlewares/strict-transport-security")); | ||
const x_content_type_options_1 = __importDefault(require("./middlewares/x-content-type-options")); | ||
const x_dns_prefetch_control_1 = __importDefault(require("./middlewares/x-dns-prefetch-control")); | ||
const x_download_options_1 = __importDefault(require("./middlewares/x-download-options")); | ||
const x_frame_options_1 = __importDefault(require("./middlewares/x-frame-options")); | ||
const x_permitted_cross_domain_policies_1 = __importDefault(require("./middlewares/x-permitted-cross-domain-policies")); | ||
const x_powered_by_1 = __importDefault(require("./middlewares/x-powered-by")); | ||
const x_xss_protection_1 = __importDefault(require("./middlewares/x-xss-protection")); | ||
const helmet = Object.assign(function helmet(options = {}) { | ||
var _a; | ||
if (((_a = options.constructor) === null || _a === void 0 ? void 0 : _a.name) === "IncomingMessage") { | ||
throw new Error("It appears you have done something like `app.use(helmet)`, but it should be `app.use(helmet())`."); | ||
} | ||
if (Object.values(options).some((option) => option === true)) { | ||
throw new Error("Helmet no longer supports `true` as a middleware option. Remove the property from your options to fix this error."); | ||
} | ||
const middlewareFunctions = []; | ||
if (options.contentSecurityPolicy !== false) { | ||
middlewareFunctions.push(content_security_policy_1.default(options.contentSecurityPolicy)); | ||
} | ||
if (options.dnsPrefetchControl !== false) { | ||
middlewareFunctions.push(x_dns_prefetch_control_1.default(options.dnsPrefetchControl)); | ||
} | ||
if (options.expectCt !== false) { | ||
middlewareFunctions.push(expect_ct_1.default(options.expectCt)); | ||
} | ||
if (options.frameguard !== false) { | ||
middlewareFunctions.push(x_frame_options_1.default(options.frameguard)); | ||
} | ||
if (options.hidePoweredBy !== false) { | ||
if (options.hidePoweredBy !== undefined) { | ||
console.warn("hidePoweredBy does not take options. Remove the property to silence this warning."); | ||
} | ||
middlewareFunctions.push(x_powered_by_1.default()); | ||
} | ||
if (options.hsts !== false) { | ||
middlewareFunctions.push(strict_transport_security_1.default(options.hsts)); | ||
} | ||
if (options.ieNoOpen !== false) { | ||
if (options.ieNoOpen !== undefined) { | ||
console.warn("ieNoOpen does not take options. Remove the property to silence this warning."); | ||
} | ||
middlewareFunctions.push(x_download_options_1.default()); | ||
} | ||
if (options.noSniff !== false) { | ||
if (options.noSniff !== undefined) { | ||
console.warn("noSniff does not take options. Remove the property to silence this warning."); | ||
} | ||
middlewareFunctions.push(x_content_type_options_1.default()); | ||
} | ||
if (options.permittedCrossDomainPolicies !== false) { | ||
middlewareFunctions.push(x_permitted_cross_domain_policies_1.default(options.permittedCrossDomainPolicies)); | ||
} | ||
if (options.referrerPolicy !== false) { | ||
middlewareFunctions.push(referrer_policy_1.default(options.referrerPolicy)); | ||
} | ||
if (options.xssFilter !== false) { | ||
if (options.xssFilter !== undefined) { | ||
console.warn("xssFilter does not take options. Remove the property to silence this warning."); | ||
} | ||
middlewareFunctions.push(x_xss_protection_1.default()); | ||
} | ||
return function helmetMiddleware(req, res, next) { | ||
const iterator = middlewareFunctions[Symbol.iterator](); | ||
(function internalNext(err) { | ||
if (err) { | ||
next(err); | ||
return; | ||
} | ||
const iteration = iterator.next(); | ||
if (iteration.done) { | ||
next(); | ||
} | ||
else { | ||
const middlewareFunction = iteration.value; | ||
middlewareFunction(req, res, internalNext); | ||
} | ||
})(); | ||
}; | ||
}, { | ||
contentSecurityPolicy: content_security_policy_1.default, | ||
dnsPrefetchControl: x_dns_prefetch_control_1.default, | ||
expectCt: expect_ct_1.default, | ||
frameguard: x_frame_options_1.default, | ||
hidePoweredBy: x_powered_by_1.default, | ||
hsts: strict_transport_security_1.default, | ||
ieNoOpen: x_download_options_1.default, | ||
noSniff: x_content_type_options_1.default, | ||
permittedCrossDomainPolicies: x_permitted_cross_domain_policies_1.default, | ||
referrerPolicy: referrer_policy_1.default, | ||
xssFilter: x_xss_protection_1.default, | ||
featurePolicy() { | ||
throw new Error("helmet.featurePolicy was removed because the Feature-Policy header is deprecated. If you still need this header, you can use the `feature-policy` module."); | ||
}, | ||
hpkp() { | ||
throw new Error("helmet.hpkp was removed because the header has been deprecated. If you still need this header, you can use the `hpkp` module. For more, see <https://github.com/helmetjs/helmet/issues/180>."); | ||
}, | ||
noCache() { | ||
throw new Error("helmet.noCache was removed. You can use the `nocache` module instead. For more, see <https://github.com/helmetjs/helmet/issues/215>."); | ||
}, | ||
}); | ||
module.exports = helmet; | ||
"use strict" | ||
var __importDefault = | ||
(this && this.__importDefault) || | ||
function (mod) { | ||
return mod && mod.__esModule ? mod : { default: mod } | ||
} | ||
const content_security_policy_1 = __importDefault(require("./middlewares/content-security-policy")) | ||
const expect_ct_1 = __importDefault(require("./middlewares/expect-ct")) | ||
const origin_agent_cluster_1 = __importDefault(require("./middlewares/origin-agent-cluster")) | ||
const referrer_policy_1 = __importDefault(require("./middlewares/referrer-policy")) | ||
const strict_transport_security_1 = __importDefault(require("./middlewares/strict-transport-security")) | ||
const x_content_type_options_1 = __importDefault(require("./middlewares/x-content-type-options")) | ||
const x_dns_prefetch_control_1 = __importDefault(require("./middlewares/x-dns-prefetch-control")) | ||
const x_download_options_1 = __importDefault(require("./middlewares/x-download-options")) | ||
const x_frame_options_1 = __importDefault(require("./middlewares/x-frame-options")) | ||
const x_permitted_cross_domain_policies_1 = __importDefault(require("./middlewares/x-permitted-cross-domain-policies")) | ||
const x_powered_by_1 = __importDefault(require("./middlewares/x-powered-by")) | ||
const x_xss_protection_1 = __importDefault(require("./middlewares/x-xss-protection")) | ||
const helmet = Object.assign( | ||
function helmet(options = {}) { | ||
var _a | ||
if (((_a = options.constructor) === null || _a === void 0 ? void 0 : _a.name) === "IncomingMessage") { | ||
throw new Error("It appears you have done something like `app.use(helmet)`, but it should be `app.use(helmet())`.") | ||
} | ||
if (Object.entries(options).some(([key, option]) => option === true && key !== "originAgentCluster")) { | ||
throw new Error("Helmet no longer supports `true` as a middleware option, except for Origin-Agent-Cluster. Remove the property from your options to fix this error.") | ||
} | ||
const middlewareFunctions = [] | ||
if (options.contentSecurityPolicy !== false) { | ||
middlewareFunctions.push(content_security_policy_1.default(options.contentSecurityPolicy)) | ||
} | ||
if (options.dnsPrefetchControl !== false) { | ||
middlewareFunctions.push(x_dns_prefetch_control_1.default(options.dnsPrefetchControl)) | ||
} | ||
if (options.expectCt !== false) { | ||
middlewareFunctions.push(expect_ct_1.default(options.expectCt)) | ||
} | ||
if (options.frameguard !== false) { | ||
middlewareFunctions.push(x_frame_options_1.default(options.frameguard)) | ||
} | ||
if (options.hidePoweredBy !== false) { | ||
if (options.hidePoweredBy !== undefined) { | ||
console.warn("hidePoweredBy does not take options. Remove the property to silence this warning.") | ||
} | ||
middlewareFunctions.push(x_powered_by_1.default()) | ||
} | ||
if (options.hsts !== false) { | ||
middlewareFunctions.push(strict_transport_security_1.default(options.hsts)) | ||
} | ||
if (options.ieNoOpen !== false) { | ||
if (options.ieNoOpen !== undefined) { | ||
console.warn("ieNoOpen does not take options. Remove the property to silence this warning.") | ||
} | ||
middlewareFunctions.push(x_download_options_1.default()) | ||
} | ||
if (options.noSniff !== false) { | ||
if (options.noSniff !== undefined) { | ||
console.warn("noSniff does not take options. Remove the property to silence this warning.") | ||
} | ||
middlewareFunctions.push(x_content_type_options_1.default()) | ||
} | ||
if (options.originAgentCluster !== undefined && options.originAgentCluster !== false) { | ||
middlewareFunctions.push(origin_agent_cluster_1.default()) | ||
} | ||
if (options.permittedCrossDomainPolicies !== false) { | ||
middlewareFunctions.push(x_permitted_cross_domain_policies_1.default(options.permittedCrossDomainPolicies)) | ||
} | ||
if (options.referrerPolicy !== false) { | ||
middlewareFunctions.push(referrer_policy_1.default(options.referrerPolicy)) | ||
} | ||
if (options.xssFilter !== false) { | ||
if (options.xssFilter !== undefined) { | ||
console.warn("xssFilter does not take options. Remove the property to silence this warning.") | ||
} | ||
middlewareFunctions.push(x_xss_protection_1.default()) | ||
} | ||
return function helmetMiddleware(req, res, next) { | ||
const iterator = middlewareFunctions[Symbol.iterator]() | ||
;(function internalNext(err) { | ||
if (err) { | ||
next(err) | ||
return | ||
} | ||
const iteration = iterator.next() | ||
if (iteration.done) { | ||
next() | ||
} else { | ||
const middlewareFunction = iteration.value | ||
middlewareFunction(req, res, internalNext) | ||
} | ||
})() | ||
} | ||
}, | ||
{ | ||
contentSecurityPolicy: content_security_policy_1.default, | ||
dnsPrefetchControl: x_dns_prefetch_control_1.default, | ||
expectCt: expect_ct_1.default, | ||
frameguard: x_frame_options_1.default, | ||
hidePoweredBy: x_powered_by_1.default, | ||
hsts: strict_transport_security_1.default, | ||
ieNoOpen: x_download_options_1.default, | ||
noSniff: x_content_type_options_1.default, | ||
originAgentCluster: origin_agent_cluster_1.default, | ||
permittedCrossDomainPolicies: x_permitted_cross_domain_policies_1.default, | ||
referrerPolicy: referrer_policy_1.default, | ||
xssFilter: x_xss_protection_1.default, | ||
featurePolicy() { | ||
throw new Error("helmet.featurePolicy was removed because the Feature-Policy header is deprecated. If you still need this header, you can use the `feature-policy` module.") | ||
}, | ||
hpkp() { | ||
throw new Error("helmet.hpkp was removed because the header has been deprecated. If you still need this header, you can use the `hpkp` module. For more, see <https://github.com/helmetjs/helmet/issues/180>.") | ||
}, | ||
noCache() { | ||
throw new Error("helmet.noCache was removed. You can use the `nocache` module instead. For more, see <https://github.com/helmetjs/helmet/issues/215>.") | ||
} | ||
} | ||
) | ||
module.exports = helmet |
/// <reference types="node" /> | ||
import { IncomingMessage, ServerResponse } from "http"; | ||
import { IncomingMessage, ServerResponse } from "http" | ||
interface ContentSecurityPolicyDirectiveValueFunction { | ||
(req: IncomingMessage, res: ServerResponse): string; | ||
(req: IncomingMessage, res: ServerResponse): string | ||
} | ||
declare type ContentSecurityPolicyDirectiveValue = string | ContentSecurityPolicyDirectiveValueFunction; | ||
declare type ContentSecurityPolicyDirectiveValue = string | ContentSecurityPolicyDirectiveValueFunction | ||
export interface ContentSecurityPolicyOptions { | ||
directives?: Record<string, Iterable<ContentSecurityPolicyDirectiveValue> | typeof dangerouslyDisableDefaultSrc>; | ||
reportOnly?: boolean; | ||
directives?: Record<string, Iterable<ContentSecurityPolicyDirectiveValue> | typeof dangerouslyDisableDefaultSrc> | ||
reportOnly?: boolean | ||
} | ||
interface ContentSecurityPolicy { | ||
(options?: Readonly<ContentSecurityPolicyOptions>): (req: IncomingMessage, res: ServerResponse, next: (err?: Error) => void) => void; | ||
getDefaultDirectives: typeof getDefaultDirectives; | ||
dangerouslyDisableDefaultSrc: typeof dangerouslyDisableDefaultSrc; | ||
(options?: Readonly<ContentSecurityPolicyOptions>): (req: IncomingMessage, res: ServerResponse, next: (err?: Error) => void) => void | ||
getDefaultDirectives: typeof getDefaultDirectives | ||
dangerouslyDisableDefaultSrc: typeof dangerouslyDisableDefaultSrc | ||
} | ||
declare const dangerouslyDisableDefaultSrc: unique symbol; | ||
declare const dangerouslyDisableDefaultSrc: unique symbol | ||
declare const getDefaultDirectives: () => { | ||
[x: string]: Iterable<ContentSecurityPolicyDirectiveValue>; | ||
}; | ||
declare const contentSecurityPolicy: ContentSecurityPolicy; | ||
export default contentSecurityPolicy; | ||
export { getDefaultDirectives, dangerouslyDisableDefaultSrc }; | ||
[x: string]: Iterable<ContentSecurityPolicyDirectiveValue> | ||
} | ||
declare const contentSecurityPolicy: ContentSecurityPolicy | ||
export default contentSecurityPolicy | ||
export { getDefaultDirectives, dangerouslyDisableDefaultSrc } |
@@ -1,129 +0,118 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.dangerouslyDisableDefaultSrc = exports.getDefaultDirectives = void 0; | ||
const dangerouslyDisableDefaultSrc = Symbol("dangerouslyDisableDefaultSrc"); | ||
exports.dangerouslyDisableDefaultSrc = dangerouslyDisableDefaultSrc; | ||
"use strict" | ||
Object.defineProperty(exports, "__esModule", { value: true }) | ||
exports.dangerouslyDisableDefaultSrc = exports.getDefaultDirectives = void 0 | ||
const dangerouslyDisableDefaultSrc = Symbol("dangerouslyDisableDefaultSrc") | ||
exports.dangerouslyDisableDefaultSrc = dangerouslyDisableDefaultSrc | ||
const DEFAULT_DIRECTIVES = { | ||
"default-src": ["'self'"], | ||
"base-uri": ["'self'"], | ||
"block-all-mixed-content": [], | ||
"font-src": ["'self'", "https:", "data:"], | ||
"frame-ancestors": ["'self'"], | ||
"img-src": ["'self'", "data:"], | ||
"object-src": ["'none'"], | ||
"script-src": ["'self'"], | ||
"script-src-attr": ["'none'"], | ||
"style-src": ["'self'", "https:", "'unsafe-inline'"], | ||
"upgrade-insecure-requests": [], | ||
}; | ||
const getDefaultDirectives = () => (Object.assign({}, DEFAULT_DIRECTIVES)); | ||
exports.getDefaultDirectives = getDefaultDirectives; | ||
const dashify = (str) => str.replace(/[A-Z]/g, (capitalLetter) => "-" + capitalLetter.toLowerCase()); | ||
const isDirectiveValueInvalid = (directiveValue) => /;|,/.test(directiveValue); | ||
const has = (obj, key) => Object.prototype.hasOwnProperty.call(obj, key); | ||
"default-src": ["'self'"], | ||
"base-uri": ["'self'"], | ||
"block-all-mixed-content": [], | ||
"font-src": ["'self'", "https:", "data:"], | ||
"frame-ancestors": ["'self'"], | ||
"img-src": ["'self'", "data:"], | ||
"object-src": ["'none'"], | ||
"script-src": ["'self'"], | ||
"script-src-attr": ["'none'"], | ||
"style-src": ["'self'", "https:", "'unsafe-inline'"], | ||
"upgrade-insecure-requests": [] | ||
} | ||
const getDefaultDirectives = () => Object.assign({}, DEFAULT_DIRECTIVES) | ||
exports.getDefaultDirectives = getDefaultDirectives | ||
const dashify = str => str.replace(/[A-Z]/g, capitalLetter => "-" + capitalLetter.toLowerCase()) | ||
const isDirectiveValueInvalid = directiveValue => /;|,/.test(directiveValue) | ||
const has = (obj, key) => Object.prototype.hasOwnProperty.call(obj, key) | ||
function normalizeDirectives(options) { | ||
const { directives: rawDirectives = getDefaultDirectives() } = options; | ||
const result = []; | ||
const directiveNamesSeen = new Set(); | ||
for (const rawDirectiveName in rawDirectives) { | ||
if (!has(rawDirectives, rawDirectiveName)) { | ||
continue; | ||
} | ||
if (rawDirectiveName.length === 0 || | ||
/[^a-zA-Z0-9-]/.test(rawDirectiveName)) { | ||
throw new Error(`Content-Security-Policy received an invalid directive name ${JSON.stringify(rawDirectiveName)}`); | ||
} | ||
const directiveName = dashify(rawDirectiveName); | ||
if (directiveNamesSeen.has(directiveName)) { | ||
throw new Error(`Content-Security-Policy received a duplicate directive ${JSON.stringify(directiveName)}`); | ||
} | ||
directiveNamesSeen.add(directiveName); | ||
const rawDirectiveValue = rawDirectives[rawDirectiveName]; | ||
let directiveValue; | ||
if (typeof rawDirectiveValue === "string") { | ||
directiveValue = [rawDirectiveValue]; | ||
} | ||
else if (!rawDirectiveValue) { | ||
throw new Error(`Content-Security-Policy received an invalid directive value for ${JSON.stringify(directiveName)}`); | ||
} | ||
else if (rawDirectiveValue === dangerouslyDisableDefaultSrc) { | ||
if (directiveName === "default-src") { | ||
continue; | ||
} | ||
else { | ||
throw new Error(`Content-Security-Policy: tried to disable ${JSON.stringify(directiveName)} as if it were default-src; simply omit the key`); | ||
} | ||
} | ||
else { | ||
directiveValue = rawDirectiveValue; | ||
} | ||
for (const element of directiveValue) { | ||
if (typeof element === "string" && isDirectiveValueInvalid(element)) { | ||
throw new Error(`Content-Security-Policy received an invalid directive value for ${JSON.stringify(directiveName)}`); | ||
} | ||
} | ||
result.push({ directiveName, directiveValue }); | ||
} | ||
if (!result.length) { | ||
throw new Error("Content-Security-Policy has no directives. Either set some or disable the header"); | ||
} | ||
if (!directiveNamesSeen.has("default-src")) { | ||
throw new Error("Content-Security-Policy needs a default-src but none was provided"); | ||
} | ||
return result; | ||
const { directives: rawDirectives = getDefaultDirectives() } = options | ||
const result = [] | ||
const directiveNamesSeen = new Set() | ||
for (const rawDirectiveName in rawDirectives) { | ||
if (!has(rawDirectives, rawDirectiveName)) { | ||
continue | ||
} | ||
if (rawDirectiveName.length === 0 || /[^a-zA-Z0-9-]/.test(rawDirectiveName)) { | ||
throw new Error(`Content-Security-Policy received an invalid directive name ${JSON.stringify(rawDirectiveName)}`) | ||
} | ||
const directiveName = dashify(rawDirectiveName) | ||
if (directiveNamesSeen.has(directiveName)) { | ||
throw new Error(`Content-Security-Policy received a duplicate directive ${JSON.stringify(directiveName)}`) | ||
} | ||
directiveNamesSeen.add(directiveName) | ||
const rawDirectiveValue = rawDirectives[rawDirectiveName] | ||
let directiveValue | ||
if (typeof rawDirectiveValue === "string") { | ||
directiveValue = [rawDirectiveValue] | ||
} else if (!rawDirectiveValue) { | ||
throw new Error(`Content-Security-Policy received an invalid directive value for ${JSON.stringify(directiveName)}`) | ||
} else if (rawDirectiveValue === dangerouslyDisableDefaultSrc) { | ||
if (directiveName === "default-src") { | ||
continue | ||
} else { | ||
throw new Error(`Content-Security-Policy: tried to disable ${JSON.stringify(directiveName)} as if it were default-src; simply omit the key`) | ||
} | ||
} else { | ||
directiveValue = rawDirectiveValue | ||
} | ||
for (const element of directiveValue) { | ||
if (typeof element === "string" && isDirectiveValueInvalid(element)) { | ||
throw new Error(`Content-Security-Policy received an invalid directive value for ${JSON.stringify(directiveName)}`) | ||
} | ||
} | ||
result.push({ directiveName, directiveValue }) | ||
} | ||
if (!result.length) { | ||
throw new Error("Content-Security-Policy has no directives. Either set some or disable the header") | ||
} | ||
if (!directiveNamesSeen.has("default-src")) { | ||
throw new Error("Content-Security-Policy needs a default-src but none was provided") | ||
} | ||
return result | ||
} | ||
function getHeaderValue(req, res, normalizedDirectives) { | ||
const result = []; | ||
for (const { directiveName, directiveValue: rawDirectiveValue, } of normalizedDirectives) { | ||
let directiveValue = ""; | ||
for (const element of rawDirectiveValue) { | ||
if (element instanceof Function) { | ||
directiveValue += " " + element(req, res); | ||
} | ||
else { | ||
directiveValue += " " + element; | ||
} | ||
} | ||
if (!directiveValue) { | ||
result.push(directiveName); | ||
} | ||
else if (isDirectiveValueInvalid(directiveValue)) { | ||
return new Error(`Content-Security-Policy received an invalid directive value for ${JSON.stringify(directiveName)}`); | ||
} | ||
else { | ||
result.push(`${directiveName}${directiveValue}`); | ||
} | ||
} | ||
return result.join(";"); | ||
const result = [] | ||
for (const { directiveName, directiveValue: rawDirectiveValue } of normalizedDirectives) { | ||
let directiveValue = "" | ||
for (const element of rawDirectiveValue) { | ||
if (element instanceof Function) { | ||
directiveValue += " " + element(req, res) | ||
} else { | ||
directiveValue += " " + element | ||
} | ||
} | ||
if (!directiveValue) { | ||
result.push(directiveName) | ||
} else if (isDirectiveValueInvalid(directiveValue)) { | ||
return new Error(`Content-Security-Policy received an invalid directive value for ${JSON.stringify(directiveName)}`) | ||
} else { | ||
result.push(`${directiveName}${directiveValue}`) | ||
} | ||
} | ||
return result.join(";") | ||
} | ||
const contentSecurityPolicy = function contentSecurityPolicy(options = {}) { | ||
if ("loose" in options) { | ||
console.warn("Content-Security-Policy middleware no longer needs the `loose` parameter. You should remove it."); | ||
} | ||
if ("setAllHeaders" in options) { | ||
console.warn("Content-Security-Policy middleware no longer supports the `setAllHeaders` parameter. See <https://github.com/helmetjs/helmet/wiki/Setting-legacy-Content-Security-Policy-headers-in-Helmet-4>."); | ||
} | ||
["disableAndroid", "browserSniff"].forEach((deprecatedOption) => { | ||
if (deprecatedOption in options) { | ||
console.warn(`Content-Security-Policy middleware no longer does browser sniffing, so you can remove the \`${deprecatedOption}\` option. See <https://github.com/helmetjs/csp/issues/97> for discussion.`); | ||
} | ||
}); | ||
const headerName = options.reportOnly | ||
? "Content-Security-Policy-Report-Only" | ||
: "Content-Security-Policy"; | ||
const normalizedDirectives = normalizeDirectives(options); | ||
return function contentSecurityPolicyMiddleware(req, res, next) { | ||
const result = getHeaderValue(req, res, normalizedDirectives); | ||
if (result instanceof Error) { | ||
next(result); | ||
} | ||
else { | ||
res.setHeader(headerName, result); | ||
next(); | ||
} | ||
}; | ||
}; | ||
contentSecurityPolicy.getDefaultDirectives = getDefaultDirectives; | ||
contentSecurityPolicy.dangerouslyDisableDefaultSrc = dangerouslyDisableDefaultSrc; | ||
module.exports = contentSecurityPolicy; | ||
exports.default = contentSecurityPolicy; | ||
if ("loose" in options) { | ||
console.warn("Content-Security-Policy middleware no longer needs the `loose` parameter. You should remove it.") | ||
} | ||
if ("setAllHeaders" in options) { | ||
console.warn("Content-Security-Policy middleware no longer supports the `setAllHeaders` parameter. See <https://github.com/helmetjs/helmet/wiki/Setting-legacy-Content-Security-Policy-headers-in-Helmet-4>.") | ||
} | ||
;["disableAndroid", "browserSniff"].forEach(deprecatedOption => { | ||
if (deprecatedOption in options) { | ||
console.warn(`Content-Security-Policy middleware no longer does browser sniffing, so you can remove the \`${deprecatedOption}\` option. See <https://github.com/helmetjs/csp/issues/97> for discussion.`) | ||
} | ||
}) | ||
const headerName = options.reportOnly ? "Content-Security-Policy-Report-Only" : "Content-Security-Policy" | ||
const normalizedDirectives = normalizeDirectives(options) | ||
return function contentSecurityPolicyMiddleware(req, res, next) { | ||
const result = getHeaderValue(req, res, normalizedDirectives) | ||
if (result instanceof Error) { | ||
next(result) | ||
} else { | ||
res.setHeader(headerName, result) | ||
next() | ||
} | ||
} | ||
} | ||
contentSecurityPolicy.getDefaultDirectives = getDefaultDirectives | ||
contentSecurityPolicy.dangerouslyDisableDefaultSrc = dangerouslyDisableDefaultSrc | ||
module.exports = contentSecurityPolicy | ||
exports.default = contentSecurityPolicy |
@@ -1,8 +0,8 @@ | ||
import { IncomingMessage, ServerResponse } from "http"; | ||
import { IncomingMessage, ServerResponse } from "http" | ||
export interface ExpectCtOptions { | ||
maxAge?: number; | ||
enforce?: boolean; | ||
reportUri?: string; | ||
maxAge?: number | ||
enforce?: boolean | ||
reportUri?: string | ||
} | ||
declare function expectCt(options?: Readonly<ExpectCtOptions>): (_req: IncomingMessage, res: ServerResponse, next: () => void) => void; | ||
export default expectCt; | ||
declare function expectCt(options?: Readonly<ExpectCtOptions>): (_req: IncomingMessage, res: ServerResponse, next: () => void) => void | ||
export default expectCt |
@@ -1,29 +0,28 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
"use strict" | ||
Object.defineProperty(exports, "__esModule", { value: true }) | ||
function parseMaxAge(value = 0) { | ||
if (value >= 0 && Number.isFinite(value)) { | ||
return Math.floor(value); | ||
} | ||
else { | ||
throw new Error(`Expect-CT: ${JSON.stringify(value)} is not a valid value for maxAge. Please choose a positive integer.`); | ||
} | ||
if (value >= 0 && Number.isFinite(value)) { | ||
return Math.floor(value) | ||
} else { | ||
throw new Error(`Expect-CT: ${JSON.stringify(value)} is not a valid value for maxAge. Please choose a positive integer.`) | ||
} | ||
} | ||
function getHeaderValueFromOptions(options) { | ||
const directives = [`max-age=${parseMaxAge(options.maxAge)}`]; | ||
if (options.enforce) { | ||
directives.push("enforce"); | ||
} | ||
if (options.reportUri) { | ||
directives.push(`report-uri="${options.reportUri}"`); | ||
} | ||
return directives.join(", "); | ||
const directives = [`max-age=${parseMaxAge(options.maxAge)}`] | ||
if (options.enforce) { | ||
directives.push("enforce") | ||
} | ||
if (options.reportUri) { | ||
directives.push(`report-uri="${options.reportUri}"`) | ||
} | ||
return directives.join(", ") | ||
} | ||
function expectCt(options = {}) { | ||
const headerValue = getHeaderValueFromOptions(options); | ||
return function expectCtMiddleware(_req, res, next) { | ||
res.setHeader("Expect-CT", headerValue); | ||
next(); | ||
}; | ||
const headerValue = getHeaderValueFromOptions(options) | ||
return function expectCtMiddleware(_req, res, next) { | ||
res.setHeader("Expect-CT", headerValue) | ||
next() | ||
} | ||
} | ||
module.exports = expectCt; | ||
exports.default = expectCt; | ||
module.exports = expectCt | ||
exports.default = expectCt |
@@ -1,6 +0,6 @@ | ||
import { IncomingMessage, ServerResponse } from "http"; | ||
import { IncomingMessage, ServerResponse } from "http" | ||
export interface ReferrerPolicyOptions { | ||
policy?: string | string[]; | ||
policy?: string | string[] | ||
} | ||
declare function referrerPolicy(options?: Readonly<ReferrerPolicyOptions>): (_req: IncomingMessage, res: ServerResponse, next: () => void) => void; | ||
export default referrerPolicy; | ||
declare function referrerPolicy(options?: Readonly<ReferrerPolicyOptions>): (_req: IncomingMessage, res: ServerResponse, next: () => void) => void | ||
export default referrerPolicy |
@@ -1,39 +0,28 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
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", | ||
"", | ||
]); | ||
function getHeaderValueFromOptions({ policy = ["no-referrer"], }) { | ||
const tokens = typeof policy === "string" ? [policy] : policy; | ||
if (tokens.length === 0) { | ||
throw new Error("Referrer-Policy received no policy tokens"); | ||
} | ||
const tokensSeen = new Set(); | ||
tokens.forEach((token) => { | ||
if (!ALLOWED_TOKENS.has(token)) { | ||
throw new Error(`Referrer-Policy received an unexpected policy token ${JSON.stringify(token)}`); | ||
} | ||
else if (tokensSeen.has(token)) { | ||
throw new Error(`Referrer-Policy received a duplicate policy token ${JSON.stringify(token)}`); | ||
} | ||
tokensSeen.add(token); | ||
}); | ||
return tokens.join(","); | ||
"use strict" | ||
Object.defineProperty(exports, "__esModule", { value: true }) | ||
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", ""]) | ||
function getHeaderValueFromOptions({ policy = ["no-referrer"] }) { | ||
const tokens = typeof policy === "string" ? [policy] : policy | ||
if (tokens.length === 0) { | ||
throw new Error("Referrer-Policy received no policy tokens") | ||
} | ||
const tokensSeen = new Set() | ||
tokens.forEach(token => { | ||
if (!ALLOWED_TOKENS.has(token)) { | ||
throw new Error(`Referrer-Policy received an unexpected policy token ${JSON.stringify(token)}`) | ||
} else if (tokensSeen.has(token)) { | ||
throw new Error(`Referrer-Policy received a duplicate policy token ${JSON.stringify(token)}`) | ||
} | ||
tokensSeen.add(token) | ||
}) | ||
return tokens.join(",") | ||
} | ||
function referrerPolicy(options = {}) { | ||
const headerValue = getHeaderValueFromOptions(options); | ||
return function referrerPolicyMiddleware(_req, res, next) { | ||
res.setHeader("Referrer-Policy", headerValue); | ||
next(); | ||
}; | ||
const headerValue = getHeaderValueFromOptions(options) | ||
return function referrerPolicyMiddleware(_req, res, next) { | ||
res.setHeader("Referrer-Policy", headerValue) | ||
next() | ||
} | ||
} | ||
module.exports = referrerPolicy; | ||
exports.default = referrerPolicy; | ||
module.exports = referrerPolicy | ||
exports.default = referrerPolicy |
@@ -1,8 +0,8 @@ | ||
import { IncomingMessage, ServerResponse } from "http"; | ||
import { IncomingMessage, ServerResponse } from "http" | ||
export interface StrictTransportSecurityOptions { | ||
maxAge?: number; | ||
includeSubDomains?: boolean; | ||
preload?: boolean; | ||
maxAge?: number | ||
includeSubDomains?: boolean | ||
preload?: boolean | ||
} | ||
declare function strictTransportSecurity(options?: Readonly<StrictTransportSecurityOptions>): (_req: IncomingMessage, res: ServerResponse, next: () => void) => void; | ||
export default strictTransportSecurity; | ||
declare function strictTransportSecurity(options?: Readonly<StrictTransportSecurityOptions>): (_req: IncomingMessage, res: ServerResponse, next: () => void) => void | ||
export default strictTransportSecurity |
@@ -1,39 +0,38 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const DEFAULT_MAX_AGE = 180 * 24 * 60 * 60; | ||
"use strict" | ||
Object.defineProperty(exports, "__esModule", { value: true }) | ||
const DEFAULT_MAX_AGE = 180 * 24 * 60 * 60 | ||
function parseMaxAge(value = DEFAULT_MAX_AGE) { | ||
if (value >= 0 && Number.isFinite(value)) { | ||
return Math.floor(value); | ||
} | ||
else { | ||
throw new Error(`Strict-Transport-Security: ${JSON.stringify(value)} is not a valid value for maxAge. Please choose a positive integer.`); | ||
} | ||
if (value >= 0 && Number.isFinite(value)) { | ||
return Math.floor(value) | ||
} else { | ||
throw new Error(`Strict-Transport-Security: ${JSON.stringify(value)} is not a valid value for maxAge. Please choose a positive integer.`) | ||
} | ||
} | ||
function getHeaderValueFromOptions(options) { | ||
if ("maxage" in options) { | ||
throw new Error("Strict-Transport-Security received an unsupported property, `maxage`. Did you mean to pass `maxAge`?"); | ||
} | ||
if ("includeSubdomains" in options) { | ||
console.warn('Strict-Transport-Security middleware should use `includeSubDomains` instead of `includeSubdomains`. (The correct one has an uppercase "D".)'); | ||
} | ||
if ("setIf" in options) { | ||
console.warn("Strict-Transport-Security middleware no longer supports the `setIf` parameter. See the documentation and <https://github.com/helmetjs/helmet/wiki/Conditionally-using-middleware> if you need help replicating this behavior."); | ||
} | ||
const directives = [`max-age=${parseMaxAge(options.maxAge)}`]; | ||
if (options.includeSubDomains === undefined || options.includeSubDomains) { | ||
directives.push("includeSubDomains"); | ||
} | ||
if (options.preload) { | ||
directives.push("preload"); | ||
} | ||
return directives.join("; "); | ||
if ("maxage" in options) { | ||
throw new Error("Strict-Transport-Security received an unsupported property, `maxage`. Did you mean to pass `maxAge`?") | ||
} | ||
if ("includeSubdomains" in options) { | ||
console.warn('Strict-Transport-Security middleware should use `includeSubDomains` instead of `includeSubdomains`. (The correct one has an uppercase "D".)') | ||
} | ||
if ("setIf" in options) { | ||
console.warn("Strict-Transport-Security middleware no longer supports the `setIf` parameter. See the documentation and <https://github.com/helmetjs/helmet/wiki/Conditionally-using-middleware> if you need help replicating this behavior.") | ||
} | ||
const directives = [`max-age=${parseMaxAge(options.maxAge)}`] | ||
if (options.includeSubDomains === undefined || options.includeSubDomains) { | ||
directives.push("includeSubDomains") | ||
} | ||
if (options.preload) { | ||
directives.push("preload") | ||
} | ||
return directives.join("; ") | ||
} | ||
function strictTransportSecurity(options = {}) { | ||
const headerValue = getHeaderValueFromOptions(options); | ||
return function strictTransportSecurityMiddleware(_req, res, next) { | ||
res.setHeader("Strict-Transport-Security", headerValue); | ||
next(); | ||
}; | ||
const headerValue = getHeaderValueFromOptions(options) | ||
return function strictTransportSecurityMiddleware(_req, res, next) { | ||
res.setHeader("Strict-Transport-Security", headerValue) | ||
next() | ||
} | ||
} | ||
module.exports = strictTransportSecurity; | ||
exports.default = strictTransportSecurity; | ||
module.exports = strictTransportSecurity | ||
exports.default = strictTransportSecurity |
@@ -1,3 +0,3 @@ | ||
import { IncomingMessage, ServerResponse } from "http"; | ||
declare function xContentTypeOptions(): (_req: IncomingMessage, res: ServerResponse, next: () => void) => void; | ||
export default xContentTypeOptions; | ||
import { IncomingMessage, ServerResponse } from "http" | ||
declare function xContentTypeOptions(): (_req: IncomingMessage, res: ServerResponse, next: () => void) => void | ||
export default xContentTypeOptions |
@@ -1,10 +0,10 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
"use strict" | ||
Object.defineProperty(exports, "__esModule", { value: true }) | ||
function xContentTypeOptions() { | ||
return function xContentTypeOptionsMiddleware(_req, res, next) { | ||
res.setHeader("X-Content-Type-Options", "nosniff"); | ||
next(); | ||
}; | ||
return function xContentTypeOptionsMiddleware(_req, res, next) { | ||
res.setHeader("X-Content-Type-Options", "nosniff") | ||
next() | ||
} | ||
} | ||
module.exports = xContentTypeOptions; | ||
exports.default = xContentTypeOptions; | ||
module.exports = xContentTypeOptions | ||
exports.default = xContentTypeOptions |
@@ -1,6 +0,6 @@ | ||
import { IncomingMessage, ServerResponse } from "http"; | ||
import { IncomingMessage, ServerResponse } from "http" | ||
export interface XDnsPrefetchControlOptions { | ||
allow?: boolean; | ||
allow?: boolean | ||
} | ||
declare function xDnsPrefetchControl(options?: Readonly<XDnsPrefetchControlOptions>): (_req: IncomingMessage, res: ServerResponse, next: () => void) => void; | ||
export default xDnsPrefetchControl; | ||
declare function xDnsPrefetchControl(options?: Readonly<XDnsPrefetchControlOptions>): (_req: IncomingMessage, res: ServerResponse, next: () => void) => void | ||
export default xDnsPrefetchControl |
@@ -1,11 +0,11 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
"use strict" | ||
Object.defineProperty(exports, "__esModule", { value: true }) | ||
function xDnsPrefetchControl(options = {}) { | ||
const headerValue = options.allow ? "on" : "off"; | ||
return function xDnsPrefetchControlMiddleware(_req, res, next) { | ||
res.setHeader("X-DNS-Prefetch-Control", headerValue); | ||
next(); | ||
}; | ||
const headerValue = options.allow ? "on" : "off" | ||
return function xDnsPrefetchControlMiddleware(_req, res, next) { | ||
res.setHeader("X-DNS-Prefetch-Control", headerValue) | ||
next() | ||
} | ||
} | ||
module.exports = xDnsPrefetchControl; | ||
exports.default = xDnsPrefetchControl; | ||
module.exports = xDnsPrefetchControl | ||
exports.default = xDnsPrefetchControl |
@@ -1,3 +0,3 @@ | ||
import { IncomingMessage, ServerResponse } from "http"; | ||
declare function xDownloadOptions(): (_req: IncomingMessage, res: ServerResponse, next: () => void) => void; | ||
export default xDownloadOptions; | ||
import { IncomingMessage, ServerResponse } from "http" | ||
declare function xDownloadOptions(): (_req: IncomingMessage, res: ServerResponse, next: () => void) => void | ||
export default xDownloadOptions |
@@ -1,10 +0,10 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
"use strict" | ||
Object.defineProperty(exports, "__esModule", { value: true }) | ||
function xDownloadOptions() { | ||
return function xDownloadOptionsMiddleware(_req, res, next) { | ||
res.setHeader("X-Download-Options", "noopen"); | ||
next(); | ||
}; | ||
return function xDownloadOptionsMiddleware(_req, res, next) { | ||
res.setHeader("X-Download-Options", "noopen") | ||
next() | ||
} | ||
} | ||
module.exports = xDownloadOptions; | ||
exports.default = xDownloadOptions; | ||
module.exports = xDownloadOptions | ||
exports.default = xDownloadOptions |
@@ -1,6 +0,6 @@ | ||
import { IncomingMessage, ServerResponse } from "http"; | ||
import { IncomingMessage, ServerResponse } from "http" | ||
export interface XFrameOptionsOptions { | ||
action?: string; | ||
action?: string | ||
} | ||
declare function xFrameOptions(options?: Readonly<XFrameOptionsOptions>): (_req: IncomingMessage, res: ServerResponse, next: () => void) => void; | ||
export default xFrameOptions; | ||
declare function xFrameOptions(options?: Readonly<XFrameOptionsOptions>): (_req: IncomingMessage, res: ServerResponse, next: () => void) => void | ||
export default xFrameOptions |
@@ -1,25 +0,25 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
function getHeaderValueFromOptions({ action = "SAMEORIGIN", }) { | ||
const normalizedAction = typeof action === "string" ? action.toUpperCase() : action; | ||
switch (normalizedAction) { | ||
case "SAME-ORIGIN": | ||
return "SAMEORIGIN"; | ||
case "DENY": | ||
case "SAMEORIGIN": | ||
return normalizedAction; | ||
case "ALLOW-FROM": | ||
throw new Error("X-Frame-Options no longer supports `ALLOW-FROM` due to poor browser support. See <https://github.com/helmetjs/helmet/wiki/How-to-use-X%E2%80%93Frame%E2%80%93Options's-%60ALLOW%E2%80%93FROM%60-directive> for more info."); | ||
default: | ||
throw new Error(`X-Frame-Options received an invalid action ${JSON.stringify(action)}`); | ||
} | ||
"use strict" | ||
Object.defineProperty(exports, "__esModule", { value: true }) | ||
function getHeaderValueFromOptions({ action = "SAMEORIGIN" }) { | ||
const normalizedAction = typeof action === "string" ? action.toUpperCase() : action | ||
switch (normalizedAction) { | ||
case "SAME-ORIGIN": | ||
return "SAMEORIGIN" | ||
case "DENY": | ||
case "SAMEORIGIN": | ||
return normalizedAction | ||
case "ALLOW-FROM": | ||
throw new Error("X-Frame-Options no longer supports `ALLOW-FROM` due to poor browser support. See <https://github.com/helmetjs/helmet/wiki/How-to-use-X%E2%80%93Frame%E2%80%93Options's-%60ALLOW%E2%80%93FROM%60-directive> for more info.") | ||
default: | ||
throw new Error(`X-Frame-Options received an invalid action ${JSON.stringify(action)}`) | ||
} | ||
} | ||
function xFrameOptions(options = {}) { | ||
const headerValue = getHeaderValueFromOptions(options); | ||
return function xFrameOptionsMiddleware(_req, res, next) { | ||
res.setHeader("X-Frame-Options", headerValue); | ||
next(); | ||
}; | ||
const headerValue = getHeaderValueFromOptions(options) | ||
return function xFrameOptionsMiddleware(_req, res, next) { | ||
res.setHeader("X-Frame-Options", headerValue) | ||
next() | ||
} | ||
} | ||
module.exports = xFrameOptions; | ||
exports.default = xFrameOptions; | ||
module.exports = xFrameOptions | ||
exports.default = xFrameOptions |
@@ -1,6 +0,6 @@ | ||
import { IncomingMessage, ServerResponse } from "http"; | ||
import { IncomingMessage, ServerResponse } from "http" | ||
export interface XPermittedCrossDomainPoliciesOptions { | ||
permittedPolicies?: string; | ||
permittedPolicies?: string | ||
} | ||
declare function xPermittedCrossDomainPolicies(options?: Readonly<XPermittedCrossDomainPoliciesOptions>): (_req: IncomingMessage, res: ServerResponse, next: () => void) => void; | ||
export default xPermittedCrossDomainPolicies; | ||
declare function xPermittedCrossDomainPolicies(options?: Readonly<XPermittedCrossDomainPoliciesOptions>): (_req: IncomingMessage, res: ServerResponse, next: () => void) => void | ||
export default xPermittedCrossDomainPolicies |
@@ -1,25 +0,19 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const ALLOWED_PERMITTED_POLICIES = new Set([ | ||
"none", | ||
"master-only", | ||
"by-content-type", | ||
"all", | ||
]); | ||
function getHeaderValueFromOptions({ permittedPolicies = "none", }) { | ||
if (ALLOWED_PERMITTED_POLICIES.has(permittedPolicies)) { | ||
return permittedPolicies; | ||
} | ||
else { | ||
throw new Error(`X-Permitted-Cross-Domain-Policies does not support ${JSON.stringify(permittedPolicies)}`); | ||
} | ||
"use strict" | ||
Object.defineProperty(exports, "__esModule", { value: true }) | ||
const ALLOWED_PERMITTED_POLICIES = new Set(["none", "master-only", "by-content-type", "all"]) | ||
function getHeaderValueFromOptions({ permittedPolicies = "none" }) { | ||
if (ALLOWED_PERMITTED_POLICIES.has(permittedPolicies)) { | ||
return permittedPolicies | ||
} else { | ||
throw new Error(`X-Permitted-Cross-Domain-Policies does not support ${JSON.stringify(permittedPolicies)}`) | ||
} | ||
} | ||
function xPermittedCrossDomainPolicies(options = {}) { | ||
const headerValue = getHeaderValueFromOptions(options); | ||
return function xPermittedCrossDomainPoliciesMiddleware(_req, res, next) { | ||
res.setHeader("X-Permitted-Cross-Domain-Policies", headerValue); | ||
next(); | ||
}; | ||
const headerValue = getHeaderValueFromOptions(options) | ||
return function xPermittedCrossDomainPoliciesMiddleware(_req, res, next) { | ||
res.setHeader("X-Permitted-Cross-Domain-Policies", headerValue) | ||
next() | ||
} | ||
} | ||
module.exports = xPermittedCrossDomainPolicies; | ||
exports.default = xPermittedCrossDomainPolicies; | ||
module.exports = xPermittedCrossDomainPolicies | ||
exports.default = xPermittedCrossDomainPolicies |
@@ -1,3 +0,3 @@ | ||
import { IncomingMessage, ServerResponse } from "http"; | ||
declare function xPoweredBy(): (_req: IncomingMessage, res: ServerResponse, next: () => void) => void; | ||
export default xPoweredBy; | ||
import { IncomingMessage, ServerResponse } from "http" | ||
declare function xPoweredBy(): (_req: IncomingMessage, res: ServerResponse, next: () => void) => void | ||
export default xPoweredBy |
@@ -1,10 +0,10 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
"use strict" | ||
Object.defineProperty(exports, "__esModule", { value: true }) | ||
function xPoweredBy() { | ||
return function xPoweredByMiddleware(_req, res, next) { | ||
res.removeHeader("X-Powered-By"); | ||
next(); | ||
}; | ||
return function xPoweredByMiddleware(_req, res, next) { | ||
res.removeHeader("X-Powered-By") | ||
next() | ||
} | ||
} | ||
module.exports = xPoweredBy; | ||
exports.default = xPoweredBy; | ||
module.exports = xPoweredBy | ||
exports.default = xPoweredBy |
@@ -1,3 +0,3 @@ | ||
import { IncomingMessage, ServerResponse } from "http"; | ||
declare function xXssProtection(): (_req: IncomingMessage, res: ServerResponse, next: () => void) => void; | ||
export default xXssProtection; | ||
import { IncomingMessage, ServerResponse } from "http" | ||
declare function xXssProtection(): (_req: IncomingMessage, res: ServerResponse, next: () => void) => void | ||
export default xXssProtection |
@@ -1,10 +0,10 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
"use strict" | ||
Object.defineProperty(exports, "__esModule", { value: true }) | ||
function xXssProtection() { | ||
return function xXssProtectionMiddleware(_req, res, next) { | ||
res.setHeader("X-XSS-Protection", "0"); | ||
next(); | ||
}; | ||
return function xXssProtectionMiddleware(_req, res, next) { | ||
res.setHeader("X-XSS-Protection", "0") | ||
next() | ||
} | ||
} | ||
module.exports = xXssProtection; | ||
exports.default = xXssProtection; | ||
module.exports = xXssProtection | ||
exports.default = xXssProtection |
@@ -9,3 +9,3 @@ { | ||
"description": "help secure Express/Connect apps with various HTTP headers", | ||
"version": "4.3.1", | ||
"version": "4.4.0", | ||
"keywords": [ | ||
@@ -37,24 +37,26 @@ "express", | ||
"dist/index.d.ts", | ||
"dist/middlewares/content-security-policy/index.d.ts", | ||
"dist/middlewares/content-security-policy/index.js", | ||
"dist/middlewares/content-security-policy/index.d.ts", | ||
"dist/middlewares/expect-ct/index.d.ts", | ||
"dist/middlewares/expect-ct/index.js", | ||
"dist/middlewares/expect-ct/index.d.ts", | ||
"dist/middlewares/origin-agent-cluster/index.d.ts", | ||
"dist/middlewares/origin-agent-cluster/index.js", | ||
"dist/middlewares/referrer-policy/index.d.ts", | ||
"dist/middlewares/referrer-policy/index.js", | ||
"dist/middlewares/referrer-policy/index.d.ts", | ||
"dist/middlewares/strict-transport-security/index.d.ts", | ||
"dist/middlewares/strict-transport-security/index.js", | ||
"dist/middlewares/strict-transport-security/index.d.ts", | ||
"dist/middlewares/x-content-type-options/index.d.ts", | ||
"dist/middlewares/x-content-type-options/index.js", | ||
"dist/middlewares/x-content-type-options/index.d.ts", | ||
"dist/middlewares/x-dns-prefetch-control/index.d.ts", | ||
"dist/middlewares/x-dns-prefetch-control/index.js", | ||
"dist/middlewares/x-dns-prefetch-control/index.d.ts", | ||
"dist/middlewares/x-download-options/index.d.ts", | ||
"dist/middlewares/x-download-options/index.js", | ||
"dist/middlewares/x-download-options/index.d.ts", | ||
"dist/middlewares/x-frame-options/index.d.ts", | ||
"dist/middlewares/x-frame-options/index.js", | ||
"dist/middlewares/x-frame-options/index.d.ts", | ||
"dist/middlewares/x-permitted-cross-domain-policies/index.d.ts", | ||
"dist/middlewares/x-permitted-cross-domain-policies/index.js", | ||
"dist/middlewares/x-permitted-cross-domain-policies/index.d.ts", | ||
"dist/middlewares/x-powered-by/index.d.ts", | ||
"dist/middlewares/x-powered-by/index.js", | ||
"dist/middlewares/x-powered-by/index.d.ts", | ||
"dist/middlewares/x-xss-protection/index.js", | ||
"dist/middlewares/x-xss-protection/index.d.ts" | ||
"dist/middlewares/x-xss-protection/index.d.ts", | ||
"dist/middlewares/x-xss-protection/index.js" | ||
], | ||
@@ -83,3 +85,3 @@ "devDependencies": { | ||
"clean": "node ./bin/clean.js", | ||
"build": "npm run clean && tsc", | ||
"build": "npm run clean && tsc && npm run format", | ||
"build-middleware-package": "npm run build && node ./bin/build-middleware-package.js", | ||
@@ -86,0 +88,0 @@ "test": "jest" |
@@ -341,2 +341,20 @@ # Helmet | ||
<details> | ||
<summary><code>helmet.originAgentCluster()</code></summary> | ||
`helmet.originAgentCluster` sets the `Origin-Agent-Cluster` header, which provides a mechanism to allow web applications to isolate their origins. Read more about it [in the spec](https://whatpr.org/html/6214/origin.html#origin-keyed-agent-clusters). | ||
This middleware takes no options. | ||
Examples: | ||
```js | ||
// Sets "Origin-Agent-Cluster: ?1" | ||
app.use(helmet.originAgentCluster()); | ||
``` | ||
You can't install this module separately. | ||
</details> | ||
<details> | ||
<summary><code>helmet.dnsPrefetchControl(options)</code></summary> | ||
@@ -343,0 +361,0 @@ |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
33
500
70173
561
1