<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>CSP on 飞鸽跳转</title><link>https://feige301.com/zh-cn/tags/csp/</link><description>Recent content in CSP on 飞鸽跳转</description><generator>Hugo</generator><language>zh-CN</language><lastBuildDate>Sat, 18 Apr 2026 01:10:30 +0800</lastBuildDate><atom:link href="https://feige301.com/zh-cn/tags/csp/index.xml" rel="self" type="application/rss+xml"/><item><title>Content-Security-Policy (CSP)：反JS注入的最后防线</title><link>https://feige301.com/zh-cn/posts/2026/content-security-policy-csp-anti-js-injection-last-line-of-defense-http-hijacking.html</link><pubDate>Sat, 18 Apr 2026 01:10:30 +0800</pubDate><guid>https://feige301.com/zh-cn/posts/2026/content-security-policy-csp-anti-js-injection-last-line-of-defense-http-hijacking.html</guid><description>&lt;p>我们习惯于在浏览器中输入一个网址，然后期待内容能够安全、完整地呈现在眼前。然而，这其中存在诸多不确定因素。在用户请求一个网页到最终浏览器渲染的整个链路上，数据包可能要经过多个网络节点，其中就包括一些“中间设备”或“流量网关”。这些设备在设计上可能为了路由优化、流量统计、内容缓存等目的，但在某些情况下，它们也可能成为未经授权修改数据内容的源头。&lt;/p>
&lt;p>想象一下，你发出的一个信件，在邮寄过程中被中途打开，并且被悄悄地塞入了一张与你本意无关的广告传单。当你收到这封信时，它看起来似乎没问题，但内容却已经不再纯粹。在网络世界中，这种现象被我们称之为“HTTP劫持”（HTTP Hijacking）。&lt;/p>
&lt;h3 id="http劫持隐形的威胁与用户痛点">
 HTTP劫持：隐形的威胁与用户痛点
 &lt;a class="anchor" href="#http%e5%8a%ab%e6%8c%81%e9%9a%90%e5%bd%a2%e7%9a%84%e5%a8%81%e8%83%81%e4%b8%8e%e7%94%a8%e6%88%b7%e7%97%9b%e7%82%b9">#&lt;/a>
&lt;/h3>
&lt;p>HTTP劫持，顾名思义，是指在HTTP通信过程中，网络流量被拦截或修改的行为。虽然HTTPS协议在很大程度上解决了传输过程中的内容篡改问题，但并非所有的网络流量都严格使用HTTPS，尤其是在一些初次连接、跳转或特定资源加载的场景。当HTTP劫持发生时，攻击者或某些“中间设备”可能会在合法的网页内容中注入额外的代码，最常见的就是JavaScript代码。&lt;/p>
&lt;p>这种未经授权的JavaScript注入可能导致一系列问题：&lt;/p>
&lt;ul>
&lt;li>&lt;strong>广告弹窗和强制跳转：&lt;/strong> 用户访问的页面可能突然弹出无关广告，或者被强制跳转到其他站点，严重干扰用户体验。&lt;/li>
&lt;li>&lt;strong>数据窃取：&lt;/strong> 恶意注入的JavaScript可以读取用户的Cookie、会话信息，甚至在用户输入密码时捕获这些敏感数据。&lt;/li>
&lt;li>&lt;strong>页面内容篡改：&lt;/strong> 原始页面结构和内容可能被改变，显示错误或虚假信息，影响网站的品牌形象和可信度。&lt;/li>
&lt;li>&lt;strong>功能破坏：&lt;/strong> 注入的代码可能与原有页面逻辑冲突，导致页面功能异常或崩溃。&lt;/li>
&lt;/ul>
&lt;p>对于网站管理员、运维人员和开发者而言，这些问题带来巨大的困扰。用户体验受损、数据安全面临风险、业务流程被中断，甚至可能面临合规性挑战。这些都指向了一个核心痛点：如何确保用户在与网站交互时，所看到和执行的代码是完全可信的，且未经任何第三方篡改？尤其是在面对“局部局域网环境”中可能出现的“某地区运营商”进行流量修改，或因自身业务需求涉及多域名跳转的场景下，如何保障整个链路的安全性与纯净性，成为了迫切需要解决的技术难题。&lt;/p>
&lt;p>解决这一痛点，需要一种机制，它不仅能够检测到篡改，更重要的是，能够在客户端层面对恶意注入的代码进行“免疫”，确保浏览器只执行我们允许的、来自可信源的代码。这正是Content-Security-Policy（CSP）所能发挥的关键作用。&lt;/p>
&lt;h2 id="content-security-policy-csp客户端反注入的最后防线">
 Content-Security-Policy (CSP)：客户端反注入的最后防线
 &lt;a class="anchor" href="#content-security-policy-csp%e5%ae%a2%e6%88%b7%e7%ab%af%e5%8f%8d%e6%b3%a8%e5%85%a5%e7%9a%84%e6%9c%80%e5%90%8e%e9%98%b2%e7%ba%bf">#&lt;/a>
&lt;/h2>
&lt;p>Content-Security-Policy (CSP) 是一种由Web服务器向浏览器发送的HTTP响应头。它的核心理念是让网站开发者能够明确地告诉浏览器：哪些资源（如脚本、样式表、图片、字体、媒体文件等）是可信的，以及它们可以从哪些源加载。如果浏览器尝试加载或执行不符合这些策略的资源，它将会被阻止。&lt;/p>
&lt;p>可以把CSP想象成一个网站的“安全保镖”，它站在用户浏览器的门口，手持一份详细的“白名单”。任何试图进入浏览器（即被加载或执行）的资源，都必须经过这个保镖的核对。如果资源不在白名单上，或者来自非授权的来源，保镖就会立即将其拦截在外，确保只有经过批准的“访客”才能进入。&lt;/p>
&lt;h3 id="csp的核心工作原理">
 CSP的核心工作原理
 &lt;a class="anchor" href="#csp%e7%9a%84%e6%a0%b8%e5%bf%83%e5%b7%a5%e4%bd%9c%e5%8e%9f%e7%90%86">#&lt;/a>
&lt;/h3>
&lt;p>CSP通过定义一系列指令（directives）来工作，每个指令都指定了特定类型的资源可以从哪些源加载。例如：&lt;/p>
&lt;ul>
&lt;li>&lt;code>script-src&lt;/code>：定义JavaScript脚本的允许加载源。&lt;/li>
&lt;li>&lt;code>style-src&lt;/code>：定义CSS样式表的允许加载源。&lt;/li>
&lt;li>&lt;code>img-src&lt;/code>：定义图片的允许加载源。&lt;/li>
&lt;li>&lt;code>default-src&lt;/code>：作为所有未明确指定指令的默认回退策略。&lt;/li>
&lt;li>&lt;code>connect-src&lt;/code>：定义XMLHttpRequest (XHR)、WebSocket等连接的允许目标。&lt;/li>
&lt;li>&lt;code>frame-src&lt;/code>：定义&lt;code>&amp;lt;iframe&amp;gt;&lt;/code>标签中内容的允许加载源。&lt;/li>
&lt;/ul>
&lt;p>这些指令可以指定多种源，例如：&lt;/p>
&lt;ul>
&lt;li>&lt;code>'self'&lt;/code>：允许从当前域名加载资源。&lt;/li>
&lt;li>&lt;code>*.example.com&lt;/code>：允许从&lt;code>example.com&lt;/code>及其所有子域加载资源。&lt;/li>
&lt;li>&lt;code>https://cdn.example.com&lt;/code>：只允许从特定的CDN安全地加载资源。&lt;/li>
&lt;li>&lt;code>'none'&lt;/code>：禁止加载任何资源。&lt;/li>
&lt;li>&lt;code>'unsafe-inline'&lt;/code>：允许行内脚本或样式（强烈不推荐，除非无法避免）。&lt;/li>
&lt;li>&lt;code>'unsafe-eval'&lt;/code>：允许使用&lt;code>eval()&lt;/code>等从字符串创建代码的方法（强烈不推荐）。&lt;/li>
&lt;li>&lt;code>'nonce-&amp;lt;base64-value&amp;gt;'&lt;/code>：允许带有匹配nonce属性的行内脚本或样式。&lt;/li>
&lt;li>&lt;code>'sha256-&amp;lt;base64-hash&amp;gt;'&lt;/code>：允许与指定哈希值匹配的行内脚本或样式。&lt;/li>
&lt;/ul>
&lt;p>当浏览器接收到一个包含CSP头的HTTP响应后，它会解析这些策略，并严格遵守。如果页面中存在一个&lt;code>&amp;lt;script&amp;gt;&lt;/code>标签，而其&lt;code>src&lt;/code>属性指向的域名不在&lt;code>script-src&lt;/code>指令的白名单中，或者它是一个未被&lt;code>nonce&lt;/code>或&lt;code>hash&lt;/code>授权的行内脚本，浏览器就会拒绝执行该脚本。&lt;/p>
&lt;h3 id="csp抵抗http劫持的有效手段">
 CSP：抵抗HTTP劫持的有效手段
 &lt;a class="anchor" href="#csp%e6%8a%b5%e6%8a%97http%e5%8a%ab%e6%8c%81%e7%9a%84%e6%9c%89%e6%95%88%e6%89%8b%e6%ae%b5">#&lt;/a>
&lt;/h3>
&lt;p>回到HTTP劫持的问题，如果“中间设备”或“某地区运营商”在HTTP响应中注入了未经授权的JavaScript代码，无论这些代码是来自一个外部的恶意域名，还是直接作为行内脚本被插入，CSP都能发挥其防御作用。&lt;/p>
&lt;p>例如，一个网站期望其所有JavaScript都从自己的域名 (&lt;code>example.com&lt;/code>) 和一个特定的CDN (&lt;code>cdn.example.com&lt;/code>) 加载。它可以在响应头中设置如下CSP：&lt;/p>
&lt;pre tabindex="0">&lt;code>Content-Security-Policy: default-src &amp;#39;self&amp;#39;; script-src &amp;#39;self&amp;#39; https://cdn.example.com; object-src &amp;#39;none&amp;#39;; base-uri &amp;#39;self&amp;#39;;
&lt;/code>&lt;/pre>&lt;p>这条策略告诉浏览器：&lt;/p>
&lt;ol>
&lt;li>默认所有资源（&lt;code>default-src&lt;/code>）只能从当前域名（&lt;code>'self'&lt;/code>）加载。&lt;/li>
&lt;li>JavaScript脚本（&lt;code>script-src&lt;/code>）只能从当前域名或&lt;code>https://cdn.example.com&lt;/code>加载。&lt;/li>
&lt;li>插件（&lt;code>object-src&lt;/code>）一律禁止加载。&lt;/li>
&lt;li>页面的&lt;code>base&lt;/code>标签的URL（&lt;code>base-uri&lt;/code>）只能是当前域名。&lt;/li>
&lt;/ol>
&lt;p>现在，假设一个“中间设备”尝试注入一个来自&lt;code>http://malicious-ad.com/inject.js&lt;/code>的脚本，或者直接在HTML中插入 &lt;code>&amp;lt;script&amp;gt;alert('You are hijacked!');&amp;lt;/script&amp;gt;&lt;/code> 这样的行内脚本。&lt;/p></description></item></channel></rss>