From 5c80bce0dd1e1b7f3f5863e2bf8742b3aca05997 Mon Sep 17 00:00:00 2001 From: Evan Hahn Date: Sat, 2 Apr 2016 15:20:40 -0700 Subject: [PATCH] Improve Helmet contentSecurityPolicy definitions This change adds a number of additional options that `helmet.contentSecurityPolicy` can take. --- helmet/helmet-tests.ts | 61 +++++++++++++++++++++++++++--------------- helmet/helmet.d.ts | 29 +++++++++++++++----- 2 files changed, 62 insertions(+), 28 deletions(-) diff --git a/helmet/helmet-tests.ts b/helmet/helmet-tests.ts index 83fd224a7..48e4f2d9a 100644 --- a/helmet/helmet-tests.ts +++ b/helmet/helmet-tests.ts @@ -21,37 +21,56 @@ function xssFilterTest() { } /** - * @summary Test for {@see helmet#csp} function + * @summary Test for {@see helmet#csp} function. */ function contentSecurityPolicyTest() { - - // taken directly from helmet-csp docs + const emptyArray: string[] = []; const config = { - // Specify directives as normal. directives: { - defaultSrc: ["'self'", 'default.com'], - scriptSrc: ["'self'", "'unsafe-inline'"], - styleSrc: ['style.com'], - imgSrc: ['img.com', 'data:'], - sandbox: ['allow-forms', 'allow-scripts'], - reportUri: '/report-violation', - - objectSrc: ["'self'"], // An empty array allows nothing through + baseUri: ['base.example.com'], + childSrc: ['child.example.com'], + connectSrc: ['connect.example.com'], + defaultSrc: ['*'], + fontSrc: ['font.example.com'], + formAction: ['formaction.example.com'], + frameAncestors: ["'none'"], + frameSrc: emptyArray, + imgSrc: ['images.example.com'], + mediaSrc: ['media.example.com'], + objectSrc: ['objects.example.com'], + pluginTypes: emptyArray, + reportUri: '/some-url', + sandbox: emptyArray, + scriptSrc: ['scripts.example.com', function (req: express.Request, res: express.Response) { + return "'nonce-abc123'"; + }], + styleSrc: ['css.example.com'] }, - - // Set to true if you only want browsers to report errors, not block them reportOnly: false, - - // Set to true if you want to blindly set all headers: Content-Security-Policy, - // X-WebKit-CSP, and X-Content-Security-Policy. setAllHeaders: false, - - // Set to true if you want to disable CSP on Android where it can be buggy. disableAndroid: false - } - app.use(helmet.csp()); + }; + + app.use(helmet.contentSecurityPolicy()); + app.use(helmet.contentSecurityPolicy({})); app.use(helmet.contentSecurityPolicy(config)); + app.use(helmet.contentSecurityPolicy({ + directives: { + defaultSrc: ["'self'"] + }, + setAllHeaders: true + })); + + app.use(helmet.csp()); + app.use(helmet.csp({})); + app.use(helmet.csp(config)); + app.use(helmet.csp({ + directives: { + defaultSrc: ["'self'"] + }, + setAllHeaders: true + })); } /** diff --git a/helmet/helmet.d.ts b/helmet/helmet.d.ts index 39f831155..f209af051 100644 --- a/helmet/helmet.d.ts +++ b/helmet/helmet.d.ts @@ -8,20 +8,35 @@ declare module "helmet" { import express = require("express"); + interface IHelmetCspDirectiveFunction { + (req: express.Request, res: express.Response): string; + } + type HelmetCspDirectiveValue = string | IHelmetCspDirectiveFunction; + interface IHelmetCspDirectives { - defaultSrc? : string[]; - scriptSrc? : string[]; - styleSrc? : string[]; - imgSrc? : string[]; - sandbox? : string[]; - reportUri? : string; - objectSrc? : string[]; + baseUri? : HelmetCspDirectiveValue[], + childSrc? : HelmetCspDirectiveValue[], + connectSrc? : HelmetCspDirectiveValue[], + defaultSrc? : HelmetCspDirectiveValue[], + fontSrc? : HelmetCspDirectiveValue[], + formAction? : HelmetCspDirectiveValue[], + frameAncestors? : HelmetCspDirectiveValue[], + frameSrc? : HelmetCspDirectiveValue[], + imgSrc? : HelmetCspDirectiveValue[], + mediaSrc? : HelmetCspDirectiveValue[], + objectSrc? : HelmetCspDirectiveValue[], + pluginTypes? : HelmetCspDirectiveValue[], + reportUri?: string, + sandbox? : HelmetCspDirectiveValue[], + scriptSrc? : HelmetCspDirectiveValue[], + styleSrc? : HelmetCspDirectiveValue[] } interface IHelmetCspConfiguration { reportOnly? : boolean; setAllHeaders? : boolean; disableAndroid? : boolean; + browserSniff?: boolean; directives? : IHelmetCspDirectives }