File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -19,9 +19,10 @@ export const WEB_CSP_BASELINE: Record<string, string[]> = {
1919} ;
2020
2121// Reject the separators (whitespace ends a source, ';' ends a directive, ','
22- // ends a policy) so a stray char can't inject directives when sources are joined.
22+ // ends a policy) so a stray char can't inject directives when sources are joined,
23+ // plus " < > so a source can't break out of the content="..." meta attribute.
2324const CSP_DIRECTIVE = / ^ [ a - z A - Z ] [ a - z A - Z - ] * $ / ;
24- const CSP_SOURCE = / ^ [ ^ \s ; , ] + $ / ;
25+ const CSP_SOURCE = / ^ [ ^ \s ; , " < > ] + $ / ;
2526
2627export function isCspOverrides ( v : unknown ) : v is Record < string , string [ ] > {
2728 return (
Original file line number Diff line number Diff line change @@ -278,9 +278,7 @@ function readExportStandard(read: CourseConfigRead): string {
278278// `false` drops the meta for deployments that set a CSP header themselves.
279279function cspMeta ( read : CourseConfigRead ) : string {
280280 if ( readExportStandard ( read ) !== 'web' ) return '' ;
281- const csp = read . ok
282- ? ( read . config . export as { csp ?: unknown } | undefined ) ?. csp
283- : undefined ;
281+ const csp = read . ok ? read . config . export ?. csp : undefined ;
284282 if ( csp === false ) return '' ;
285283 return `\n <meta http-equiv="Content-Security-Policy" content="${ buildCsp ( csp ) } " />` ;
286284}
Original file line number Diff line number Diff line change @@ -63,5 +63,25 @@ describe('isCspOverrides', () => {
6363 expect ( isCspOverrides ( { 'font-src' : [ "'self' https://x" ] } ) ) . toBe ( false ) ;
6464 expect ( isCspOverrides ( { '' : [ "'self'" ] } ) ) . toBe ( false ) ;
6565 expect ( isCspOverrides ( { 'font src' : [ "'self'" ] } ) ) . toBe ( false ) ;
66+ // A " or > would break out of the content="..." meta attribute into markup.
67+ expect (
68+ isCspOverrides ( { 'font-src' : [ 'https://x"><script>alert(1)</script>' ] } ) ,
69+ ) . toBe ( false ) ;
70+ } ) ;
71+
72+ it ( 'accepts the legitimate source forms' , ( ) => {
73+ for ( const src of [
74+ "'self'" ,
75+ "'unsafe-inline'" ,
76+ "'none'" ,
77+ 'https:' ,
78+ 'data:' ,
79+ 'blob:' ,
80+ 'https://fonts.gstatic.com' ,
81+ "'nonce-abc123=='" ,
82+ "'sha256-AbC+/dEf='" ,
83+ ] ) {
84+ expect ( isCspOverrides ( { 'font-src' : [ src ] } ) ) . toBe ( true ) ;
85+ }
6686 } ) ;
6787} ) ;
You can’t perform that action at this time.
0 commit comments