initial commit

This commit is contained in:
teddit
2020-11-17 21:44:32 +01:00
commit fdfcd554f8
2656 changed files with 318683 additions and 0 deletions
@@ -0,0 +1,24 @@
/// <reference types="node" />
import { IncomingMessage, ServerResponse } from "http";
interface ContentSecurityPolicyDirectiveValueFunction {
(req: IncomingMessage, res: ServerResponse): string;
}
declare type ContentSecurityPolicyDirectiveValue = string | ContentSecurityPolicyDirectiveValueFunction;
interface ContentSecurityPolicyDirectives {
[directiveName: string]: Iterable<ContentSecurityPolicyDirectiveValue>;
}
export interface ContentSecurityPolicyOptions {
directives?: ContentSecurityPolicyDirectives;
reportOnly?: boolean;
}
declare const getDefaultDirectives: () => {
[x: string]: Iterable<ContentSecurityPolicyDirectiveValue>;
};
declare function contentSecurityPolicy(options?: Readonly<ContentSecurityPolicyOptions>): (req: IncomingMessage, res: ServerResponse, next: (err?: Error) => void) => void;
declare namespace contentSecurityPolicy {
var getDefaultDirectives: () => {
[x: string]: Iterable<ContentSecurityPolicyDirectiveValue>;
};
}
export default contentSecurityPolicy;
export { getDefaultDirectives };
+120
View File
@@ -0,0 +1,120 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getDefaultDirectives = void 0;
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 isRawPolicyDirectiveNameInvalid = (rawDirectiveName) => rawDirectiveName.length === 0 || /[^a-zA-Z0-9-]/.test(rawDirectiveName);
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 getHeaderName({ reportOnly, }) {
if (reportOnly) {
return "Content-Security-Policy-Report-Only";
}
else {
return "Content-Security-Policy";
}
}
function normalizeDirectives(options) {
const result = {};
const { directives: rawDirectives = getDefaultDirectives() } = options;
for (const rawDirectiveName in rawDirectives) {
if (!has(rawDirectives, rawDirectiveName)) {
continue;
}
if (isRawPolicyDirectiveNameInvalid(rawDirectiveName)) {
throw new Error(`Content-Security-Policy received an invalid directive name ${JSON.stringify(rawDirectiveName)}`);
}
const directiveName = dashify(rawDirectiveName);
if (has(result, directiveName)) {
throw new Error(`Content-Security-Policy received a duplicate directive ${JSON.stringify(directiveName)}`);
}
const rawDirectiveValue = rawDirectives[rawDirectiveName];
let directiveValue;
if (typeof rawDirectiveValue === "string") {
directiveValue = [rawDirectiveValue];
}
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[directiveName] = directiveValue;
}
if (!("default-src" in result)) {
throw new Error("Content-Security-Policy needs a default-src but none was provided");
}
return result;
}
function getHeaderValue(req, res, directives) {
const result = [];
for (const directiveName in directives) {
if (!has(directives, directiveName)) {
continue;
}
const rawDirectiveValue = directives[directiveName];
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(";");
}
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 = getHeaderName(options);
const directives = normalizeDirectives(options);
return function contentSecurityPolicyMiddleware(req, res, next) {
const result = getHeaderValue(req, res, directives);
if (result instanceof Error) {
next(result);
}
else {
res.setHeader(headerName, result);
next();
}
};
}
contentSecurityPolicy.getDefaultDirectives = getDefaultDirectives;
module.exports = contentSecurityPolicy;
exports.default = contentSecurityPolicy;
+8
View File
@@ -0,0 +1,8 @@
import { IncomingMessage, ServerResponse } from "http";
export interface ExpectCtOptions {
maxAge?: number;
enforce?: boolean;
reportUri?: string;
}
declare function expectCt(options?: Readonly<ExpectCtOptions>): (_req: IncomingMessage, res: ServerResponse, next: () => void) => void;
export default expectCt;
+35
View File
@@ -0,0 +1,35 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
function parseMaxAge(value) {
if (value === undefined) {
return 0;
}
else if (typeof value === "number" &&
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 = [];
directives.push(`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();
};
}
module.exports = expectCt;
exports.default = expectCt;
+6
View File
@@ -0,0 +1,6 @@
import { IncomingMessage, ServerResponse } from "http";
export interface ReferrerPolicyOptions {
policy?: string | string[];
}
declare function referrerPolicy(options?: Readonly<ReferrerPolicyOptions>): (_req: IncomingMessage, res: ServerResponse, next: () => void) => void;
export default referrerPolicy;
+39
View File
@@ -0,0 +1,39 @@
"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();
};
}
module.exports = referrerPolicy;
exports.default = referrerPolicy;
@@ -0,0 +1,8 @@
import { IncomingMessage, ServerResponse } from "http";
export interface StrictTransportSecurityOptions {
maxAge?: number;
includeSubDomains?: boolean;
preload?: boolean;
}
declare function strictTransportSecurity(options?: Readonly<StrictTransportSecurityOptions>): (_req: IncomingMessage, res: ServerResponse, next: () => void) => void;
export default strictTransportSecurity;
@@ -0,0 +1,44 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const DEFAULT_MAX_AGE = 180 * 24 * 60 * 60;
function parseMaxAge(value) {
if (value === undefined) {
return DEFAULT_MAX_AGE;
}
else if (typeof value === "number" &&
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("; ");
}
function strictTransportSecurity(options = {}) {
const headerValue = getHeaderValueFromOptions(options);
return function strictTransportSecurityMiddleware(_req, res, next) {
res.setHeader("Strict-Transport-Security", headerValue);
next();
};
}
module.exports = strictTransportSecurity;
exports.default = strictTransportSecurity;
@@ -0,0 +1,3 @@
import { IncomingMessage, ServerResponse } from "http";
declare function xContentTypeOptions(): (_req: IncomingMessage, res: ServerResponse, next: () => void) => void;
export default xContentTypeOptions;
+10
View File
@@ -0,0 +1,10 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
function xContentTypeOptions() {
return function xContentTypeOptionsMiddleware(_req, res, next) {
res.setHeader("X-Content-Type-Options", "nosniff");
next();
};
}
module.exports = xContentTypeOptions;
exports.default = xContentTypeOptions;
@@ -0,0 +1,6 @@
import { IncomingMessage, ServerResponse } from "http";
export interface XDnsPrefetchControlOptions {
allow?: boolean;
}
declare function xDnsPrefetchControl(options?: Readonly<XDnsPrefetchControlOptions>): (_req: IncomingMessage, res: ServerResponse, next: () => void) => void;
export default xDnsPrefetchControl;
+11
View File
@@ -0,0 +1,11 @@
"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();
};
}
module.exports = xDnsPrefetchControl;
exports.default = xDnsPrefetchControl;
+3
View File
@@ -0,0 +1,3 @@
import { IncomingMessage, ServerResponse } from "http";
declare function xDownloadOptions(): (_req: IncomingMessage, res: ServerResponse, next: () => void) => void;
export default xDownloadOptions;
+10
View File
@@ -0,0 +1,10 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
function xDownloadOptions() {
return function xDownloadOptionsMiddleware(_req, res, next) {
res.setHeader("X-Download-Options", "noopen");
next();
};
}
module.exports = xDownloadOptions;
exports.default = xDownloadOptions;
+6
View File
@@ -0,0 +1,6 @@
import { IncomingMessage, ServerResponse } from "http";
export interface XFrameOptionsOptions {
action?: string;
}
declare function xFrameOptions(options?: Readonly<XFrameOptionsOptions>): (_req: IncomingMessage, res: ServerResponse, next: () => void) => void;
export default xFrameOptions;
+26
View File
@@ -0,0 +1,26 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
function getHeaderValueFromOptions({ action = "SAMEORIGIN", }) {
action = String(action).toUpperCase();
if (action === "SAME-ORIGIN") {
return "SAMEORIGIN";
}
else if (action === "DENY" || action === "SAMEORIGIN") {
return action;
}
else if (action === "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.");
}
else {
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();
};
}
module.exports = xFrameOptions;
exports.default = xFrameOptions;
@@ -0,0 +1,6 @@
import { IncomingMessage, ServerResponse } from "http";
export interface XPermittedCrossDomainPoliciesOptions {
permittedPolicies?: string;
}
declare function xPermittedCrossDomainPolicies(options?: Readonly<XPermittedCrossDomainPoliciesOptions>): (_req: IncomingMessage, res: ServerResponse, next: () => void) => void;
export default xPermittedCrossDomainPolicies;
@@ -0,0 +1,25 @@
"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();
};
}
module.exports = xPermittedCrossDomainPolicies;
exports.default = xPermittedCrossDomainPolicies;
+3
View File
@@ -0,0 +1,3 @@
import { IncomingMessage, ServerResponse } from "http";
declare function xPoweredBy(): (_req: IncomingMessage, res: ServerResponse, next: () => void) => void;
export default xPoweredBy;
+10
View File
@@ -0,0 +1,10 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
function xPoweredBy() {
return function xPoweredByMiddleware(_req, res, next) {
res.removeHeader("X-Powered-By");
next();
};
}
module.exports = xPoweredBy;
exports.default = xPoweredBy;
+3
View File
@@ -0,0 +1,3 @@
import { IncomingMessage, ServerResponse } from "http";
declare function xXssProtection(): (_req: IncomingMessage, res: ServerResponse, next: () => void) => void;
export default xXssProtection;
+10
View File
@@ -0,0 +1,10 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
function xXssProtection() {
return function xXssProtectionMiddleware(_req, res, next) {
res.setHeader("X-XSS-Protection", "0");
next();
};
}
module.exports = xXssProtection;
exports.default = xXssProtection;