I am finding it difficult to understand an error thrown by my app when trying to invoke a REST API.
My app, a pure HTML, JavaScript based using jQuery, is running in Jetty server. The server has implemented Content-Security-Policy:
Custom HTTP headers to be added to our responses: Content-Security-Policy:
default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; connect-src 'self';
img-src 'self' data:; style-src 'self' 'unsafe-inline'; base-uri 'self';
frame-ancestors 'self'; font-src 'self';frame-src 'self'|X-Frame-Options:
SAMEORIGIN|X-Content-Type-Options: nosniff|X-XSS-Protection: 1; mode=block|
Referrer-Policy: strict-origin|Feature-Policy: 'none'|Strict-Transport-Security:
max-age=63072000; includeSubDomains; preload
I understand this part. Anyone trying to access my app has to adhere to these restrictions.
However, the JavaScript code in my app tries to call a Spring Boot REST API running on same Linux VM (http://localhost:8080/... or http://server-host-name:8080/...). When doing so, I get Content Security Policy violated when accessing http://localhost:8080...: content-src 'self'.This confuses me. Trying to access my app in Jetty without adhering to the security policy should raise error. But why would it throw an error when app in Jetty it is calling a Spring Boot API which doesn't have any such restriction?
Do I need to relax the Content Security Policy restriction on Jetty server? If so, why?
Summary:
REST API: Spring Boot HTTP API running on same Linux VM
Jetty Server: CSP restriction as mentioned above
JavaScript app in Jetty: Calling Spring Boot API
Briefly: you have to add http://localhost:8080 to the default-src directive.
Tl; DR;: the 'self' token is insidious, because you intuitively endow him with powers that he fails to fulfill.
Browsers substisute the 'self' token with the "tuple origin" (scheme + host_name + port_number) of the page URL from the browser's address bar, and then they add some CSP-specific magic:
ws: + host_name + ws_standard_portws: to wss: and http: to https: in CSP3-browsersSo, what do we have:
connect-src directive, therefore browser uses default-src as fallback.default-src 'self' to the default-src http://your_domain.com:80 or default-src https://your_domain.com:443 (depending on how you load the page).As you can see both of these do not allow http://localhost:8080. Although actually localhost is an alias of the your_domain.com, but CSP does not know this, and just blocking because of mismatch host_name + port_number.
But if you will load app with the http://localhost:8080/your_app_path url, fetch to REST API will be allowed because covered by 'self'