Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release v6 #370

Merged
merged 6 commits into from Aug 26, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/nodejs.yml
Expand Up @@ -11,7 +11,7 @@ jobs:

strategy:
matrix:
node-version: [12.x, 14.x, 16.x, 18.x]
node-version: [14.x, 16.x, 18.x]

steps:
- uses: actions/checkout@v3
Expand Down
14 changes: 14 additions & 0 deletions CHANGELOG.md
@@ -1,5 +1,19 @@
# Changelog

## Unreleased

### Changed

- **Breaking:** Where possible, increase TypeScript strictness around some strings. Only affects TypeScript users. See [#369](https://github.com/helmetjs/helmet/issues/369)
- **Breaking:** `helmet.contentSecurityPolicy` no longer sets `block-all-mixed-content` directive by default
- **Breaking:** `helmet.expectCt` is no longer set by default. It can, however, be explicitly enabled. It will be removed in Helmet 7. See [#310](https://github.com/helmetjs/helmet/issues/310)
- **Breaking:** Increase TypeScript strictness around some arguments. Only affects TypeScript users, and may not require any code changes. See [#369](https://github.com/helmetjs/helmet/issues/369)
- `helmet.frameguard` no longer offers a specific error when trying to use `ALLOW-FROM`; it just says that it is unsupported. Only the error message has changed

### Removed

- **Breaking:** Dropped support for Node 12 and 13. Node 14+ is now required

## 5.1.1 - 2022-07-23

### Changed
Expand Down
8 changes: 4 additions & 4 deletions README.md
Expand Up @@ -33,11 +33,10 @@ app.use(helmet());
By default, Helmet sets the following headers:

```http
Content-Security-Policy: default-src 'self';base-uri 'self';block-all-mixed-content;font-src 'self' https: data:;form-action 'self';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
Content-Security-Policy: default-src 'self';base-uri 'self';font-src 'self' https: data:;form-action 'self';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
Cross-Origin-Embedder-Policy: require-corp
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Resource-Policy: same-origin
Expect-CT: max-age=0
Origin-Agent-Cluster: ?1
Referrer-Policy: no-referrer
Strict-Transport-Security: max-age=15552000; includeSubDomains
Expand Down Expand Up @@ -155,7 +154,7 @@ Each middleware's name is listed below.
Default:

```http
Content-Security-Policy: default-src 'self';base-uri 'self';block-all-mixed-content;font-src 'self' https: data:;form-action 'self';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
Content-Security-Policy: default-src 'self';base-uri 'self';font-src 'self' https: data:;form-action 'self';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
```

`helmet.contentSecurityPolicy` sets the `Content-Security-Policy` header which helps mitigate cross-site scripting attacks, among other things. See [MDN's introductory article on Content Security Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP).
Expand All @@ -168,7 +167,6 @@ These directives are merged into a default policy, which you can disable by sett

default-src 'self';
base-uri 'self';
block-all-mixed-content;
font-src 'self' https: data:;
form-action 'self';
frame-ancestors 'self';
Expand Down Expand Up @@ -374,6 +372,8 @@ Expect-CT: max-age=0

`helmet.expectCt` sets the `Expect-CT` header which helps mitigate misissued SSL certificates. See [MDN's article on Certificate Transparency](https://developer.mozilla.org/en-US/docs/Web/Security/Certificate_Transparency) and the [`Expect-CT` header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Expect-CT) for more.

`Expect-CT` is no longer useful for new browsers in 2022. Therefore, `helmet.expectCt` is deprecated and will be removed in the next major version of Helmet. However, it can still be used in this version of Helmet.

`options.maxAge` is the number of seconds to expect Certificate Transparency. It defaults to `0`.

`options.enforce` is a boolean. If `true`, the user agent (usually a browser) should refuse future connections that violate its Certificate Transparency policy. Defaults to `false`.
Expand Down
2 changes: 1 addition & 1 deletion bin/build-middleware-package.js
Expand Up @@ -46,7 +46,7 @@ async function main(argv) {
url: "git://github.com/helmetjs/helmet.git",
},
engines: {
node: ">=12.0.0",
node: ">=14.0.0",
},
files: ["CHANGELOG.md", "LICENSE", "README.md", "index.js", "index.d.ts"],
main: "index.js",
Expand Down
2 changes: 1 addition & 1 deletion index.ts
Expand Up @@ -147,7 +147,7 @@ function getMiddlewareFunctionsFromOptions(
result.push(xDnsPrefetchControl(...xDnsPrefetchControlArgs));
}

const expectCtArgs = getArgs(options.expectCt);
const expectCtArgs = options.expectCt && getArgs(options.expectCt);
if (expectCtArgs) {
result.push(expectCt(...expectCtArgs));
}
Expand Down
3 changes: 2 additions & 1 deletion middlewares/content-security-policy/CHANGELOG.md
Expand Up @@ -6,10 +6,11 @@

- **Breaking:** `useDefaults` option now defaults to `true`
- **Breaking:** `form-action` directive is now set to `'self'` by default
- **Breaking:** `block-all-mixed-content` is no longer set by default

### Removed

- **Breaking:** Drop support for Node 10 and 11. Node 12+ is now required
- **Breaking:** Node 14+ is now required

## 3.4.0 - 2021-05-02

Expand Down
1 change: 0 additions & 1 deletion middlewares/content-security-policy/README.md
Expand Up @@ -29,7 +29,6 @@ If no directives are supplied, the following policy is set (whitespace added for

default-src 'self';
base-uri 'self';
block-all-mixed-content;
font-src 'self' https: data:;
form-action 'self';
frame-ancestors 'self';
Expand Down
1 change: 0 additions & 1 deletion middlewares/content-security-policy/index.ts
Expand Up @@ -42,7 +42,6 @@ const DEFAULT_DIRECTIVES: Record<
> = {
"default-src": ["'self'"],
"base-uri": ["'self'"],
"block-all-mixed-content": [],
"font-src": ["'self'", "https:", "data:"],
"form-action": ["'self'"],
"frame-ancestors": ["'self'"],
Expand Down
2 changes: 1 addition & 1 deletion middlewares/cross-origin-embedder-policy/index.ts
@@ -1,7 +1,7 @@
import { IncomingMessage, ServerResponse } from "http";

export interface CrossOriginEmbedderPolicyOptions {
policy?: string;
policy?: "require-corp" | "credentialless";
}

const ALLOWED_POLICIES = new Set(["require-corp", "credentialless"]);
Expand Down
2 changes: 1 addition & 1 deletion middlewares/cross-origin-opener-policy/index.ts
@@ -1,7 +1,7 @@
import { IncomingMessage, ServerResponse } from "http";

export interface CrossOriginOpenerPolicyOptions {
policy?: string;
policy?: "same-origin" | "same-origin-allow-popups" | "unsafe-none";
}

const ALLOWED_POLICIES = new Set([
Expand Down
6 changes: 6 additions & 0 deletions middlewares/cross-origin-resource-policy/CHANGELOG.md
@@ -1,5 +1,11 @@
# Changelog

## Unreleased

### Changed

- **Breaking:** increase TypeScript strictness around arguments. Only affects TypeScript users. See [helmetjs/helmet#369](https://github.com/helmetjs/helmet/issues/369)

## 0.3.0 - 2021-04-17

### Added
Expand Down
2 changes: 1 addition & 1 deletion middlewares/cross-origin-resource-policy/index.ts
@@ -1,7 +1,7 @@
import { IncomingMessage, ServerResponse } from "http";

export interface CrossOriginResourcePolicyOptions {
policy?: string;
policy?: "same-origin" | "same-site" | "cross-origin";
}

const ALLOWED_POLICIES = new Set(["same-origin", "same-site", "cross-origin"]);
Expand Down
8 changes: 7 additions & 1 deletion middlewares/referrer-policy/CHANGELOG.md
@@ -1,10 +1,16 @@
# Changelog

## Unreleased

### Changed

- **Breaking:** increase TypeScript strictness around arguments. Only affects TypeScript users. See [helmetjs/helmet#369](https://github.com/helmetjs/helmet/issues/369)

## 2.0.0 - Unreleased

### Removed

- Dropped support for old Node versions. Node 10+ is now required
- **Breaking:** Dropped support for old Node versions. Node 10+ is now required

## 1.2.0 - 2019-05-03

Expand Down
17 changes: 14 additions & 3 deletions middlewares/referrer-policy/index.ts
@@ -1,10 +1,21 @@
import { IncomingMessage, ServerResponse } from "http";

type ReferrerPolicyToken =
| "no-referrer"
| "no-referrer-when-downgrade"
| "same-origin"
| "origin"
| "strict-origin"
| "origin-when-cross-origin"
| "strict-origin-when-cross-origin"
| "unsafe-url"
| "";

export interface ReferrerPolicyOptions {
policy?: string | string[];
policy?: ReferrerPolicyToken | ReferrerPolicyToken[];
}

const ALLOWED_TOKENS = new Set<string>([
const ALLOWED_TOKENS = new Set<ReferrerPolicyToken>([
"no-referrer",
"no-referrer-when-downgrade",
"same-origin",
Expand All @@ -25,7 +36,7 @@ function getHeaderValueFromOptions({
throw new Error("Referrer-Policy received no policy tokens");
}

const tokensSeen = new Set<string>();
const tokensSeen = new Set<ReferrerPolicyToken>();
tokens.forEach((token) => {
if (!ALLOWED_TOKENS.has(token)) {
throw new Error(
Expand Down
3 changes: 2 additions & 1 deletion middlewares/x-frame-options/CHANGELOG.md
Expand Up @@ -4,7 +4,8 @@

### Changed

- Add TypeScript editor autocomplete. See [#322](https://github.com/helmetjs/helmet/pull/322)
- **Breaking:** increase TypeScript strictness around arguments. Only affects TypeScript users. See [helmetjs/helmet#369](https://github.com/helmetjs/helmet/issues/369)
- No longer offer a specific error when trying to use `ALLOW-FROM`; it just says that it is unsupported. Only the error message has changed

## 4.0.0 - 2020-12-21

Expand Down
9 changes: 2 additions & 7 deletions middlewares/x-frame-options/index.ts
@@ -1,12 +1,11 @@
import { IncomingMessage, ServerResponse } from "http";

export interface XFrameOptionsOptions {
// This offers autocomplete while still supporting regular `string`s.
action?: "DENY" | "SAMEORIGIN" | (string & { _?: never });
action?: "deny" | "sameorigin";
}

function getHeaderValueFromOptions({
action = "SAMEORIGIN",
action = "sameorigin",
}: Readonly<XFrameOptionsOptions>): string {
const normalizedAction =
typeof action === "string" ? action.toUpperCase() : action;
Expand All @@ -17,10 +16,6 @@ function getHeaderValueFromOptions({
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)}`
Expand Down
6 changes: 5 additions & 1 deletion middlewares/x-permitted-cross-domain-policies/CHANGELOG.md
Expand Up @@ -2,9 +2,13 @@

## Unreleased

### Changed

- **Breaking:** increase TypeScript strictness around arguments. Only affects TypeScript users. See [helmetjs/helmet#369](https://github.com/helmetjs/helmet/issues/369)

### Removed

- Dropped support for old Node versions. Node 10+ is now required
- Dropped support for old Node versions. Node 14+ is now required

## 0.5.0 - 2019-09-01

Expand Down
2 changes: 1 addition & 1 deletion middlewares/x-permitted-cross-domain-policies/index.ts
@@ -1,7 +1,7 @@
import { IncomingMessage, ServerResponse } from "http";

export interface XPermittedCrossDomainPoliciesOptions {
permittedPolicies?: string;
permittedPolicies?: "none" | "master-only" | "by-content-type" | "all";
}

const ALLOWED_PERMITTED_POLICIES = new Set([
Expand Down
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Expand Up @@ -23,7 +23,7 @@
"url": "git://github.com/helmetjs/helmet.git"
},
"engines": {
"node": ">=12.0.0"
"node": ">=14.0.0"
},
"devDependencies": {
"@rollup/plugin-typescript": "^8.3.3",
Expand Down
4 changes: 0 additions & 4 deletions test/content-security-policy.test.ts
Expand Up @@ -31,7 +31,6 @@ describe("Content-Security-Policy middleware", () => {
const expectedDirectives = new Set([
"default-src 'self'",
"base-uri 'self'",
"block-all-mixed-content",
"font-src 'self' https: data:",
"form-action 'self'",
"frame-ancestors 'self'",
Expand Down Expand Up @@ -225,7 +224,6 @@ describe("Content-Security-Policy middleware", () => {
it("can override the default options", async () => {
const expectedDirectives = new Set([
"default-src 'self' example.com",
"block-all-mixed-content",
"font-src 'self' https: data:",
"form-action 'self'",
"frame-ancestors 'self'",
Expand Down Expand Up @@ -481,7 +479,6 @@ describe("Content-Security-Policy middleware", () => {
],
expectedDirectives: new Set([
"base-uri 'self'",
"block-all-mixed-content",
"font-src 'self' https: data:",
"form-action 'self'",
"frame-ancestors 'self'",
Expand Down Expand Up @@ -537,7 +534,6 @@ describe("getDefaultDirectives", () => {
it("returns the middleware's default directives", () => {
expect(getDefaultDirectives()).toEqual({
"base-uri": ["'self'"],
"block-all-mixed-content": [],
"default-src": ["'self'"],
"font-src": ["'self'", "https:", "data:"],
"form-action": ["'self'"],
Expand Down
2 changes: 1 addition & 1 deletion test/cross-origin-embedder-policy.test.ts
Expand Up @@ -18,7 +18,7 @@ describe("Cross-Origin-Embedder-Policy middleware", () => {
);
});

["require-corp", "credentialless"].forEach((policy) => {
(["require-corp", "credentialless"] as const).forEach((policy) => {
it(`sets "Cross-Origin-Embedder-Policy: ${policy}" when told to`, async () => {
await check(crossOriginEmbedderPolicy({ policy }), {
"cross-origin-embedder-policy": policy,
Expand Down
2 changes: 1 addition & 1 deletion test/cross-origin-opener-policy.test.ts
Expand Up @@ -15,7 +15,7 @@ describe("Cross-Origin-Opener-Policy middleware", () => {
);
});

["same-origin", "same-origin-allow-popups", "unsafe-none"].forEach(
(["same-origin", "same-origin-allow-popups", "unsafe-none"] as const).forEach(
(policy) => {
it(`sets "Cross-Origin-Opener-Policy: ${policy}" when told to`, async () => {
await check(crossOriginOpenerPolicy({ policy }), {
Expand Down
2 changes: 1 addition & 1 deletion test/cross-origin-resource-policy.test.ts
Expand Up @@ -18,7 +18,7 @@ describe("Cross-Origin-Resource-Policy middleware", () => {
);
});

["same-origin", "same-site", "cross-origin"].forEach((policy) => {
(["same-origin", "same-site", "cross-origin"] as const).forEach((policy) => {
it(`sets "Cross-Origin-Resource-Policy: ${policy}" when told to`, async () => {
await check(crossOriginResourcePolicy({ policy }), {
"cross-origin-resource-policy": policy,
Expand Down
17 changes: 14 additions & 3 deletions test/index.test.ts
Expand Up @@ -24,17 +24,18 @@ import xXssProtection from "../middlewares/x-xss-protection";
describe("helmet", () => {
const topLevel = helmet.default;

it("includes all middleware with their default options", async () => {
it("includes all middleware, except Expect-CT, with their default options", async () => {
// NOTE: This test relies on the CSP object being ordered a certain way,
// which could change (and be non-breaking). If that becomes a problem,
// we should update this test to be more robust.
const expectedHeaders = {
"content-security-policy":
"default-src 'self';base-uri 'self';block-all-mixed-content;font-src 'self' https: data:;form-action 'self';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",
"default-src 'self';base-uri 'self';font-src 'self' https: data:;form-action 'self';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",
"cross-origin-embedder-policy": "require-corp",
"cross-origin-opener-policy": "same-origin",
"cross-origin-resource-policy": "same-origin",
"expect-ct": "max-age=0",
// In Helmet 7, we can remove this Expect-CT assertion.
"expect-ct": null,
"origin-agent-cluster": "?1",
"referrer-policy": "no-referrer",
"strict-transport-security": "max-age=15552000; includeSubDomains",
Expand All @@ -61,6 +62,16 @@ describe("helmet", () => {
});
});

// In Helmet 7, this test should be removed.
it("allows Expect-CT to be enabled", async () => {
await check(topLevel({ expectCt: true }), {
"expect-ct": "max-age=0",
});
await check(topLevel({ expectCt: { maxAge: 123 } }), {
"expect-ct": "max-age=123",
});
});

it("works with all default middlewares disabled", async () => {
await check(
topLevel({
Expand Down