@@ -39,8 +39,8 @@ class CspHtmlWebpackPlugin {
3939 */
4040 constructor ( policy = { } , additionalOpts = { } ) {
4141 // the policy we want to use
42- this . policy = Object . assign ( { } , defaultPolicy , policy ) ;
43- this . userPolicy = policy ;
42+ this . policy = Object . freeze ( Object . assign ( { } , defaultPolicy , policy ) ) ;
43+ this . userPolicy = Object . freeze ( policy ) ;
4444
4545 // the additional options that this plugin allows
4646 this . opts = Object . assign ( { } , defaultAdditionalOpts , additionalOpts ) ;
@@ -63,15 +63,17 @@ class CspHtmlWebpackPlugin {
6363 htmlPluginData ,
6464 'plugin.options.disableCspPlugin'
6565 ) ;
66-
6766 if ( disableCspPlugin && disableCspPlugin === true ) {
67+ // the HtmlWebpackPlugin instance has disabled the plugin
6868 return false ;
6969 }
7070
7171 if ( isFunction ( this . opts . enabled ) ) {
72+ // run the function to check if the plugin has been disabled
7273 return this . opts . enabled ( htmlPluginData ) ;
7374 }
7475
76+ // otherwise assume it's a boolean
7577 return this . opts . enabled ;
7678 }
7779
@@ -94,25 +96,25 @@ class CspHtmlWebpackPlugin {
9496 * @param {object } $ - the Cheerio instance
9597 * @param {string } policyName - one of 'script-src' and 'style-src'
9698 * @param {string } selector - a Cheerio selector string for getting the hashable elements for this policy
97- * @param {object } policyObj - the working CSP policy object
98- * @param {object } userPolicyObj - the sanitized CSP policy object provided by the user
9999 * @return {object } the new policy for `policyName`
100100 */
101- createPolicyObj ( $ , policyName , selector , policyObj , userPolicyObj ) {
102- // Wrapped in flatten([]) to handle both when policy is a string and an array
103- const flattenedUserPolicy = flatten ( userPolicyObj [ policyName ] ) ;
101+ createPolicyObj ( $ , policyName , selector ) {
104102 if (
105103 this . opts . devAllowUnsafe === true &&
106- ( flattenedUserPolicy . includes ( "'unsafe-inline'" ) ||
107- flattenedUserPolicy . includes ( "'unsafe-eval'" ) )
104+ this . userPolicy [ policyName ] &&
105+ ( this . userPolicy [ policyName ] . includes ( "'unsafe-inline'" ) ||
106+ this . userPolicy [ policyName ] . includes ( "'unsafe-eval'" ) )
108107 ) {
109- return userPolicyObj [ policyName ] ;
108+ // the user has allowed us to override unsafe-*, and we found unsafe-* in their defined policy. Let's use it
109+ return this . userPolicy [ policyName ] ;
110110 }
111111
112+ // otherwise hash all of the elements passed in
112113 const hashes = $ ( selector )
113114 . map ( ( i , element ) => this . hash ( $ ( element ) . html ( ) ) )
114115 . get ( ) ;
115- return flatten ( [ policyObj [ policyName ] ] ) . concat ( hashes ) ;
116+
117+ return flatten ( [ this . policy [ policyName ] ] ) . concat ( hashes ) ;
116118 }
117119
118120 /**
@@ -163,30 +165,24 @@ class CspHtmlWebpackPlugin {
163165 metaTag . prependTo ( $ ( 'head' ) ) ;
164166 }
165167
166- const policyObj = JSON . parse ( JSON . stringify ( this . policy ) ) ;
167- const parsedUserPolicy = JSON . parse ( JSON . stringify ( this . userPolicy ) ) ;
168-
169- // If the user policy contains 'unsafe-inline' for either script-src or style-src, we need to
170- // avoid hashing the existing script tags, so as to avoid implicitly disabling the
171- // 'unsafe-inline' preference.
172-
173- policyObj [ 'script-src' ] = this . createPolicyObj (
168+ // looks for script and style rules to hash
169+ const scriptRule = this . createPolicyObj (
174170 $ ,
175171 'script-src' ,
176- 'script:not([src])' ,
177- policyObj ,
178- parsedUserPolicy
172+ 'script:not([src])'
179173 ) ;
180- policyObj [ 'style-src' ] = this . createPolicyObj (
181- $ ,
182- 'style-src' ,
183- 'style:not([href])' ,
184- policyObj ,
185- parsedUserPolicy
174+ const styleRule = this . createPolicyObj ( $ , 'style-src' , 'style:not([href])' ) ;
175+
176+ // build the policy into the context attr of the csp meta tag
177+ metaTag . attr (
178+ 'content' ,
179+ this . buildPolicy ( {
180+ ...this . policy ,
181+ 'script-src' : scriptRule ,
182+ 'style-src' : styleRule
183+ } )
186184 ) ;
187185
188- metaTag . attr ( 'content' , this . buildPolicy ( policyObj ) ) ;
189-
190186 // eslint-disable-next-line no-param-reassign
191187 htmlPluginData . html = $ . html ( ) ;
192188
0 commit comments