@@ -31,9 +31,24 @@ class BaseProvider {
31
31
/** @type {boolean } */
32
32
#script_needs_csp;
33
33
34
+ /** @type {boolean } */
35
+ #script_src_needs_csp;
36
+
37
+ /** @type {boolean } */
38
+ #script_src_elem_needs_csp;
39
+
34
40
/** @type {boolean } */
35
41
#style_needs_csp;
36
42
43
+ /** @type {boolean } */
44
+ #style_src_needs_csp;
45
+
46
+ /** @type {boolean } */
47
+ #style_src_attr_needs_csp;
48
+
49
+ /** @type {boolean } */
50
+ #style_src_elem_needs_csp;
51
+
37
52
/** @type {import('types').CspDirectives } */
38
53
#directives;
39
54
@@ -121,92 +136,81 @@ class BaseProvider {
121
136
}
122
137
}
123
138
124
- this . #script_needs_csp =
125
- ( ! ! effective_script_src &&
126
- effective_script_src . filter ( ( value ) => value !== 'unsafe-inline' ) . length > 0 ) ||
127
- ( ! ! script_src_elem &&
128
- script_src_elem . filter ( ( value ) => value !== 'unsafe-inline' ) . length > 0 ) ;
139
+ /** @param {(import('types').Csp.Source | import('types').Csp.ActionSource)[] | undefined } directive */
140
+ const needs_csp = ( directive ) =>
141
+ ! ! directive && ! directive . some ( ( value ) => value === 'unsafe-inline' ) ;
129
142
143
+ this . #script_src_needs_csp = needs_csp ( effective_script_src ) ;
144
+ this . #script_src_elem_needs_csp = needs_csp ( script_src_elem ) ;
145
+ this . #style_src_needs_csp = needs_csp ( effective_style_src ) ;
146
+ this . #style_src_attr_needs_csp = needs_csp ( style_src_attr ) ;
147
+ this . #style_src_elem_needs_csp = needs_csp ( style_src_elem ) ;
148
+
149
+ this . #script_needs_csp = this . #script_src_needs_csp || this . #script_src_elem_needs_csp;
130
150
this . #style_needs_csp =
131
151
! __SVELTEKIT_DEV__ &&
132
- ( ( ! ! effective_style_src &&
133
- effective_style_src . filter ( ( value ) => value !== 'unsafe-inline' ) . length > 0 ) ||
134
- ( ! ! style_src_attr &&
135
- style_src_attr . filter ( ( value ) => value !== 'unsafe-inline' ) . length > 0 ) ||
136
- ( ! ! style_src_elem &&
137
- style_src_elem . filter ( ( value ) => value !== 'unsafe-inline' ) . length > 0 ) ) ;
152
+ ( this . #style_src_needs_csp ||
153
+ this . #style_src_attr_needs_csp ||
154
+ this . #style_src_elem_needs_csp) ;
138
155
139
156
this . script_needs_nonce = this . #script_needs_csp && ! this . #use_hashes;
140
157
this . style_needs_nonce = this . #style_needs_csp && ! this . #use_hashes;
158
+
141
159
this . #nonce = nonce ;
142
160
}
143
161
144
162
/** @param {string } content */
145
163
add_script ( content ) {
146
- if ( this . #script_needs_csp) {
147
- const d = this . #directives;
164
+ if ( ! this . #script_needs_csp) return ;
148
165
149
- if ( this . #use_hashes) {
150
- const hash = sha256 ( content ) ;
151
-
152
- this . #script_src. push ( `sha256-${ hash } ` ) ;
153
-
154
- if ( d [ 'script-src-elem' ] ?. length ) {
155
- this . #script_src_elem. push ( `sha256-${ hash } ` ) ;
156
- }
157
- } else {
158
- if ( this . #script_src. length === 0 ) {
159
- this . #script_src. push ( `nonce-${ this . #nonce} ` ) ;
160
- }
161
- if ( d [ 'script-src-elem' ] ?. length ) {
162
- this . #script_src_elem. push ( `nonce-${ this . #nonce} ` ) ;
163
- }
164
- }
166
+ /** @type {`nonce-${string}` | `sha256-${string}` } */
167
+ const source = this . #use_hashes ? `sha256-${ sha256 ( content ) } ` : `nonce-${ this . #nonce} ` ;
168
+
169
+ if ( this . #script_src_needs_csp) {
170
+ this . #script_src. push ( source ) ;
171
+ }
172
+
173
+ if ( this . #script_src_elem_needs_csp) {
174
+ this . #script_src_elem. push ( source ) ;
165
175
}
166
176
}
167
177
168
178
/** @param {string } content */
169
179
add_style ( content ) {
170
- if ( this . #style_needs_csp) {
171
- // this is the hash for "/* empty */"
172
- // adding it so that svelte does not break csp
173
- // see https://github.com/sveltejs/svelte/pull/7800
174
- const empty_comment_hash = '9OlNO0DNEeaVzHL4RZwCLsBHA8WBQ8toBp/4F5XV2nc=' ;
180
+ if ( ! this . #style_needs_csp) return ;
175
181
176
- const d = this . #directives;
182
+ /** @type {`nonce-${string}` | `sha256-${string}` } */
183
+ const source = this . #use_hashes ? `sha256-${ sha256 ( content ) } ` : `nonce-${ this . #nonce} ` ;
177
184
178
- if ( this . #use_hashes) {
179
- const hash = sha256 ( content ) ;
185
+ if ( this . #style_src_needs_csp) {
186
+ this . #style_src. push ( source ) ;
187
+ }
180
188
181
- this . #style_src. push ( `sha256-${ hash } ` ) ;
189
+ if ( this . #style_src_needs_csp) {
190
+ this . #style_src. push ( source ) ;
191
+ }
182
192
183
- if ( d [ 'style-src-attr' ] ?. length ) {
184
- this . #style_src_attr. push ( `sha256-${ hash } ` ) ;
185
- }
186
- if ( d [ 'style-src-elem' ] ?. length ) {
187
- if (
188
- hash !== empty_comment_hash &&
189
- ! d [ 'style-src-elem' ] . includes ( `sha256-${ empty_comment_hash } ` )
190
- ) {
191
- this . #style_src_elem. push ( `sha256-${ empty_comment_hash } ` ) ;
192
- }
193
+ if ( this . #style_src_attr_needs_csp) {
194
+ this . #style_src_attr. push ( source ) ;
195
+ }
193
196
194
- this . #style_src_elem. push ( `sha256-${ hash } ` ) ;
195
- }
196
- } else {
197
- if ( this . #style_src. length === 0 && ! d [ 'style-src' ] ?. includes ( 'unsafe-inline' ) ) {
198
- this . #style_src. push ( `nonce-${ this . #nonce} ` ) ;
199
- }
200
- if ( d [ 'style-src-attr' ] ?. length ) {
201
- this . #style_src_attr. push ( `nonce-${ this . #nonce} ` ) ;
202
- }
203
- if ( d [ 'style-src-elem' ] ?. length ) {
204
- if ( ! d [ 'style-src-elem' ] . includes ( `sha256-${ empty_comment_hash } ` ) ) {
205
- this . #style_src_elem. push ( `sha256-${ empty_comment_hash } ` ) ;
206
- }
197
+ if ( this . #style_src_elem_needs_csp) {
198
+ // this is the sha256 hash for the string "/* empty */"
199
+ // adding it so that svelte does not break csp
200
+ // see https://github.com/sveltejs/svelte/pull/7800
201
+ const sha256_empty_comment_hash = 'sha256-9OlNO0DNEeaVzHL4RZwCLsBHA8WBQ8toBp/4F5XV2nc=' ;
202
+ const d = this . #directives;
203
+
204
+ if (
205
+ d [ 'style-src-elem' ] &&
206
+ ! d [ 'style-src-elem' ] . includes ( sha256_empty_comment_hash ) &&
207
+ ! this . #style_src_elem. includes ( sha256_empty_comment_hash )
208
+ ) {
209
+ this . #style_src_elem. push ( sha256_empty_comment_hash ) ;
210
+ }
207
211
208
- this . #style_src_elem . push ( `nonce- ${ this . #nonce } ` ) ;
209
- }
212
+ if ( source !== sha256_empty_comment_hash ) {
213
+ this . #style_src_elem . push ( source ) ;
210
214
}
211
215
}
212
216
}
0 commit comments