Skip to content

Commit

Permalink
Merging e009959 into trunk-temp/pr-2301/0e8d6e61-90cd-4d2d-a936-71716…
Browse files Browse the repository at this point in the history
…63fa7ba
  • Loading branch information
trunk-io[bot] authored Nov 22, 2024
2 parents 120a07b + e009959 commit a385007
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 74 deletions.
87 changes: 22 additions & 65 deletions nosecone-next/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,24 @@
import nosecone, { defaults } from "nosecone";
import type { CspDirectives, NoseconeOptions } from "nosecone";

// Re-exports the defaults for easier overrides
export { defaults };
import nosecone, { defaults as baseDefaults } from "nosecone";
import type { NoseconeOptions } from "nosecone";

export const defaults = {
...baseDefaults,
contentSecurityPolicy: {
directives: {
...baseDefaults.contentSecurityPolicy.directives,
scriptSrc:
// Replace the defaults to remove `'self'`
process.env.NODE_ENV === "development"
? ([nonce, "'strict-dynamic'"] as const)
: // Next.js hot reloading relies on `eval` so we enable it in development
([nonce, "'strict-dynamic'", "'unsafe-eval'"] as const),
styleSrc: [
...baseDefaults.contentSecurityPolicy.directives.styleSrc,
"'unsafe-inline'",
],
},
},
} as const;

// We export `nosecone` as the default so it can be used with `new Response()`
export default nosecone;
Expand All @@ -11,64 +27,6 @@ function nonce() {
return `'nonce-${btoa(crypto.randomUUID())}'` as const;
}

const defaultDirectives = defaults.contentSecurityPolicy.directives;

function applyNextDefaults(options: NoseconeOptions): NoseconeOptions {
if (
typeof options.contentSecurityPolicy === "undefined" ||
!options.contentSecurityPolicy
) {
return options;
}

const directives =
options.contentSecurityPolicy === true ||
typeof options.contentSecurityPolicy.directives === "undefined"
? defaultDirectives
: options.contentSecurityPolicy.directives;

let scriptSrc: CspDirectives["scriptSrc"];
if (directives.scriptSrc === true) {
scriptSrc = defaultDirectives.scriptSrc;
} else {
scriptSrc = directives.scriptSrc;
}
if (scriptSrc) {
const scriptSrcSet = new Set(scriptSrc);
scriptSrcSet.delete("'self'");
scriptSrcSet.add(nonce());
scriptSrcSet.add("'strict-dynamic'");
// Next.js hot reloading relies on `eval` so we enable it in development
if (process.env.NODE_ENV === "development") {
scriptSrcSet.add("'unsafe-eval'");
}
scriptSrc = Array.from(scriptSrcSet);
}

let styleSrc: CspDirectives["styleSrc"];
if (directives.styleSrc === true) {
styleSrc = defaultDirectives.styleSrc;
} else {
styleSrc = directives.styleSrc;
}
if (styleSrc) {
const styleSrcSet = new Set(styleSrc);
styleSrcSet.add("'unsafe-inline'");
styleSrc = Array.from(styleSrcSet);
}

return {
...options,
contentSecurityPolicy: {
directives: {
...directives,
scriptSrc,
styleSrc,
},
},
};
}

/**
* Create Next.js middleware that sets secure headers on every request.
*
Expand All @@ -77,8 +35,7 @@ function applyNextDefaults(options: NoseconeOptions): NoseconeOptions {
*/
export function createMiddleware(options: NoseconeOptions = defaults) {
return async () => {
const opts = applyNextDefaults(options);
const headers = nosecone(opts);
const headers = nosecone(options);

return new Response(null, {
headers: {
Expand Down
18 changes: 9 additions & 9 deletions nosecone-sveltekit/index.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
import nosecone, {
CONTENT_SECURITY_POLICY_DIRECTIVES,
QUOTED,
defaults,
defaults as baseDefaults,
NoseconeValidationError,
} from "nosecone";
import type { CspDirectives, NoseconeOptions } from "nosecone";
import type { Handle, KitConfig } from "@sveltejs/kit";

// Re-exports the defaults for easier overrides
export { defaults };
export const defaults = {
...baseDefaults,
directives: {
...baseDefaults.contentSecurityPolicy.directives,
scriptSrc: ["'strict-dynamic'"],
},
} as const;

// We export `nosecone` as the default so it can be used with `new Response()`
export default nosecone;
Expand Down Expand Up @@ -44,11 +49,6 @@ export type ContentSecurityPolicyConfig = {
// TODO: Support `reportOnly`
};

const directives: CspDirectives = {
...defaults.contentSecurityPolicy.directives,
scriptSrc: ["'strict-dynamic'"],
};

function unquote(value?: string) {
for (const [unquoted, quoted] of QUOTED) {
if (value === quoted) {
Expand Down Expand Up @@ -108,7 +108,7 @@ function directivesToSvelteKitConfig(
}

export function csp(
options: ContentSecurityPolicyConfig = { mode: "auto", directives },
options: ContentSecurityPolicyConfig = { mode: "auto" },
): SvelteKitCsp {
return {
mode: options.mode ? options.mode : "auto",
Expand Down

0 comments on commit a385007

Please sign in to comment.