内容安全策略和 REST API 调用 - 它是如何工作的?

Content Security Policy and REST API call - how does it work?

我发现很难理解我的应用在尝试调用 REST 时抛出的错误 API。

我的应用程序,一个纯HTML,JavaScript基于jQuery,在Jetty服务器中是运行。服务器已实现 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

这部分我明白了。任何试图访问我的应用程序的人都必须遵守这些限制。

但是,我的应用程序中的 JavaScript 代码尝试在同一 Linux VM (http:/ /localhost:8080/... 或 http://server-host-name:8080/...)。这样做时,我得到 Content Security Policy violated when accessing http://localhost:8080...: content-src 'self'。这让我很困惑。在不遵守安全策略的情况下尝试在 Jetty 中访问我的应用程序应该会引发错误。但是为什么当 Jetty 中的应用程序调用没有任何此类限制的 Spring Boot API 时它会抛出错误?

我需要放宽对 Jetty 服务器的内容安全策略限制吗?如果是,为什么?

总结:
REST API:Spring 在同一 Linux VM
上启动 HTTP API 运行 Jetty 服务器:CSP 限制如上所述
JavaScript Jetty 中的应用程序:调用 Spring 启动 API

简述:你必须在default-src指令中添加http://localhost:8080

Tl; DR;'self' 令牌是阴险的,因为你凭直觉赋予他无法实现的权力。

浏览器将 'self' 标记替换为“元组来源”(方案 + host_name + port_number) 从浏览器的地址栏访问页面 URL,然后他们添加了一些 CSP 特定的魔法:

  • 允许 ws: + host_name + ws_standard_port
  • 允许在 CSP3 浏览器中将 ws: 升级到 wss: 并将 http: 升级到 https:

那么,我们有什么:

  1. 您的应用程序使用 fetch 来访问 Spring Boot REST API,缺少的 connect-src 指令应该涵盖它,因此浏览器使用 default-src 作为后备。
  2. 浏览器将 default-src 'self' 转换为 default-src http://your_domain.com:80default-src https://your_domain.com:443(取决于您加载页面的方式)。

如您所见,这两个都不允许 http://localhost:8080。虽然实际上 localhostyour_domain.com 的别名,但 CSP 不知道这一点,只是因为不匹配 host_name + [=41 而阻塞=]port_number.

但是如果您将使用 http://localhost:8080/your_app_path url 加载应用程序,将允许提取到 REST API,因为被 'self'

覆盖