jagaapple / next-secure-headers

Sets secure response headers for Next.js.
MIT License
317 stars 13 forks source link

Content-Security-Policy reportURI cannot be relative #52

Open 1aerostorm opened 2 years ago

1aerostorm commented 2 years ago

šŸ’© 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