农民工吹嘘 發表於 2025-12-15 16:47:00

防止跨站脚本攻击(XSS)(完整版HTTP安全响应头-CSP)

<h2>一、CPS简介</h2>
<p>Content-Security-Policy(CSP,内容安全策略)是一种由浏览器实施的安全机制,用于<strong>防止跨站脚本攻击(XSS)</strong>、<strong>数据注入攻击</strong>和<strong>点击劫持</strong>等常见 Web 安全威胁。</p>
<p>它通过<strong>白名单机制</strong>控制网页可以加载和执行哪些资源,从而有效减少恶意代码的执行机会。</p>
<h2>二、核心作用</h2>
<h3><strong>1、防止 XSS 攻击</strong></h3>
<p>禁止内联脚本执行,限制脚本只能从可信域名加载,即使攻击者注入恶意脚本,也无法执行。</p>
<h3><strong>2、控制资源加载来源</strong></h3>
<p>可限制图片、样式、字体、iframe、Ajax 请求等资源的来源,防止加载恶意内容。</p>
<h3><strong>3、防止数据泄露和点击劫持</strong></h3>
<p>通过限制表单提交目标、iframe 嵌入来源等方式,增强页面行为的安全性。</p>
<h2>三、CSP 的设置方式</h2>
<h3><strong>1、通过 HTTP 响应头设置(推荐)</strong></h3>
<p>示例:</p>
<pre class="language-perl highlighter-hljs" data-dark-theme="true"><code>&nbsp;Content-Security-Policy: script-src 'self'; object-src 'none'; img-src * data:;</code></pre>
<p>含义:</p>
<ul>
<li>
<p>只允许加载当前域名的脚本;</p>
</li>
<li>
<p>禁止加载任何&nbsp;<code>&lt;object&gt;</code>&nbsp;标签资源;</p>
</li>
<li>
<p>图片可从任意来源加载,包括 data URI。</p>
</li>
</ul>
<h2>四、配置说明</h2>
<h3>1、常用指令(Directive)说明</h3>
<div class="table-wrapper">
<table>
<thead>
<tr>
<th>指令</th>
<th>功能</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>default-src</code></td>
<td>默认资源加载策略(其他未指定指令的 fallback)</td>
</tr>
<tr>
<td><code>script-src</code></td>
<td>控制 JavaScript 的来源</td>
</tr>
<tr>
<td><code>style-src</code></td>
<td>控制 CSS 的来源</td>
</tr>
<tr>
<td><code>img-src</code></td>
<td>控制图片的来源</td>
</tr>
<tr>
<td><code>connect-src</code></td>
<td>控制 Ajax、WebSocket 等连接的目标</td>
</tr>
<tr>
<td><code>frame-src</code></td>
<td>控制 iframe 的来源</td>
</tr>
<tr>
<td><code>form-action</code></td>
<td>限制表单提交的目标地址</td>
</tr>
<tr>
<td><code>report-uri</code>&nbsp;/&nbsp;<code>report-to</code></td>
<td>设置违规报告接收地址,用于安全监控</td>
</tr>
</tbody>
</table>
</div>
<h3>2、指令值(Source)说明</h3>
<div class="table-wrapper">
<table>
<thead>
<tr>
<th>值</th>
<th>含义</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>'self'</code></td>
<td>只允许同源资源</td>
</tr>
<tr>
<td><code>'none'</code></td>
<td>禁止任何资源</td>
</tr>
<tr>
<td><code>'unsafe-inline'</code></td>
<td>允许内联脚本/样式(⚠️降低安全性)</td>
</tr>
<tr>
<td><code>'unsafe-eval'</code></td>
<td>允许使用&nbsp;<code>eval()</code>&nbsp;等动态执行代码(⚠️高风险)</td>
</tr>
<tr>
<td><code>https://example.com</code></td>
<td>允许指定域名</td>
</tr>
<tr>
<td><code>nonce-&lt;随机值&gt;</code></td>
<td>仅允许带有匹配&nbsp;<code>nonce</code>&nbsp;属性的脚本</td>
</tr>
<tr>
<td><code>sha256-&lt;哈希值&gt;</code></td>
<td>仅允许哈希匹配的内联脚本</td>
</tr>
</tbody>
</table>
</div>
<h2>五、注意事项</h2>
<h3>1、生产前必做,仅报告模式</h3>
<p>先在 Content-Security-Policy-Report-Only 头里跑 1-3 天,只记录不阻断:</p>
<p>nginx配置如下:</p>
<pre class="language-perl highlighter-hljs" data-dark-theme="true"><code>&nbsp;add_header Content-Security-Policy-Report-Only
"default-src 'self'; script-src 'self' https://static.xxx.com; report-uri /csp-report" always;</code></pre>
<p>观察 /csp-report 接收到的 JSON 违规日志,确认无合法资源被误杀后,再改成正式的 Content-Security-Policy 头 。</p>
<h3>2、script-src 没有nonce/hash 不能使用&nbsp;'unsafe-inline'</h3>
<p>否则会导致所有内联 &lt;script&gt;alert(1)&lt;/script&gt; 和 DOM 级 element.onclick = ... 放行。</p>
<p>攻击示例:</p>
<pre class="language-bash highlighter-hljs" data-dark-theme="true"><code>&nbsp;#请求
https://victim.com/search?q=
alert(document.cookie)</code></pre>
<pre class="language-perl highlighter-hljs" data-dark-theme="true"><code>&nbsp;#返回结果
搜索关键词:alert(document.cookie)</code></pre>
<p>错误配置示例:</p>
<pre class="language-perl highlighter-hljs" data-dark-theme="true"><code>&nbsp;add_header Content-Security-Policy "
default-src 'self';
script-src'self'data:;</code></pre>
<h3>&nbsp;3、script-src 不能允许&nbsp;data</h3>
<p>否则会导致 data:text/javascript,alert(1) 这种 Base64 内嵌脚本会被执行。<br>攻击者只需注入 &lt;script src="data:text/javascript,..."&gt; 即可完成 XSS,完全绕过域名白名单。</p>
<p>错误配置示例:</p>
<pre class="language-perl highlighter-hljs" data-dark-theme="true"><code>&nbsp;add_header Content-Security-Policy "
default-src 'self';
script-src'self' 'unsafe-inline';</code></pre>
<h2>六、服务器配置示例</h2>
<h3>1、NGINX配置示例</h3>
<p>在 server {} 块里加一行:</p>
<pre class="language-perl highlighter-hljs" data-dark-theme="true"><code>&nbsp;server {
listen 80;
server_name example.com;
# 全部响应都附加 CSP
add_header Content-Security-Policy "
default-src 'self' localhost:443 'unsafe-inline' 'unsafe-eval' blob: data: ;
sscript-src 'self' 'unsafe-inline' 'unsafe-eval';;
style-src   'self' https://fonts.googleapis.com;
img-src   'self' data: https:;
font-src    'self' https://fonts.gstatic.com;
object-src'none';
frame-ancestors 'self';
upgrade-insecure-requests;
" always;
location / {
proxy_pass http://127.0.0.1:8080;
# 其他代理头省略
}
}</code></pre>
<p>重启 Nginx 后,所有 HTML 响应都会带上该头字段 。</p>
<h3>2、Tomcat配置示例</h3>
<p>修改&nbsp;<code>conf/web.xml</code>,追加全局过滤器:</p>
<pre class="language-xml highlighter-hljs" data-dark-theme="true"><code>&nbsp;HttpHeaderSecurityFilter
org.apache.catalina.filters.HttpHeaderSecurityFilter
content-security-policy
default-src 'self';
script-src'self' 'unsafe-inline';
style-src   'self' 'unsafe-inline';
img-src   'self' data:;
object-src'none';
frame-ancestors 'self';
HttpHeaderSecurityFilter
/*</code></pre>
<p>重启 Tomcat 后,所有响应自动携带 CSP 头</p>
<h3>3、Spring Boot 示例</h3>
<pre class="language-java highlighter-hljs" data-dark-theme="true"><code>public class SecurityConfig {
@Bean
SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.headers(headers -&gt; headers
.contentSecurityPolicy(csp -&gt; csp.policyDirectives(
"default-src 'self'; " +
"script-src'self' https://cdn.jsdelivr.net; " +
"style-src   'self' https://fonts.googleapis.com; " +
"img-src   'self' data: https:; " +
"font-src    'self' https://fonts.gstatic.com; " +
"object-src'none'; " +
"frame-ancestors 'self'; " +
"upgrade-insecure-requests;")));
return http.build();
}
}</code></pre>
<p>Spring Boot 3.x 可用,启动后观察响应头已含&nbsp;<code>Content-Security-Policy</code></p>
<p>原文链接:https://www.cnblogs.com/ljbguanli/p/19113503</p>

</div>
<div id="MySignature" role="contentinfo">
    无论风雨,和自己一决胜负吧<br><br>
来源:https://www.cnblogs.com/aerfazhe/p/19353396
頁: [1]
查看完整版本: 防止跨站脚本攻击(XSS)(完整版HTTP安全响应头-CSP)