I am in the process of performing a security scan of a PoC Spring Boot application, deployed under AWS ECS.
First round of scan, I discovered issues with CSP, cookies, XSS (that's what ZAP is for!), etc. I added some Spring Security configuration to my application to harden it a bit.
Now that I want to scan the application again, the HUD is totally broken and won't display
While it's a PoC running on H2 and I see no security issue, I won't post for now the URL to it. It's in the form of http://bg-lb-op-xxxxxx.eu-central-1.elb.amazonaws.com/app/
- Zap loads it from HTTPS while I have no SSL binding on it
- Chrome insists on the following error
Error while parsing the 'sandbox' attribute: 'allow-storage-access-by-user-activation' is an invalid sandbox flag.
- And there is the https error
Mixed Content: The page at 'https://bg-lb-op-xxxxxxx/......' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint 'http://bg-lb-op-xxxxxxxx/.... This request has been blocked; the content must be served over HTTPS.
Example response headers as captured by Chrome
HTTP/1.1 200
Date: Tue, 11 Jul 2023 10:34:14 GMT
Content-Type: text/html;charset=UTF-8
Connection: keep-alive
Set-Cookie: AWSALBTG=xxxxxxxx; Expires=Tue, 18 Jul 2023 10:34:14 GMT; Path=/
Set-Cookie: AWSALBTGCORS=xxxxxxxx; Expires=Tue, 18 Jul 2023 10:34:14 GMT; Path=/; SameSite=None
Set-Cookie: AWSALB=xxxxxxx; Expires=Tue, 18 Jul 2023 10:34:14 GMT; Path=/
Set-Cookie: AWSALBCORS=xxxxx; Expires=Tue, 18 Jul 2023 10:34:14 GMT; Path=/; SameSite=None
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Cross-Origin-Opener-Policy: unsafe-none
Cross-Origin-Embedder-Policy: require-corp
Cross-Origin-Resource-Policy: same-site
Content-Length: 2799
After the first scan I added the following Spring security configuration
@Bean
@Order
public SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws Exception {
return httpSecurity
.authorizeRequests(request -> request
.antMatchers("/js/**", "/styles/**", "/images/**", "/favicon.ico").permitAll()
.antMatchers("/ping/**").permitAll()
.anyRequest().authenticated()
)
.formLogin(form -> form
.loginPage("/login")
.successHandler(authenticationSuccessHandler)
.permitAll()
)
.logout(withDefaults())
.csrf(withDefaults())
.headers(headers -> headers
.httpStrictTransportSecurity(withDefaults())
.cacheControl(withDefaults())
.contentTypeOptions(withDefaults())
.xssProtection().xssProtectionEnabled(true).block(true).and()
.referrerPolicy(ReferrerPolicyHeaderWriter.ReferrerPolicy.NO_REFERRER).and()
.crossOriginEmbedderPolicy().policy(CrossOriginEmbedderPolicyHeaderWriter.CrossOriginEmbedderPolicy.REQUIRE_CORP).and()
.crossOriginOpenerPolicy().policy(CrossOriginOpenerPolicyHeaderWriter.CrossOriginOpenerPolicy.UNSAFE_NONE).and()
.crossOriginResourcePolicy().policy(CrossOriginResourcePolicyHeaderWriter.CrossOriginResourcePolicy.SAME_SITE).and()
.frameOptions(HeadersConfigurer.FrameOptionsConfig::deny)
.contentSecurityPolicy(csp -> csp.policyDirectives("base-uri 'self'; " +
"default-src 'self' 'unsafe-inline' https://cdn.jsdelivr.net https://cdnjs.cloudflare.com https://ajax.googleapis.com; " +
"style-src 'self' 'unsafe-inline' https://cdn.jsdelivr.net https://cdnjs.cloudflare.com https://ajax.googleapis.com; " +
"font-src https://cdnjs.cloudflare.com;" +
"connect-src 'self'; " +
"worker-src 'none'; " +
"frame-src 'none'; " +
"form-action 'self';"))
)
.build();
}
From what I can see, security headers are messing with ZAP's injection tool. If I roll everything back, I can see the HUD again. But I knew that ZAP should try to filter out the headers that may interfere with its own injection tool.
I can't retest the application to confirm that past issues are fixed.
Is there anything I have missed/messed?