|
46 | 46 | import org.springframework.security.crypto.password.PasswordEncoder;
|
47 | 47 | import org.springframework.security.web.access.AccessDeniedHandler;
|
48 | 48 | import org.springframework.security.web.authentication.Http403ForbiddenEntryPoint;
|
| 49 | +import org.springframework.security.web.header.HeaderWriter; |
| 50 | +import org.springframework.security.web.header.writers.ContentSecurityPolicyHeaderWriter; |
| 51 | +import org.springframework.security.web.header.writers.DelegatingRequestMatcherHeaderWriter; |
| 52 | +import org.springframework.security.web.util.matcher.AntPathRequestMatcher; |
| 53 | +import org.springframework.security.web.util.matcher.NegatedRequestMatcher; |
49 | 54 |
|
50 | 55 | import ru.mystamps.web.Url;
|
51 | 56 | import ru.mystamps.web.config.ServicesConfig;
|
@@ -117,39 +122,22 @@ protected void configure(HttpSecurity http) throws Exception {
|
117 | 122 | .disable()
|
118 | 123 | .headers()
|
119 | 124 | .defaultsDisabled() // TODO
|
120 |
| - .contentSecurityPolicy( |
121 |
| - // default policy prevents loading resources from any source |
122 |
| - "default-src 'none'; " |
123 |
| - // 'self' is required for: our own CSS files |
124 |
| - // 'https://cdn.rawgit.com' is required for: languages.min.css (TODO: GH #246) |
125 |
| - // 'https://www.gstatic.com' is required for: Google Charts on collection page. |
126 |
| - // 'sha256-Dpm...' is required for: 'box-shadow: none; border: 0px;' inline CSS |
127 |
| - // that are using on /series/add and /series/{id} pages. |
128 |
| - // 'sha256-/kX...' is required for: 'overflow: hidden;' inline CSS that is using |
129 |
| - // bg Google Charts on collection page. |
130 |
| - + "style-src 'self' https://cdn.rawgit.com https://www.gstatic.com " |
131 |
| - + "'sha256-DpmxvnMJIlwkpmmAANZYNzmyfnX2PQCBDO4CB2BFjzU=' " |
132 |
| - + "'sha256-/kXZODfqoc2myS1eI6wr0HH8lUt+vRhW8H/oL+YJcMg='; " |
133 |
| - // 'self' is required for: our own JS files |
134 |
| - // 'unsafe-inline' is required for: jquery.min.js (that is using code inside of |
135 |
| - // event handlers. We can't use hashing algorithms because they aren't supported |
136 |
| - // for handlers. In future, we should get rid of jQuery or use |
137 |
| - // 'unsafe-hashed-attributes' from CSP3. Details: |
138 |
| - // https://github.com/jquery/jquery/blob/d71f6a53927ad02d/jquery.js#L1441-L1447 |
139 |
| - // and https://w3c.github.io/webappsec-csp/#unsafe-hashed-attributes-usage) |
140 |
| - // 'unsafe-eval' is required for: loader.js (for Google Charts) |
141 |
| - // 'https://www.gstatic.com' is required for: Google Charts on collection page. |
142 |
| - + "script-src 'self' 'unsafe-inline' 'unsafe-eval' https://www.gstatic.com; " |
143 |
| - // 'self' is required for: AJAX requests from our scripts (country suggestions) |
144 |
| - + "connect-src 'self'; " |
145 |
| - // 'self' is required for: uploaded images and its previews |
146 |
| - // 'https://cdn.rawgit.com' is required for: languages.png (TODO: GH #246) |
147 |
| - // 'https://raw.githubusercontent.com' is required for: languages.png |
148 |
| - + "img-src 'self' https://cdn.rawgit.com https://raw.githubusercontent.com; " |
149 |
| - // 'self' is required for: glyphicons-halflings-regular.woff2 from bootstrap |
150 |
| - + "font-src 'self'; " |
151 |
| - + "report-uri https://mystamps.report-uri.io/r/default/csp/reportOnly" |
152 |
| - ).reportOnly(); |
| 125 | + .addHeaderWriter( |
| 126 | + new DelegatingRequestMatcherHeaderWriter( |
| 127 | + new NegatedRequestMatcher( |
| 128 | + new AntPathRequestMatcher( |
| 129 | + Url.INFO_COLLECTION_PAGE.replace("{slug}", "**") |
| 130 | + ) |
| 131 | + ), |
| 132 | + getCspForCommonPages() |
| 133 | + ) |
| 134 | + ) |
| 135 | + .addHeaderWriter( |
| 136 | + new DelegatingRequestMatcherHeaderWriter( |
| 137 | + new AntPathRequestMatcher(Url.INFO_COLLECTION_PAGE.replace("{slug}", "**")), |
| 138 | + getCspForCollectionInfoPage() |
| 139 | + ) |
| 140 | + ); |
153 | 141 | }
|
154 | 142 |
|
155 | 143 | // Used in ServicesConfig.getUserService()
|
@@ -210,4 +198,74 @@ private UserDetailsService getUserDetailsService() {
|
210 | 198 | return new CustomUserDetailsService(servicesConfig.getUserService());
|
211 | 199 | }
|
212 | 200 |
|
| 201 | + private HeaderWriter getCspForCommonPages() { |
| 202 | + ContentSecurityPolicyHeaderWriter writer = new ContentSecurityPolicyHeaderWriter( |
| 203 | + // default policy prevents loading resources from any source |
| 204 | + "default-src 'none'; " |
| 205 | + // 'self' is required for: our own CSS files |
| 206 | + // 'https://cdn.rawgit.com' is required for: languages.min.css (TODO: GH #246) |
| 207 | + // 'sha256-Dpm...' is required for: 'box-shadow: none; border: 0px;' inline CSS |
| 208 | + // that are using on /series/add and /series/{id} pages. |
| 209 | + + "style-src 'self' https://cdn.rawgit.com " |
| 210 | + + "'sha256-DpmxvnMJIlwkpmmAANZYNzmyfnX2PQCBDO4CB2BFjzU='; " |
| 211 | + // 'self' is required for: our own JS files |
| 212 | + // 'unsafe-inline' is required for: jquery.min.js (that is using code inside of |
| 213 | + // event handlers. We can't use hashing algorithms because they aren't supported |
| 214 | + // for handlers. In future, we should get rid of jQuery or use |
| 215 | + // 'unsafe-hashed-attributes' from CSP3. Details: |
| 216 | + // https://github.com/jquery/jquery/blob/d71f6a53927ad02d/jquery.js#L1441-L1447 |
| 217 | + // and https://w3c.github.io/webappsec-csp/#unsafe-hashed-attributes-usage) |
| 218 | + + "script-src 'self' 'unsafe-inline'; " |
| 219 | + // 'self' is required for: AJAX requests from our scripts (country suggestions) |
| 220 | + + "connect-src 'self'; " |
| 221 | + // 'self' is required for: uploaded images and its previews |
| 222 | + // 'https://cdn.rawgit.com' is required for: languages.png (TODO: GH #246) |
| 223 | + // 'https://raw.githubusercontent.com' is required for: languages.png |
| 224 | + + "img-src 'self' https://cdn.rawgit.com https://raw.githubusercontent.com; " |
| 225 | + // 'self' is required for: glyphicons-halflings-regular.woff2 from bootstrap |
| 226 | + + "font-src 'self'; " |
| 227 | + + "report-uri https://mystamps.report-uri.io/r/default/csp/reportOnly" |
| 228 | + ); |
| 229 | + writer.setReportOnly(true); |
| 230 | + return writer; |
| 231 | + } |
| 232 | + |
| 233 | + private HeaderWriter getCspForCollectionInfoPage() { |
| 234 | + ContentSecurityPolicyHeaderWriter writer = new ContentSecurityPolicyHeaderWriter( |
| 235 | + // default policy prevents loading resources from any source |
| 236 | + "default-src 'none'; " |
| 237 | + // 'self' is required for: our own CSS files |
| 238 | + // 'https://cdn.rawgit.com' is required for: languages.min.css (TODO: GH #246) |
| 239 | + // 'https://www.gstatic.com' is required for: Google Charts on collection page. |
| 240 | + // 'sha256-Dpm...' is required for: 'box-shadow: none; border: 0px;' inline CSS |
| 241 | + // that are using on /series/add and /series/{id} pages. |
| 242 | + // 'sha256-/kX...' is required for: 'overflow: hidden;' inline CSS that is using |
| 243 | + // bg Google Charts on collection page. |
| 244 | + + "style-src 'self' https://cdn.rawgit.com https://www.gstatic.com " |
| 245 | + + "'sha256-DpmxvnMJIlwkpmmAANZYNzmyfnX2PQCBDO4CB2BFjzU=' " |
| 246 | + + "'sha256-/kXZODfqoc2myS1eI6wr0HH8lUt+vRhW8H/oL+YJcMg='; " |
| 247 | + // 'self' is required for: our own JS files |
| 248 | + // 'unsafe-inline' is required for: jquery.min.js (that is using code inside of |
| 249 | + // event handlers. We can't use hashing algorithms because they aren't supported |
| 250 | + // for handlers. In future, we should get rid of jQuery or use |
| 251 | + // 'unsafe-hashed-attributes' from CSP3. Details: |
| 252 | + // https://github.com/jquery/jquery/blob/d71f6a53927ad02d/jquery.js#L1441-L1447 |
| 253 | + // and https://w3c.github.io/webappsec-csp/#unsafe-hashed-attributes-usage) |
| 254 | + // 'unsafe-eval' is required for: loader.js (for Google Charts) |
| 255 | + // 'https://www.gstatic.com' is required for: Google Charts on collection page. |
| 256 | + + "script-src 'self' 'unsafe-inline' 'unsafe-eval' https://www.gstatic.com; " |
| 257 | + // 'self' is required for: AJAX requests from our scripts (country suggestions) |
| 258 | + + "connect-src 'self'; " |
| 259 | + // 'self' is required for: uploaded images and its previews |
| 260 | + // 'https://cdn.rawgit.com' is required for: languages.png (TODO: GH #246) |
| 261 | + // 'https://raw.githubusercontent.com' is required for: languages.png |
| 262 | + + "img-src 'self' https://cdn.rawgit.com https://raw.githubusercontent.com; " |
| 263 | + // 'self' is required for: glyphicons-halflings-regular.woff2 from bootstrap |
| 264 | + + "font-src 'self'; " |
| 265 | + + "report-uri https://mystamps.report-uri.io/r/default/csp/reportOnly" |
| 266 | + ); |
| 267 | + writer.setReportOnly(true); |
| 268 | + return writer; |
| 269 | + } |
| 270 | + |
213 | 271 | }
|
0 commit comments