-
Notifications
You must be signed in to change notification settings - Fork 373
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Import Referrer-Policy (referrer-policy) middleware
This imports the [helmet-csp package][0] into this repo as part of my effort to make Helmet a monorepo. You can find its prior history in the old repo. Similar to: * 936cd27 which imported `referrer-policy` * 141f131 which imported `crossdomain` * ff12fb7 which imported `dont-sniff-mimetype` * 2b64d11 which imported `hide-powered-by` * 7906601 which imported `frameguard` * d03c555 which imported `expect-ct` * e933c28 which imported `dns-prefetch-control` * 13b496f which imported `ienoopen` [0]: https://github.com/helmetjs/csp
- Loading branch information
Showing
12 changed files
with
687 additions
and
41 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
# Changelog | ||
|
||
## 3.0.0 - Unreleased | ||
|
||
### Added | ||
|
||
- If no `default-src` directive is supplied, an error is thrown | ||
- Directive lists can be any iterable, not just arrays | ||
|
||
### Changed | ||
|
||
- There is now a default set of directives if none are supplied | ||
- Duplicate keys now throw an error | ||
- This middleware is more lenient | ||
|
||
### Removed | ||
|
||
- Removed browser sniffing (including the `browserSniff` parameter) | ||
- Removed conditional support. This includes directive functions and support for a function as the `reportOnly`. [Read this if you need help.](https://github.com/helmetjs/helmet/wiki/Conditionally-using-middleware) | ||
- Removed a lot of checks—you should be checking your CSP with a different tool | ||
- Removed support for legacy headers (and therefore the `setAllHeaders` parameter). [Read this if you need help.](https://github.com/helmetjs/helmet/wiki/Setting-legacy-Content-Security-Policy-headers-in-Helmet-4) | ||
- Dropped support for old Node versions. Node 10+ is now required | ||
- Removed the `loose` option | ||
- Removed the `disableAndroid` option | ||
|
||
## 2.9.5 - 2020-02-22 | ||
|
||
### Changed | ||
|
||
- Updated `bowser` subdependency from 2.7.0 to 2.9.0 | ||
|
||
### Fixed | ||
|
||
- Fixed an issue some people were having when importing the `bowser` subdependency. See [#96](https://github.com/helmetjs/csp/issues/96) and [#101](https://github.com/helmetjs/csp/pull/101) | ||
- Fixed a link in the readme. See [#100](https://github.com/helmetjs/csp/pull/100) | ||
|
||
## 2.9.4 - 2019-10-21 | ||
|
||
### Changed | ||
|
||
- Updated `bowser` subdependency from 2.6.1 to 2.7.0. See [#94](https://github.com/helmetjs/csp/pull/94) | ||
|
||
## 2.9.3 - 2019-09-30 | ||
|
||
### Fixed | ||
|
||
- Published a missing TypeScript type definition file. See [#90](https://github.com/helmetjs/csp/issues/90) | ||
|
||
## 2.9.2 - 2019-09-20 | ||
|
||
### Fixed | ||
|
||
- Fixed a bug where a request from Firefox 4 could delete `default-src` from future responses | ||
- Fixed tablet PC detection by updating `bowser` subdependency to latest version | ||
|
||
## 2.9.1 - 2019-09-04 | ||
|
||
### Changed | ||
|
||
- Updated `bowser` subdependency from 2.5.3 to 2.5.4. See [#88](https://github.com/helmetjs/csp/pull/88) | ||
|
||
### Fixed | ||
|
||
- The "security" keyword was declared twice in package metadata. See [#87](https://github.com/helmetjs/csp/pull/87) | ||
|
||
## 2.9.0 - 2019-08-28 | ||
|
||
### Added | ||
|
||
- Added TypeScript type definitions. See [#86](https://github.com/helmetjs/csp/pull/86) | ||
|
||
### Fixed | ||
|
||
- Switched from `platform` to `bowser` to quiet a security vulnerability warning. See [#80](https://github.com/helmetjs/csp/issues/80) | ||
|
||
## 2.8.0 - 2019-07-24 | ||
|
||
### Added | ||
|
||
- Added a new `sandbox` directive, `allow-downloads-without-user-activation` (see [#85](https://github.com/helmetjs/csp/pull/85)) | ||
- Created a changelog | ||
- Added some package metadata | ||
|
||
### Changed | ||
|
||
- Updated documentation to use ES2015 | ||
- Updated documentation to remove dependency on UUID package | ||
- Updated `content-security-policy-builder` to 2.1.0 | ||
- Excluded some files from the npm package | ||
|
||
Changes in versions 2.7.1 and below can be found in [Helmet's changelog](https://github.com/helmetjs/helmet/blob/master/CHANGELOG.md). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
# Content Security Policy middleware | ||
|
||
Content Security Policy helps prevent unwanted content being injected into your webpages. This can mitigate cross-site scripting (XSS) vulnerabilities, malicious frames, unwanted trackers, and much more. | ||
|
||
If you want to learn how CSP works, check out the fantastic [HTML5 Rocks guide](http://www.html5rocks.com/en/tutorials/security/content-security-policy/), the [Content Security Policy Reference](http://content-security-policy.com/), and the [Content Security Policy specification](http://www.w3.org/TR/CSP/). | ||
|
||
This middleware helps set Content Security Policies. | ||
|
||
Basic usage: | ||
|
||
```javascript | ||
const csp = require("helmet-csp"); | ||
|
||
app.use( | ||
csp({ | ||
directives: { | ||
defaultSrc: ["'self'", "default.example"], | ||
scriptSrc: ["'self'", "'unsafe-inline'"], | ||
objectSrc: ["'none'"], | ||
upgradeInsecureRequests: [], | ||
}, | ||
reportOnly: false, | ||
}) | ||
); | ||
``` | ||
|
||
You can set any directives you wish. `defaultSrc` is required. Directives can be kebab-cased (like `script-src`) or camel-cased (like `scriptSrc`). They are equivalent, but duplicates are not allowed. | ||
|
||
The `reportOnly` option, if set to `true`, sets the `Content-Security-Policy-Report-Only` header instead. | ||
|
||
This middleware does minimal validation. You should use a more sophisticated CSP validator, like [Google's CSP Evaluator](https://csp-evaluator.withgoogle.com/), to make sure your CSP looks good. | ||
|
||
## Recipe: generating nonces | ||
|
||
You can dynamically generate nonces to allow inline `<script>` tags to be safely evaluated. Here's a simple example: | ||
|
||
```js | ||
const crypto = require("crypto"); | ||
|
||
app.use((req, res, next) { | ||
res.locals.nonce = crypto.randomBytes(16).toString("hex"); | ||
next(); | ||
}); | ||
|
||
app.use((req, res, next) => { | ||
csp({ | ||
directives: { | ||
defaultSrc: ["'self'"], | ||
scriptSrc: ["'self'", `'nonce-${res.locals.nonce}'`], | ||
}, | ||
})(req, res, next); | ||
}); | ||
|
||
app.use((req, res) => { | ||
res.end(`<script nonce="${res.locals.nonce}">alert(1 + 1);</script>`); | ||
}); | ||
``` | ||
|
||
## See also | ||
|
||
- [Google's CSP Evaluator tool](https://csp-evaluator.withgoogle.com/) | ||
- [GitHub's CSP journey](http://githubengineering.com/githubs-csp-journey/) | ||
- [Content Security Policy for Single Page Web Apps](https://developer.squareup.com/blog/content-security-policy-for-single-page-web-apps/) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
import { IncomingMessage, ServerResponse } from "http"; | ||
|
||
export interface ContentSecurityPolicyOptions { | ||
directives?: { | ||
[directiveName: string]: Iterable<string>; | ||
}; | ||
reportOnly?: boolean; | ||
} | ||
|
||
const isRawPolicyDirectiveNameInvalid = (rawDirectiveName: string): boolean => | ||
rawDirectiveName.length === 0 || /[^a-zA-Z0-9-]/.test(rawDirectiveName); | ||
|
||
const dashify = (str: string): string => | ||
str.replace(/[A-Z]/g, (capitalLetter) => "-" + capitalLetter.toLowerCase()); | ||
|
||
function getHeaderNameFromOptions({ | ||
reportOnly, | ||
}: ContentSecurityPolicyOptions): string { | ||
if (reportOnly) { | ||
return "Content-Security-Policy-Report-Only"; | ||
} else { | ||
return "Content-Security-Policy"; | ||
} | ||
} | ||
|
||
function getHeaderValueFromOptions( | ||
options: ContentSecurityPolicyOptions | ||
): string { | ||
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 { | ||
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": [], | ||
}, | ||
} = options; | ||
|
||
const directiveNamesUsed = new Set<string>(); | ||
|
||
const result = Object.entries(directives) | ||
.map(([rawDirectiveName, rawDirectiveValue]) => { | ||
if (isRawPolicyDirectiveNameInvalid(rawDirectiveName)) { | ||
throw new Error( | ||
`Content-Security-Policy received an invalid directive name ${JSON.stringify( | ||
rawDirectiveName | ||
)}` | ||
); | ||
} | ||
const directiveName = dashify(rawDirectiveName); | ||
if (directiveNamesUsed.has(directiveName)) { | ||
throw new Error( | ||
`Content-Security-Policy received a duplicate directive ${JSON.stringify( | ||
directiveName | ||
)}` | ||
); | ||
} | ||
directiveNamesUsed.add(directiveName); | ||
|
||
let directiveValue: string; | ||
if (typeof rawDirectiveValue === "string") { | ||
directiveValue = " " + rawDirectiveValue; | ||
} else { | ||
directiveValue = ""; | ||
for (const element of rawDirectiveValue) { | ||
directiveValue += " " + element; | ||
} | ||
} | ||
|
||
if (!directiveValue) { | ||
return directiveName; | ||
} | ||
|
||
if (/;|,/.test(directiveValue)) { | ||
throw new Error( | ||
`Content-Security-Policy received an invalid directive value for ${JSON.stringify( | ||
directiveName | ||
)}` | ||
); | ||
} | ||
|
||
return `${directiveName}${directiveValue}`; | ||
}) | ||
.join(";"); | ||
|
||
if (!directiveNamesUsed.has("default-src")) { | ||
throw new Error( | ||
"Content-Security-Policy needs a default-src but none was provided" | ||
); | ||
} | ||
|
||
return result; | ||
} | ||
|
||
function contentSecurityPolicy( | ||
options: Readonly<ContentSecurityPolicyOptions> = {} | ||
) { | ||
const headerName = getHeaderNameFromOptions(options); | ||
const headerValue = getHeaderValueFromOptions(options); | ||
|
||
return function contentSecurityPolicyMiddleware( | ||
_req: IncomingMessage, | ||
res: ServerResponse, | ||
next: () => void | ||
) { | ||
res.setHeader(headerName, headerValue); | ||
next(); | ||
}; | ||
} | ||
|
||
module.exports = contentSecurityPolicy; | ||
export default contentSecurityPolicy; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
["index.js", "index.d.ts"] |
12 changes: 12 additions & 0 deletions
12
middlewares/content-security-policy/package-overrides.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
{ | ||
"name": "helmet-csp", | ||
"author": "Adam Baldwin <[email protected]> (https://evilpacket.net)", | ||
"contributors": [ | ||
"Evan Hahn <[email protected]> (https://evanhahn.com)", | ||
"Ryan Cannon <[email protected]> (https://ryancannon.com)" | ||
], | ||
"description": "Content Security Policy middleware", | ||
"version": "2.9.5", | ||
"keywords": ["express", "security", "content-security-policy", "csp", "xss"], | ||
"homepage": "https://helmetjs.github.io/docs/csp/" | ||
} |
Oops, something went wrong.