Giter Site home page Giter Site logo

next-secure-headers's Introduction

next-secure-headers

โ›‘๏ธ Sets secure response headers for Next.js. ๐ŸŒป

// /next.config.js

module.exports = {
  async headers() {
    return [{
      source: "/(.*)",
      headers: createSecureHeaders({
        contentSecurityPolicy: {
          directives: {
            defaultSrc: "'self'",
            styleSrc: ["'self'", "https://stackpath.bootstrapcdn.com"],
          },
        },
        forceHTTPSRedirect: [true, { maxAge: 60 * 60 * 24 * 4, includeSubDomains: true }],
        referrerPolicy: "same-origin",
      })
    }];
  },
};
npm GitHub Actions license @jagaapple_tech

Table of Contents

Features

FEATURES WHAT YOU CAN DO
โš›๏ธ Designed for Next.js Use for next.config.js or page components in /pages
โœจ Default applied rules Help your project even if you don't have knowledge
๐ŸŽฉ Type Safe You can use with TypeScript

Why use next-secure-headers instead of Helmet?

next-secure-headers is a similar to Helmet, which sets HTTP response headers related to security for Express.js.

Next.js supports to be used in Node.js frameworks such as Express.js. So you can use Helmet with your Next.js project if you create a custom server, but the Next.js development team does not recommend a custom server. Also, they are working to implement in order to be possible to use Next.js without a custom server. In fact, Next.js 9 supports Dynamic Routing, so we don't need to build a custom server in order to implement it using such as next-routes, which requires a custom server.

// /next.config.js
const { createSecureHeaders } = require("next-secure-headers");

module.exports = {
  async headers() {
    return [{ source: "/(.*)", headers: createSecureHeaders() }];
  },
};

If you want to use Helmet, it requires to use a custom server against a recommended way. To solve this problem, next-secure-headers was born. next-secure-headers is built for Next.js project so that you can specify any headers in next.config.js or page components.

next-secure-headers vs Helmet

The following are rules next-secure-headers has and Helmet has. next-secure-headers is inspired by Helmet, but it doesn't have some rules for some reason.

next-secure-headers Helmet Comment
Strict-Transport-Security forceHTTPSRedirect hsts
X-Frame-Options frameGuard frameguard
X-Download-Options noopen ieNoOpen
X-Content-Type-Options nosniff noSniff
X-XSS-Protection xssProtection xssFilter
Content-Security-Policy contentSecurityPolicy contentSecurityPolicy
Expect-CT expectCT expectCt
Referrer-Policy referrerPolicy referrerPolicy
X-DNS-Prefetch-Control - dnsPrefetchControl This has privacy implications but this improves performance.
Feature-Policy - featurePolicy Feature Policy improves security but it is working draft yet.
X-Powered-By - hidePoweredBy Next.js supports to remove this header in next.config.js.
Related to cache - nocache As Helmet said, caching has lots of benefits.
X-Permitted-Cross-Domain-Policies - crossdomain Adobe Flash is one of old web technologies.

Quick Start

Requirements

  • npm or Yarn
  • Node.js 10.0.0 or higher
  • Next.js 8.0.0 or higher

Installation

$ npm install -D next-secure-headers

If you are using Yarn, use the following command.

$ yarn add -D next-secure-headers

โ—๏ธ For withSecureHeaders . If you want to use withSecureHeaders , you have to install without -D option (i.e., installing as dependencies not devDependencies ).

Setup

There are two ways to specify headers. One is to use createSecureHeaders in next.config.js , and another is to use withSecureHeaders in page components.

Use createSecureHeaders in next.config.js (RECOMMENDED)

โ—๏ธ Next.js 9.5 or higher is required. headers function has been supported since Next.js 9.5, so you have to use Next.js 9.5 or higher if you want to use this way.

๐Ÿค” For Next.js 10 and I18n routes. If your project uses Next.js 10 and built-in I18n routes, and you want to apply rules for all pages, you have to specify "/:path*" to source property instead of "/(.*)" . Conversely, if your project doesn't use I18n routes even if using Next.js 10, you have to specify "/(.*)" instead. These limitations are maybe bugs in Next.js .

This way uses createSecureHeaders function and a built-in header configuration way by Next.js. This is not required any servers, can be used in static pages, and can retain Automatic Static Optimization. If your project does not use any servers (using static pages or SSG) or you have just created a Next.js project, I recommend retaining static pages and adopting this way.

Import createSecureHeaders from next-secure-headers and use it in headers async function in next.config.js .

// /next.config.js
const { createSecureHeaders } = require("next-secure-headers");

module.exports = {
  async headers() {
    return [{ source: "/(.*)", headers: createSecureHeaders() }];
  },
};

By default, next-secure-headers applies some rules. If you want to enable or disable rules, you can give options to the first argument of the function.

module.exports = {
  async headers() {
    return [{
      source: "/(.*)",
      headers: createSecureHeaders({
        contentSecurityPolicy: {
          directives: {
            defaultSrc: "'self'",
            styleSrc: ["'self'", "https://stackpath.bootstrapcdn.com"],
          },
        },
        forceHTTPSRedirect: [true, { maxAge: 60 * 60 * 24 * 4, includeSubDomains: true }],
        referrerPolicy: "same-origin",
      }),
    }];
  },
};

Also, you can configure different headers by URLs following the official documents.

Use withSecureHeaders in page components

โ—๏ธ Servers are required. This way requires any servers because withSecureHeaders uses getServerSideProps of Next.js.

Use an exported function for your Next.js application in /pages/_app.tsx . Also, you can use in any page components in /pages/xxx.tsx instead.

// /pages/_app.tsx
import { withSecureHeaders } from "next-secure-headers";

class Application extends App {
  ...
}

export default withSecureHeaders()(Application);

By default, next-secure-headers applies some rules. If you want to enable or disable rules, you can give options to the first argument of the function.

export default withSecureHeaders({
  contentSecurityPolicy: {
    directives: {
      defaultSrc: "'self'",
      styleSrc: ["'self'", "https://stackpath.bootstrapcdn.com"],
    },
  },
  forceHTTPSRedirect: [true, { maxAge: 60 * 60 * 24 * 4, includeSubDomains: true }],
  referrerPolicy: "same-origin",
})(Application);

Rules

forceHTTPSRedirect

{
  forceHTTPSRedirect: boolean | [true, Partial<{ maxAge: number; includeSubDomains: boolean; preload: boolean }>];
}
Default Value MDN
[true, { maxAge: 63072000 }] https://developer.mozilla.org/docs/Web/HTTP/Headers/Strict-Transport-Security

This is to set "Strict-Transport-Security (HSTS)" header and it's to prevent man-in-the-middle attacks during redirects from HTTP to HTTPS. To enable this is highly recommended if you use HTTPS (SSL) on your servers.

You can give true if you want to enable this rule, or you can specify options by giving [true, OPTION_OBJECT] . By default, this sets max-age to two years (63,072,000 seconds).

frameGuard

{
  frameGuard: false | "deny" | "sameorigin" | ["allow-from", { uri: string | URL }];
}
Default Value MDN
"deny" https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Frame-Options

This is to set "X-Frame-Options" header and it's to prevent clickjacking attacks. "deny" is highly recommended if you don't use frame elements such as iframe .

noopen

{
  noopen: false | "noopen";
}
Default Value MDN
"noopen" https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Download-Options

This is to set "X-Download-Options" header and it's to prevent to open downloaded files automatically for IE8+ (MIME Handling attacks).

nosniff

{
  nosniff: false | "nosniff";
}
Default Value MDN
"nosniff" https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Content-Type-Options

This is to set "X-Content-Type-Options" header and it's to prevent MIME Sniffing attacks.

xssProtection

{
  xssProtection: false | "sanitize" | "block-rendering" | ["report", { uri: string | URL }];
}
Default Value MDN
"sanitize" https://developer.mozilla.org/docs/Web/HTTP/Headers/X-XSS-Protection

This is to set "X-XSS-Protection" header and it's to prevent XSS attacks.

If you specify "sanitize" , this sets the header to "1" and browsers will sanitize unsafe area. If you specify "block-rendering" , this sets the header to "1; mode=block" and browsers will block rendering a page. "X-XSS-Protection" blocks many XSS attacks, but Content Security Policy is recommended to use compared to this.

contentSecurityPolicy

{
  contentSecurityPolicy:
    | false
    | {
        directives:
          & Partial<{
            childSrc: string | string[];
            connectSrc: string | string[];
            defaultSrc: string | string[];
            fontSrc: string | string[];
            frameSrc: string | string[];
            imgSrc: string | string[];
            manifestSrc: string | string[];
            mediaSrc: string | string[];
            prefetchSrc: string | string[];
            objectSrc: string | string[];
            scriptSrc: string | string[];
            scriptSrcElem: string | string[];
            scriptSrcAttr: string | string[];
            styleSrc: string | string[];
            styleSrcElem: string | string[];
            styleSrcAttr: string | string[];
            workerSrc: string | string[];
          }>
          & Partial<{
            baseURI: string | string[];
            pluginTypes: string | string[];
            sandbox:
              | true
              | "allow-downloads-without-user-activation"
              | "allow-forms"
              | "allow-modals"
              | "allow-orientation-lock"
              | "allow-pointer-lock"
              | "allow-popups"
              | "allow-popups-to-escape-sandbox"
              | "allow-presentation"
              | "allow-same-origin"
              | "allow-scripts"
              | "allow-storage-access-by-user-activation"
              | "allow-top-navigation"
              | "allow-top-navigation-by-user-activation";
          }>
          & Partial<{
            formAction: string | string[];
            frameAncestors: string | string[];
            navigateTo: string | string[];
            reportURI: string | URL | (string | URL)[];
            reportTo: string;
          }>;
        reportOnly?: boolean;
      };
}
Default Value MDN
false https://developer.mozilla.org/docs/Web/HTTP/Headers/Content-Security-Policy

This is to set "Content-Security-Policy" or "Content-Security-Policy-Report-Only" header and it's to prevent to load and execute non-allowed resources.

If you give true to reportOnly , this sets "Content-Security-Policy-Report-Only" to value instead of "Content-Security-Policy".

Also you can specify directives using chain-case names such as child-src instead of childSrc .

โ—๏ธ When setting frameAncestors :X-Frame-Options takes priority. Section "Relation to X-Frame-Options" of the CSP Spec says: "If a resource is delivered with a policy that includes a directive named frame-ancestors and whose disposition is "enforce", then the X-Frame-Options header MUST be ignored", but Chrome 40 & Firefox 35 ignore the frame-ancestors directive and follow the X-Frame-Options header instead.

Therefore, if setting frameAncestors you should set frameGuard to false.

expectCT

{
  expectCT: boolean | [true, Partial<{ maxAge: number; enforce: boolean; reportURI: string | URL }>];
}
Default Value MDN
false https://developer.mozilla.org/docs/Web/HTTP/Headers/Expect-CT

This is to set "Expect-CT" header and it's to tell browsers to expect Certificate Transparency.

referrerPolicy

{
  referrerPolicy:
    | false
    | "no-referrer" | "no-referrer-when-downgrade" | "origin" | "origin-when-cross-origin" | "same-origin" | "strict-origin" | "strict-origin-when-cross-origin"
    | ("no-referrer" | "no-referrer-when-downgrade" | "origin" | "origin-when-cross-origin" | "same-origin" | "strict-origin" | "strict-origin-when-cross-origin")[];
}
Default Value MDN
false https://developer.mozilla.org/docs/Web/HTTP/Headers/Referrer-Policy

This is to set "Referrer-Policy" header and it's to prevent to be got referrer by other servers. You can specify one or more values for legacy browsers which does not support a specific value.

API

createSecureHeaders

import { createSecureHeaders } from "next-secure-headers";

createSecureHeaders({ referrerPolicy: "same-origin" });
// [
//   {
//     key: "Referrer-Policy",
//     value: "same-origin",
//   },
// ]

createSecureHeaders is a function to return headers as object following a format like { key, value } .

createSecureHeaders(OPTIONS);

The first argument accepts options for rules.

withSecureHeaders

import { withSecureHeaders } from "next-secure-headers";

export default withSecureHeaders({ referrerPolicy: "same-origin" })(Page);

withSecureHeaders is a HOC to specify headers using getServerSideProps . You can use this function for application ( /pages/_app.tsx ) and page components ( /pages/xxx.tsx ). THIS IS NOT AVAILBLE IN next.config.js .

withSecureHeaders(OPTIONS)(APPLICATION_OR_COMPONENT);

The first argument accepts options for rules, and the argument of the returned function accepts application or page components. The returned value is a new React component.

createHeadersObject

import { createHeadersObject } from "next-secure-headers";

createHeadersObject({ referrerPolicy: "same-origin" });
// {
//   "Referrer-Policy": "same-origin",
// }

createHeadersObject is a function to return headers as object.

createHeadersObject(OPTIONS);

The first argument accepts options for rules.

Recipes

How to remove X-Powered-By header

In general, X-Powered-By HTTP response header should be removed from response headers because it helps hackers to get the server information.

next-secure-headers does not support to remove X-Powered-By header, but Next.js supports to do.

// next.config.js
module.exports = {
  poweredByHeader: false,
};

If you give false to poweredByHeader in next.config.js , Next.js removes the header from response headers.

Overrides headers in a specific page using withSecureHeaders

// /pages/_app.tsx
export default withSecureHeaders({ referrerPolicy: "same-origin" })(Application);

// /pages/about.tsx
export default withSecureHeaders({ referrerPolicy: "no-referrer-when-downgrade" })(Page);
// But actually the server responds "same-origin"...

next-secure-headers does not support to override response headers in child page components because of being restricted by Next.js architecture.

// /config/secure-headers.ts
import { withSecureHeaders } from "next-secure-headers";

export const secureHeadersDefaultOption: Parameters<typeof withSecureHeaders>[0] = {
  referrerPolicy: "same-origin",
};

// /pages/_app.tsx
import { secureHeadersDefaultOption } from "../config/secure-headers";

export default withSecureHeaders(secureHeadersDefaultOption)(Application);

// /pages/about.tsx
export default withSecureHeaders({
  ...secureHeadersDefaultOption,
  referrerPolicy: "no-referrer-when-downgrade",
})(Page);

To solve this, you should define the option as one module, then you should import and merge the object.

Contributing to next-secure-headers

Bug reports and pull requests are welcome on GitHub at https://github.com/jagaapple/next-secure-headers. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the Contributor Covenant code of conduct.

Please read Contributing Guidelines before development and contributing.

License

The library is available as open source under the terms of the MIT License.

Copyright 2020 Jaga Apple. All rights reserved.

next-secure-headers's People

Contributors

jagaapple avatar mattdell avatar naotone avatar samantha-wong avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

next-secure-headers's Issues

Support for setting dynamic frameAncestors URLs

Hi,

I need to set frameAncestors to different URLs depending on the current URL.
I have not been able to do that with next.config.js or withSecureHeaders, although I might be missing something?

Thanks,
-Louise

Add support for Next.js 9.5 and static pages

Vercel has introduced Next.js v9.5, and it supports to configure custom response headers in Next.js ( next.config.js ) for servers and static pages. I think next-secure-headers can supports static pages without getInitialProps and getServerSideProps , also it is possible to enable Automatic Static Optimization (#11).

https://nextjs.org/blog/next-9-5

These changes require breaking changes, so that I'll release them as v2, and it is not backward-compatible with v1.x.

Feature/Permission policy

๐ŸŒฑ Feature Request

Is your feature request related to a problem? Please describe.

Currently the package doesn't support the Feature-Policy header, nor the Permission-Policy header.
Although the headers are still in draft stage, most browsers are already accepting them.
Moreover, sending those response headers is already a recommended best practice amongst IT corporations, and is included as part of pen testing reports.

Describe the solution you'd like

Implementing the support for those headers.

Documentation, Adoption, Migration Strategy

Same way as other headers in the package.

  • [ x ] I've tried to find similar issues and pull requests
  • [ x ] I would like to work on this feature ๐Ÿ’ช๐Ÿป

Typo in README file, `soruce` instead of `source`

๐Ÿ’ฉ Bug Report

A summary of the bug

Hello,
There is a typo in README file in property name. It says soruce, but it should be source instead.
There are 4 places in a file with this typo, to be precise.

Environment

  • This project version(s): v2.0.0

  • I've tried to find similar issues
  • I would like to work on a fix ๐Ÿ’ช๐Ÿป

Export types for contentSecurityPolicy and directives

๐ŸŒฑ Feature Request

Is your feature request related to a problem? Please describe.

A clear and concise description of what you want and what your use case is.

Hello, I have been working on my own interpretation of this package to handle specific headers for my company and I would like to import the types for directives in contentSecurityPolicy so that I'm able to extend the interface.

Describe the solution you'd like

A clear and concise description of what you want to happen.

Adding the types to the export would be the ideal way forward. Being able to export the types means that we can extend it to make certain keys and values strict to a specific value or to only accept string[]

Describe alternatives you've considered

A clear and concise description of any alternative solutions or features you've considered.

Currently, I have been trying to access the types through this method.

import { createSecureHeaders } from 'next-secure-headers';

type ArgumentTypes<F extends Function> = F extends (...args: infer A) => any ? A : never;

type SecureHeadersArguments = ArgumentTypes<typeof createSecureHeaders>[0];

export type Directives = SecureHeadersArguments['contentSecurityPolicy'];

But I'm getting a type error on the last line:

Property 'contentSecurityPolicy' does not exist on type 'Partial<{ contentSecurityPolicy: ContentSecurityPolicyOption; expectCT: ExpectCTOption; forceHTTPSRedirect: ForceHTTPSRedirectOption; ... 4 more ...; xssProtection: XSSProtectionOption; }> | undefined'.ts(2339)

Documentation, Adoption, Migration Strategy

If you can, explain how users will be able to use this and how it might be documented. Maybe a mock-up?

import { ContentSecurityPolicyOption } from "next-secure-headers";

type Directives = ContentSecurityPolicyOption['directives']
  • I've tried to find similar issues and pull requests
  • I would like to work on this feature ๐Ÿ’ช๐Ÿป

X-XSS-Protection: header should be disabled by default

๐ŸŒฑ Feature Request

Is your feature request related to a problem? Please describe.

The X-XSS-Protection header seems to be falling out of favor across similar projects, since it causes more problems than it solves.

Describe the solution you'd like

The default value for X-XSS-Protection should be changed from 1 to 0. That ensures legacy browsers disable their buggy XSS Protection filters.

Describe alternatives you've considered

An alternative would be to update the README, suggesting projects configure xssProtection: false manually. And potentially updating this chart.

Documentation, Adoption, Migration Strategy

Helmet included this change as part of a major version bump. That's probably the safest way to go?

It's easy enough to work around in the meantime. I'm mainly opening up an issue since there weren't any similar discussions here yet, and I was curious if xssProtection: false is generally recommended now.

Additional context

helmetjs/helmet#230
https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html#x-xss-protection-header


  • I've tried to find similar issues and pull requests
  • I would like to work on this feature ๐Ÿ’ช๐Ÿป

Nonce & Hash support for CSP Level 2

๐ŸŒฑ Feature Request

Is your feature request related to a problem? Please describe.

I am attempting to implement a CSP into my app and not use unsafe-inline.

The way I understand CSP is that for every HTTP request I need to generate a base64 nonce / hash which gets put on the script tag and in the CSP header prefixed with nonce-.

Describe the solution you'd like

I am not entirely sure on the solution I need here.
In my opinion it would be nice to have a solution which allows me to access a generated base64 string and pass it into both the headers and the script tags

Describe alternatives you've considered

I haven't considered any way of approaching this yet but I'll continue to try.


  • I've tried to find similar issues and pull requests
  • I would like to work on this feature ๐Ÿ’ช๐Ÿป

Support for frame-ancestors

๐ŸŒฑ Feature Request

Is your feature request related to a problem? Please describe.

A clear and concise description of what you want and what your use case is.

I'm looking to set the CSP frame-ancestors header: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/frame-ancestors

as such:

Content-Security-Policy: frame-ancestors 'self' https://www.example.org;

Describe the solution you'd like

A clear and concise description of what you want to happen.

I would like to be able to set in the configuration a key value such as...

frameAncestors: "'self' https://www.example.org"

Describe alternatives you've considered

A clear and concise description of any alternative solutions or features you've considered.
I'm currently doing this...

    headers: async () => [
      {
        source: '/(.*)',
        headers: [
          ...createSecureHeaders(),
          {
            key: 'Content-Security-Policy',
            value: "frame-ancestors 'self' *.example.com;",
          },
        ]
      },
    ],

Documentation, Adoption, Migration Strategy

If you can, explain how users will be able to use this and how it might be documented. Maybe a mock-up?

Additional context

Add any other context or screenshots about the feature request here.


  • I've tried to find similar issues and pull requests
  • I would like to work on this feature ๐Ÿ’ช๐Ÿป

Modify `source` value in sample codes

๐Ÿ’ฉ Bug Report

A summary of the bug

Currently the readme is written source: "/(.*)" , but it does not working in some cases -- for example, an application uses Next.js built-in I18n routings.

Current behavior

Configured headers is not applied in some cases.

Expected behavior

It should be applied even if an application uses Next.js built-in I18n routings.

Additional context

Use "/:path*" instead.


  • I've tried to find similar issues
  • I would like to work on a fix ๐Ÿ’ช๐Ÿป

Using i18n in next.config.js will cause secure headers to disappear

๐Ÿ’ฉ Bug Report

A summary of the bug

Using i18n internationalization will cause secure headers to disappear

Current behavior

If you have this in your next.config.js:

i18n: {
  defaultLocale: "de",
  locales: ["de"]
},

Your headers will not be used.

To Reproduce

Steps to reproduce the behavior, please provide code snippets or a repository.

  1. add this to your next.config.js alongside your headers configuration
    i18n: { defaultLocale: "de", locales: ["de"] },
  2. npm run build & npm run start
  3. Check network tab, the CSP header wont be displayed
  4. Remove i18n, recompile & restart, CSP Headers are back there

Expected behavior

CSP Headers to work when i18n locales are set.

Environment

  • This project version(s): v2.2.0
  • Nodejs version: v14.15.4
  • OS: Windows 10

Additional context

The headers config i used:

  async headers() {
    return [{
      source: "/(.*)",
      headers: createSecureHeaders({
        contentSecurityPolicy: {
          directives: {
            defaultSrc: "'self'",
            imgSrc: ["https://*", "'self'", "data:"],
            styleSrc: ["'self'", "https://use.typekit.net/", "'unsafe-inline'"],
            fontSrc: "https://use.typekit.net/",
            scriptSrc: ["'self'", process.env.NODE_ENV === "development" ? "'unsafe-eval'" : ""],
            scriptSrcElem: "'self'"
          }
        }
      })
    }]
  }

  • I've tried to find similar issues
  • I would like to work on a fix ๐Ÿ’ช๐Ÿป

ESLint - no extraneous dependencies

๐Ÿ’ฉ Bug Report

A summary of the bug

ESLint is throwing an error on:

const { createSecureHeaders } = require('next-secure-headers');

'next-secure-headers' should be listed in the project's dependencies, not devDependencies.eslintimport/no-extraneous-dependencies

I was in fact wondering why should this be a development dependency given that the directives should, of course, be included in production.

Current behavior

This is next.config.js

   const { createSecureHeaders } = require('next-secure-headers');

 module.exports = {
     async headers() {
        return [{ source: '/(.*)', headers: createSecureHeaders() }];
    },
 };

To Reproduce

Install using $ npm install -D next-secure-headers

Per your documentation, it should be installed with the -D option, unless :

โ—๏ธ For withSecureHeaders . If you want to use withSecureHeaders , you have to install without -D option (i.e., installing as dependencies not devDependencies )

.

Expected behavior

No warnings from ESLint

Environment

  • This project version(s): v2.0.0
  • Nextjs version: 9.5.3
  • Nodejs version: v12.16.0
  • OS: macOS 10.15.6

Additional context

Add any other context about the problem here, or a screenshot if applicable.


  • I've tried to find similar issues
  • I would like to work on a fix ๐Ÿ’ช๐Ÿป

Add how to set unsupported headers to readme

๐ŸŒฑ Feature Request

Is your feature request related to a problem? Please describe.

Next.js supports to set any headers, but some developers don't know about it.

Describe the solution you'd like

Readme should be written how to set unsupported headers in next-secure-headers using the standard way in Next.js.

Describe alternatives you've considered

None.

Documentation, Adoption, Migration Strategy

None.

Additional context

This will be released in 2.3.0.


  • I've tried to find similar issues and pull requests
  • I would like to work on this feature ๐Ÿ’ช๐Ÿป

Support for Content-Security-Policy: upgrade-insecure-requests;

๐ŸŒฑ Feature Request

Is your feature request related to a problem? Please describe.

A clear and concise description of what you want and what your use case is.

Hi,
There is a way to set the upgrade-insecure-requests in the CSP headers?

Describe the solution you'd like

A clear and concise description of what you want to happen.

A new parameter like "upgradeInsecureRequest" of type bool (default false)

Describe alternatives you've considered

A clear and concise description of any alternative solutions or features you've considered.

Documentation, Adoption, Migration Strategy

If you can, explain how users will be able to use this and how it might be documented. Maybe a mock-up?

Additional context

Add any other context or screenshots about the feature request here.


  • I've tried to find similar issues and pull requests
  • I would like to work on this feature ๐Ÿ’ช๐Ÿป

Support spec names of CSP directives

๐ŸŒฑ Feature Request

Is your feature request related to a problem? Please describe.

The spec defines directives in kebab-case, e.g. script-src, these are currently not picked up, but appear as undefined.

Describe the solution you'd like

Since the camel-cased directives are sensible as well, supporting both would be nice.

Content-Security-Policy reportURI cannot be relative

๐Ÿ’ฉ Bug Report

A summary of the bug

next-secure-headers crashes if you try to use a relative URL in reportURI.

Here you can see what next-secure-headers is using URL for that directive:
https://github.com/jagaapple/next-secure-headers/blob/master/src/rules/content-security-policy.ts#L197
https://github.com/jagaapple/next-secure-headers/blob/master/src/rules/shared/uri-encoder.ts
And it is a bad idea.

Current behavior

Currently it crashes the server on its start:

ready - started server on 0.0.0.0:3000, url: http://localhost:3000
TypeError [ERR_INVALID_URL]: Invalid URL
    at new NodeError (node:internal/errors:363:5)
    at onParseError (node:internal/url:536:9)
    at new URL (node:internal/url:612:5)
    at encodeStrictURI (/home/my/ui-auth/node_modules/next-secure-headers/lib/rules/shared/uri-encoder.js:4:34)
    at Array.map (<anonymous>)
    at convertReportingDirectiveToString (/home/my/***/node_modules/next-secure-headers/lib/rules/content-security-policy.js:109:62)
    at createContentSecurityPolicyOptionHeaderValue (/home/my/***/node_modules/next-secure-headers/lib/rules/content-security-policy.js:127:9)
    at Object.createContentSecurityPolicyHeader (/home/my/***/node_modules/next-secure-headers/lib/rules/content-security-policy.js:139:19)
    at Object.createHeadersObject (/home/my/***/node_modules/next-secure-headers/lib/index.js:18:23)
    at createSecureHeaders (/home/my/***/node_modules/next-secure-headers/lib/index.js:37:35) {
  input: '/api/csp_violation',
  code: 'ERR_INVALID_URL'
}

To Reproduce

Create following next.config.mjs

import { createSecureHeaders, } from 'next-secure-headers';

let cspDirectives = {
    defaultSrc: "'self'",
    styleSrc: ["'self'", "https://stackpath.bootstrapcdn.com"],
}; // any directives
cspDirectives.reportURI = '/api/csp_violation';

export default {
    async headers() {
        return [
            {
                source: '/(.*)',
                headers: createSecureHeaders({
                    contentSecurityPolicy: {
                        directives: cspDirectives,
                    },
                    referrerPolicy: 'no-referrer',
                }),
            },
        ];
    },
}

And run yarn run dev.

Expected behavior

No crash.

Helmet allows relative report-uri in CSP (e.g /api/csp_violation).

Also, specification allows such URIs:
https://w3c.github.io/webappsec-csp/#directive-report-uri
https://datatracker.ietf.org/doc/html/rfc3986#section-4.1

Environment

  • This project version(s): v2.2.0
  • Nodejs version: v16.3.0
  • OS: Ubuntu 16.04

  • I've tried to find similar issues
  • I would like to work on a fix ๐Ÿ’ช๐Ÿป

Google Analytics & Adsense errors

๐Ÿ’ฉ Bug Report

A summary of the bug

I set up next.config.js as below aiming at allowing the regular scripts from Analytics and Adsense but getting a number of errors.

I tried adding some of the origins to the config, but how can one be sure to have included all origins that Google may include.

Current behavior

With the following code at `next.config.js:

   async headers() {
    return [
        {
            source: '/(.*)',
            headers: createSecureHeaders({
                contentSecurityPolicy: {
                    directives: {
                        scriptSrc: [
                            "'self'",
                            'https://www.googletagmanager.com',
                            'https://pagead2.googlesyndication.com',
                            'https://partner.googleadservices.com',
                        ],
                    },
                },
            }),
        },
    ];
},

Getting these errors:
Screenshot 2021-06-20 at 12 34 17

To Reproduce

Code above

Expected behavior

Load scripts while keeping secure headers.

Environment

  • This project version(s): v2.1.0
  • Nodejs version: v14.15.3
  • OS: macOS 11.4

Additional context

Add any other context about the problem here, or a screenshot if applicable.


  • I've tried to find similar issues
  • I would like to work on a fix ๐Ÿ’ช๐Ÿป

Add Content-Security-Policy Default directives as found in Helmet

๐ŸŒฑ Feature Request

Is your feature request related to a problem? Please describe.

As a solution similar to helmet, it would be beneficial for consumers to have similar defaults, so as to align with other packages features. This would provide consumers with a simple interface to match other packages leveraging helmet defaults. Otherwise, consumers need to specify these in their repositories.

You can find the defaults in helmet here

Describe the solution you'd like

Somewhere in the CSP rule, you could allow users to specify they want a set of default directives here: https://github.com/jagaapple/next-secure-headers/blob/master/src/rules/content-security-policy.ts#L226-L238

The behavior of the helmet repository is that if you tell it to include CSP without specifying any directives, it will default to the set defined in the module here

next-secure-headers can implement something similar by here:
https://github.com/jagaapple/next-secure-headers/blob/master/src/rules/content-security-policy.ts#L213-L223

When no directives are passed through, it can default to the same set of directives.

Describe alternatives you've considered

Consumers need to maintain a basic set of default directives for helmet independently when this should rest with the package.

Documentation, Adoption, Migration Strategy

If you can, explain how users will be able to use this and how it might be documented. Maybe a mock-up?

Additional context

Add any other context or screenshots about the feature request here.


  • I've tried to find similar issues and pull requests
  • I would like to work on this feature ๐Ÿ’ช๐Ÿป

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.