spring-projects/spring-boot

Modify Content Security Policy to allow LiveReload when devtools enabled

Closed this issue · 10 comments

When Spring Boot's devtools are enabled it would be nice if we could automatically modify the Content Security Policy (CSP) to allow LiveReload. Otherwise when using a more restrictive CSP the following error occurs:

Refused to connect to 'ws://127.0.0.1:35729/livereload' because it violates the following Content Security Policy directive: "default-src 'self'". Note that 'connect-src' was not explicitly set, so 'default-src' is used as a fallback.

Currently this will only be relevant if someone has enabled CSP through the generic header support. For example:

http
    .headers()
        .addHeaderWriter(new StaticHeadersWriter("Content-Security-Policy","default-src 'self'"))

This will be especially important when Spring Security 4.1 is released which will provide a simple DSL for adding CSP (this is not yet pushed to master). See SEC-2117 for tracking. In that case something like this will prevent the LiveReload from working in the browser:

http
    .headers()
        .csp()
            .defaultSrc().self();

This can be worked around using something like this:

http
    .headers()
        .csp()
            .defaultSrc().self().sources("ws://127.0.0.1:35729");

However, this is not ideal since this would not be suitable for production.

Will it be possible to add the .sources("ws...") element after the fact?

i.e the user types:

http
    .headers()
        .csp()
            .defaultSrc().self();

And if devtools is running we change it to include sources("ws://127.0.0.1:35729").

@philwebb I think part of this issue will be to figure out how best to make this work.

One feature I have been considering is adding a hook into Spring Security that allows modifying any arbitrary HttpSecurity instance. This feature would be an ideal candidate for that. Not to mention it would make some of the other features in boot more useful. For example, the security properties could apply to any HttpSecurity instance rather than just the ones boot creates which are often times ignored once the user does anything with web security.

Alternatively it may be possible to do this with a generic HttpServletResponseWrapper that checks the headers.

I figured I ask in case you needed to add some hook before Spring Security 4.1 is GA

@philwebb Thanks for checking. I will be sure to coordinate between the two projects to ensure Boot has a hook to make this possible.

PS: I went ahead and created SEC-2117 to track this

We never ended up creating a DSL for CSP & do not have plans for doing so since CSP is a moving target. I'm not sure how feasible this feature is without the DSL within Spring Security. One option might be to use a servlet Filter that wraps the response and customizes the header if it is written.

@rwinch I thought this added that?

@mbhave It added very basic support. There is just a value attribute but nothing like what was described above. For example it looks like this:

.headers()
    .contentSecurityPolicy("script-src 'self' https://trustedscripts.example.com; object-src https://trustedplugins.example.com; report-uri /csp-report-endpoint/");

I see. I think we should close this issue in that case.