内容安全策略和 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:
那么,我们有什么:
- 您的应用程序使用 fetch 来访问 Spring Boot REST API,缺少的
connect-src
指令应该涵盖它,因此浏览器使用 default-src
作为后备。
- 浏览器将
default-src 'self'
转换为 default-src http://your_domain.com:80
或 default-src https://your_domain.com:443
(取决于您加载页面的方式)。
如您所见,这两个都不允许 http://localhost:8080
。虽然实际上 localhost
是 your_domain.com
的别名,但 CSP 不知道这一点,只是因为不匹配 host_name + [=41 而阻塞=]port_number.
但是如果您将使用 http://localhost:8080/your_app_path
url 加载应用程序,将允许提取到 REST API,因为被 'self'
覆盖
我发现很难理解我的应用在尝试调用 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:
那么,我们有什么:
- 您的应用程序使用 fetch 来访问 Spring Boot REST API,缺少的
connect-src
指令应该涵盖它,因此浏览器使用default-src
作为后备。 - 浏览器将
default-src 'self'
转换为default-src http://your_domain.com:80
或default-src https://your_domain.com:443
(取决于您加载页面的方式)。
如您所见,这两个都不允许 http://localhost:8080
。虽然实际上 localhost
是 your_domain.com
的别名,但 CSP 不知道这一点,只是因为不匹配 host_name + [=41 而阻塞=]port_number.
但是如果您将使用 http://localhost:8080/your_app_path
url 加载应用程序,将允许提取到 REST API,因为被 'self'