<?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>前端安全 on Last Stand</title><link>https://amatsuzero.github.io/LastStand/tags/%E5%89%8D%E7%AB%AF%E5%AE%89%E5%85%A8/</link><description>Recent content in 前端安全 on Last Stand</description><generator>Hugo</generator><language>zh-cn</language><lastBuildDate>Thu, 07 Aug 2025 00:00:00 +0800</lastBuildDate><atom:link href="https://amatsuzero.github.io/LastStand/tags/%E5%89%8D%E7%AB%AF%E5%AE%89%E5%85%A8/index.xml" rel="self" type="application/rss+xml"/><item><title>XSS防御</title><link>https://amatsuzero.github.io/LastStand/posts/frontend/security/security-001/</link><pubDate>Wed, 02 Oct 2024 00:00:00 +0800</pubDate><guid>https://amatsuzero.github.io/LastStand/posts/frontend/security/security-001/</guid><description>&lt;h2 id="一简述"&gt;一、简述&lt;/h2&gt;
&lt;p&gt;跨站脚本（Cross-site scripting，简称为：CSS, 但这会与层叠样式表（Cascading Style Sheets，CSS）的缩写混淆。因此，跨站脚本攻击缩写为XSS）是一种网站应用程序的安全漏洞攻击。&lt;/p&gt;
&lt;p&gt;XSS攻击通常指的是通过利用网页开发时留下的漏洞，通过巧妙的方法注入恶意指令代码到网页，使用户加载并执行攻击者恶意制造的网页程序。这些恶意网页程序通常是JavaScript，但实际上也可以包括Java、 VBScript、 LiveScript、ActiveX、 Flash 或者甚至是普通的HTML。攻击成功后，攻击者可能得到包括但不限于更高的权限（如执行一些操作）、私密网页内容、会话和cookie等各种内容。&lt;/p&gt;
&lt;h2 id="二xss类型"&gt;二、XSS类型&lt;/h2&gt;
&lt;p&gt;最常见的几种分类：&lt;strong&gt;反射型（非持久型）XSS&lt;/strong&gt;、&lt;strong&gt;存储型（持久型）XSS&lt;/strong&gt;、&lt;strong&gt;DOM型XSS&lt;/strong&gt;、&lt;strong&gt;通用型XSS&lt;/strong&gt;、&lt;strong&gt;突变型XSS&lt;/strong&gt;。&lt;/p&gt;
&lt;h3 id="反射型xss"&gt;反射型XSS&lt;/h3&gt;
&lt;p&gt;反射型XSS只是简单的把用户输入的数据从服务器反射给用户浏览器，要利用这个漏洞，攻击者必须以某种方式诱导用户访问一个精心设计的URL（恶意链接），才能实施攻击。&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-php" data-lang="php"&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:#a6e22e"&gt;php&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;echo&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;lt;p&amp;gt;hello,&lt;/span&gt;&lt;span style="color:#e6db74"&gt;$_GET[&amp;#39;user&amp;#39;]&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;lt;/p&amp;gt;&amp;#34;&lt;/span&gt;; &lt;span style="color:#75715e"&gt;?&amp;gt;&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;如果未做防范XSS，用户名设为&lt;code&gt;&amp;lt;script&amp;gt;alert(&amp;quot;Tz&amp;quot;)&amp;lt;/script&amp;gt;&lt;/code&gt;,则会执行预设好的JavaScript代码。&lt;/p&gt;
&lt;h4 id="漏洞成因"&gt;漏洞成因&lt;/h4&gt;
&lt;p&gt;当用户的输入或者一些用户可控参数未经处理地输出到页面上，就容易产生XSS漏洞。主要场景有以下几种：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;将不可信数据插入到HTML标签之间时；// 例如div, p, td；&lt;/li&gt;
&lt;li&gt;将不可信数据插入到HTML属性里时；// 例如：&lt;code&gt;&amp;lt;div width=$INPUT&amp;gt;&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;将不可信数据插入到SCRIPT里时；// 例如：&lt;code&gt;&amp;lt;script&amp;gt;var message = ” $INPUT “;&amp;lt;/script&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;还有插入到Style属性里的情况，同样具有一定的危害性；// 例如&lt;code&gt;&amp;lt;span style=” property : $INPUT ”&amp;gt;&amp;lt;/span&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;将不可信数据插入到HTML URL里时，// 例如：&lt;code&gt;&amp;lt;a href=”[http://www.abcd.com?param=](http://www.ccc.com/?param=) $INPUT ”&amp;gt;&amp;lt;/a&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;使用富文本时，没有使用XSS规则引擎进行编码过滤。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;对于以上的几个场景，若服务端或者前端没有做好防范措施，就会出现漏洞隐患。&lt;/strong&gt;&lt;/p&gt;
&lt;h4 id="攻击流程"&gt;攻击流程&lt;/h4&gt;
&lt;p&gt;反射型XSS通常出现在搜索等功能中，需要被攻击者点击对应的链接才能触发，且受到XSS Auditor(chrome内置的XSS保护)、NoScript等防御手段的影响较大，所以它的危害性较存储型要小。&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://amatsuzero.github.io/LastStand/posts/frontend/security/security-001/image-01.webp"&gt;&lt;/p&gt;
&lt;h3 id="存储型xss"&gt;存储型XSS&lt;/h3&gt;
&lt;p&gt;​ 存储型（或 HTML 注入型/持久型）XSS 攻击最常发生在由社区内容驱动的网站或 Web 邮件网站，不需要特制的链接来执行。黑客仅仅需要提交 XSS 漏洞利用代码（反射型XSS通常只在url中）到一个网站上其他用户可能访问的地方。这些地区可能是&lt;code&gt;博客评论，用户评论，留言板，聊天室，HTML 电子邮件，wikis&lt;/code&gt;，和其他的许多地方。一旦用户访问受感染的页，执行是自动的。&lt;/p&gt;
&lt;h4 id="漏洞成因-1"&gt;漏洞成因&lt;/h4&gt;
&lt;p&gt;​ 存储型XSS漏洞的成因与反射型的根源类似，不同的是恶意代码会被保存在服务器中，导致其它用户（前端）和管理员（前后端）在访问资源时执行了恶意代码，用户访问服务器-跨站链接-返回跨站代码。&lt;/p&gt;
&lt;h4 id="攻击流程-1"&gt;攻击流程&lt;/h4&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://amatsuzero.github.io/LastStand/posts/frontend/security/security-001/image-02.webp"&gt;&lt;/p&gt;
&lt;h3 id="dom型xss"&gt;DOM型XSS&lt;/h3&gt;
&lt;p&gt;通过修改页面的DOM节点形成的XSS，称之为DOM Based XSS。&lt;/p&gt;</description></item><item><title>CSRF攻击</title><link>https://amatsuzero.github.io/LastStand/posts/frontend/security/security-002/</link><pubDate>Wed, 02 Oct 2024 00:00:00 +0800</pubDate><guid>https://amatsuzero.github.io/LastStand/posts/frontend/security/security-002/</guid><description>&lt;h2 id="csrf是什么"&gt;CSRF是什么&lt;/h2&gt;
&lt;p&gt;CSRF（Cross-site request forgery）跨站请求伪造：&lt;strong&gt;攻击者诱导受害者进入第三方网站，在第三方网站中，向被攻击网站发送跨站请求，利用受害者在被攻击网站已经获取的注册凭证，绕过后台的用户验证，达到冒充用户对被攻击的网站执行某项操作的目的。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;一个典型的CSRF攻击有着如下的流程：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;受害者登录a.com，并保留了登录凭证（Cookie）。&lt;/li&gt;
&lt;li&gt;攻击者引诱受害者访问了b.com。&lt;/li&gt;
&lt;li&gt;b.com 向 a.com 发送请求。&lt;/li&gt;
&lt;li&gt;a.com接收到请求后，对请求进行验证，并确认是受害者的凭证，误以为是受害者自己发送的请求。&lt;/li&gt;
&lt;li&gt;a.com以受害者的名义执行了这个请求。&lt;/li&gt;
&lt;li&gt;攻击完成，攻击者在受害者不知情的情况下，冒充受害者，让a.com执行了自己定义的操作。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="csrf的特点"&gt;CSRF的特点&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;攻击一般发起在第三方网站，而不是被攻击的网站。被攻击的网站无法防止攻击发生&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;攻击利用受害者在被攻击网站的登录凭证，冒充受害者提交操作；而不是直接窃取数据&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;整个过程攻击者并不能获取到受害者的登录凭证，仅仅是“冒用”&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;跨站请求可以用各种方式：图片URL、超链接、CORS、Form提交等等。&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="如何进行预防"&gt;如何进行预防&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;CSRF通常从第三方网站发起，被攻击的网站无法防止攻击发生，只能通过增强自己网站针对CSRF的防护能力来提升安全性。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;防止&lt;code&gt;csrf&lt;/code&gt;常用方案如下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;阻止不明外域的访问&lt;br&gt;&lt;/li&gt;
&lt;li&gt;同源检测&lt;/li&gt;
&lt;li&gt;Samesite Cookie&lt;/li&gt;
&lt;li&gt;提交时要求附加本域才能获取的信息&lt;br&gt;&lt;/li&gt;
&lt;li&gt;CSRF Token&lt;/li&gt;
&lt;li&gt;双重Cookie验证&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="同源检测"&gt;同源检测&lt;/h3&gt;
&lt;p&gt;Cookie的同源和浏览器的同源策略有所区别：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;浏览器同源策略：协议、域名和端口都相同即同源；&lt;/li&gt;
&lt;li&gt;Cookie同源策略：域名相同即同源；&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;在HTTP协议中，每个异步请求都会携带两个header,用来标记来源域名：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Origin Header&lt;/li&gt;
&lt;li&gt;Referer Header&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;这两个Header在浏览器发起请求时，大多数情况会自动带上，并且不能由前端修改，服务器接收到后可以根据这两个Header确定来源的域名；&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;综上所述：&lt;/strong&gt; 同源验证是一个相对简单的防范方法，能够防范绝大多数的CSRF攻击。但这并不是万无一失的，&lt;strong&gt;对于安全性要求较高，或者有较多用户输入内容的网站，我们就要对关键的接口做额外的防护措施。&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id="samesite-cookie属性"&gt;Samesite Cookie属性&lt;/h3&gt;
&lt;p&gt;在&lt;strong&gt;Chrome 51&lt;/strong&gt;版本后，浏览器的 Cookie 新增加了一个SameSite属性，用来防止 CSRF 攻击。&lt;/p&gt;
&lt;p&gt;Cookie的Samesite属性用来限制第三方Cookie, 从而减少安全风险，它有三个值：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Set-Cookie: SameSite = Strict;&lt;/li&gt;
&lt;li&gt;Set-Cookie: SameSite = Lax;&lt;/li&gt;
&lt;li&gt;Set-Cookie: SameSite = None;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Strict：&lt;/strong&gt; 最为严格，完全禁止第三方Cookie, 跨站点时，任何情况都不发送Cookie;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Lax：&lt;/strong&gt; 限制稍微宽松，大多数情况下时不发送第三方Cookie的，除了a链接、预加载请求和GET表单；&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;None：&lt;/strong&gt; 关闭&lt;code&gt;SameSite&lt;/code&gt;属性，但必须同时设置&lt;code&gt;Secure&lt;/code&gt;属性，&lt;/p&gt;</description></item><item><title>https</title><link>https://amatsuzero.github.io/LastStand/posts/frontend/security/https/</link><pubDate>Wed, 02 Oct 2024 00:00:00 +0800</pubDate><guid>https://amatsuzero.github.io/LastStand/posts/frontend/security/https/</guid><description>&lt;p&gt;阅读本文之前，咱们先来看几道面试题:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;什么是&lt;code&gt;HTTPS&lt;/code&gt;？&lt;/li&gt;
&lt;li&gt;&lt;code&gt;HTTPS&lt;/code&gt;改进&lt;code&gt;HTTP&lt;/code&gt;存在的哪些问题？&lt;/li&gt;
&lt;li&gt;&lt;code&gt;HTTPS&lt;/code&gt;加密原理是什么？&lt;/li&gt;
&lt;li&gt;什么是&lt;code&gt;对称加密&lt;/code&gt;和&lt;code&gt;非对称加密&lt;/code&gt;？&lt;/li&gt;
&lt;li&gt;&lt;code&gt;HTTPS&lt;/code&gt;传输过程?&lt;/li&gt;
&lt;li&gt;什么是数字证书？为什么需要数字证书?&lt;/li&gt;
&lt;li&gt;为什么需要数字签名？&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;hellip;&lt;/p&gt;
&lt;p&gt;如果你能准确无误的回答以上问题，你可以不用继续往下面看了，如果不能，通过阅读这篇文章，我相信你肯定能完全掌握&lt;code&gt;HTTPS&lt;/code&gt;。好了废话不多说，我们开始。&lt;/p&gt;
&lt;h2 id="什么是-https"&gt;什么是 HTTPS&lt;/h2&gt;
&lt;p&gt;当我们在访问一个地址采用&lt;code&gt;HTTPS&lt;/code&gt;协议的&lt;code&gt;Web&lt;/code&gt;网站时，浏览器的地址栏内会出现一个带锁的标记，就像这样：&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://amatsuzero.github.io/LastStand/posts/frontend/security/https/image-01.webp"&gt;&lt;/p&gt;
&lt;p&gt;我们想要了解一个东西之前，我们得先知道它是什么，那么&lt;code&gt;HTTPS&lt;/code&gt;是什么呢？&lt;/p&gt;
&lt;p&gt;可能很多同学都能说道说道：“&lt;code&gt;HTTPS&lt;/code&gt;就是能够给我们的请求加密的一个东西”。的确，我们都知道，&lt;code&gt;HTTPS&lt;/code&gt;可以加密，但是很多同学的理解仅限于此，无法深层次的理解&lt;code&gt;HTTPS&lt;/code&gt;。那么到底什么是&lt;code&gt;HTTPS&lt;/code&gt;？&lt;/p&gt;
&lt;p&gt;&lt;code&gt;HTTPS&lt;/code&gt;是在&lt;code&gt;HTTP&lt;/code&gt;上建立&lt;code&gt;SSL&lt;/code&gt;加密层，并对传输数据进行加密，是&lt;code&gt;HTTP&lt;/code&gt;协议的安全版。 说得再简单一点，&lt;code&gt;HTTPS&lt;/code&gt;就是 &lt;code&gt;HTTP + SSL&lt;/code&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://amatsuzero.github.io/LastStand/posts/frontend/security/https/image-02.webp"&gt;&lt;/p&gt;
&lt;p&gt;哦明白了，原来&lt;code&gt;HTTPS&lt;/code&gt;就是“披着羊皮的狼”啊。&lt;code&gt;HTTP&lt;/code&gt;你肯定是理解的，如果不理解，建议先去阅读&lt;code&gt;HTTP&lt;/code&gt;相关知识。&lt;/p&gt;
&lt;p&gt;那&lt;code&gt;SSL&lt;/code&gt;又是什么呢？&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://amatsuzero.github.io/LastStand/posts/frontend/security/https/image-03.webp"&gt;&lt;/p&gt;
&lt;p&gt;我们都知道，&lt;code&gt;HTTP&lt;/code&gt;是应用层的协议，&lt;code&gt;HTTP&lt;/code&gt;是直接和&lt;code&gt;TCP&lt;/code&gt;通信的，当我们更换为&lt;code&gt;HTTPS&lt;/code&gt;的时候，它就演变成了，先和&lt;code&gt;SSL&lt;/code&gt;通信、然后再由&lt;code&gt;SSL&lt;/code&gt;和&lt;code&gt;TCP&lt;/code&gt;通信了。知道了这一流程，我们思考一下，加密过程是在哪个过程进行的？ 结果很显然，加密过程就是在&lt;code&gt;HTTP&lt;/code&gt;-&amp;gt;&lt;code&gt;SSL&lt;/code&gt;这一阶段实现的，所以&lt;code&gt;SSL&lt;/code&gt;简单来说，就是实现&lt;code&gt;HTTP&lt;/code&gt;的加密过程:&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://amatsuzero.github.io/LastStand/posts/frontend/security/https/image-04.webp"&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;对称加密&lt;/code&gt;和&lt;code&gt;非对称加密&lt;/code&gt;、&lt;code&gt;散列函数&lt;/code&gt;这些又是啥啊？没事后面会讲，这些概念你先记住咯。&lt;/p&gt;
&lt;h2 id="https-有什么用"&gt;HTTPS 有什么用&lt;/h2&gt;
&lt;p&gt;在讲明HTTPS的作用之前，我们先来看看&lt;code&gt;HTTP&lt;/code&gt;有哪些弊端：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;和服务器通信时，直接采用明文传输，那么明文内容有可能被挟持监听和篡改&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;由于&lt;code&gt;HTTP&lt;/code&gt;本身不具备加密的功能，所以无法做到对通信内容进行加密。也就是说，我们传输的方式，都是直接以明文的形式进行传输，这些明文数据会经过中间代理服务器、路由器、wifi热点、通信服务运营商等多个物理节点，相当于所有通信的数据都在网络中&lt;code&gt;裸奔&lt;/code&gt;，想想都刺激。&lt;/p&gt;
&lt;p&gt;那么显而易见，明文传输有什么缺陷呢？明文传输可能会导致&lt;code&gt;数据泄露&lt;/code&gt;、&lt;code&gt;数据篡改&lt;/code&gt;、&lt;code&gt;流量劫持&lt;/code&gt;、&lt;code&gt;钓鱼攻击&lt;/code&gt;等一系列危险。假设有这么一个场景，某一天，你的另一个女朋友过生日，于是你用浏览器登录了你的邮箱，想给她发送一封生日祝福的邮件。假如这个邮箱网站使用的是&lt;code&gt;HTTP&lt;/code&gt;协议，当你点击发送的时候，你的“祝福内容”（注意：是明文），被某个黑客拦截到，然后将这份“祝福内容”直接转发到你的“现任女朋友”，那后果简直不堪设想。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;和服务器通信时，无法验证身份&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;使用HTTP发起请求时，服务器不会验证请求方的身份，响应请求时，请求方也不会验证服务方的身份。说简单点就是，任何人都可以发起请求，同时，服务器只要接收到请求，不管对方是谁都会返回一个响应。所以任何人都可以伪造虚假服务器欺骗用户，实现“钓鱼欺诈”，用户无法察觉，这也是为啥以前我们的qq号老是被盗的原因。&lt;/p&gt;
&lt;p&gt;了解到HTTP这些缺陷之后，我们就自然知道了HTTPS到底有什么用：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;保证数据的安全性（加密我们的明文数据）&lt;/li&gt;
&lt;li&gt;保证数据的完整性&lt;/li&gt;
&lt;li&gt;身份认证&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="https如何加密ssl过程"&gt;HTTPS如何加密（SSL过程）&lt;/h2&gt;
&lt;p&gt;通过上面的内容，我们知道了&lt;code&gt;HTTPS&lt;/code&gt;能够对数据进行加密，那么它具体是如何加密的呢？&lt;/p&gt;
&lt;p&gt;这里我们需要先了解两种加密方式：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;对称加密&lt;/li&gt;
&lt;li&gt;非对称加密&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;别觉得它们会有多么难理解，心中坚信，一切计算机网络的知识都是&lt;code&gt;纸老虎&lt;/code&gt;。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="什么是对称加密"&gt;什么是对称加密&lt;/h2&gt;
&lt;p&gt;那么什么是&lt;code&gt;对称加密&lt;/code&gt;呢？&lt;/p&gt;
&lt;p&gt;简单说就是有一个密钥，它可以加密数据，也可以对加密后的数据进行解密。试想有这样一个场景：两个港口需要运送一批货物，发货方发货时，将货物装进集装箱并用一把锁将集装箱锁起来，收货方收到货物时，需要用同样的钥匙（不一定是同一把）将集装箱打开，从而取出货物。&lt;/p&gt;
&lt;p&gt;所以简单来说，对称加密就是通信双方都有一把同样的&lt;code&gt;钥匙&lt;/code&gt;，用于打开同一个&lt;code&gt;集装箱&lt;/code&gt;（解密），从而获取数据的一种方式:&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://amatsuzero.github.io/LastStand/posts/frontend/security/https/image-05.webp"&gt;&lt;/p&gt;
&lt;h2 id="https用对称加密可行吗"&gt;HTTPS用对称加密可行吗&lt;/h2&gt;
&lt;p&gt;如果通信双方（浏览器和服务器）都各自拥有同样的私钥，在发送方发送数据之前，将数据&lt;code&gt;锁&lt;/code&gt;（加密）起来，然后接收方再用私钥&lt;code&gt;解锁&lt;/code&gt;（解密），这样就能完美的保证通信的安全。但是关键的问题就在于，在通信之前，服务器或者浏览器如何同时拥有一把同样的私钥呢？我们来想想办法：&lt;/p&gt;
&lt;p&gt;1、服务器给浏览器传输私钥&lt;/p&gt;
&lt;p&gt;当浏览器发起请求到服务器时，服务器生成一个私钥，然后传输给浏览器，浏览器拿到之后，他们正式通信就开始用这一个私钥进行加密通信，不就行了？那么问题又来了，假设在传输私钥本身的过程中，被中间人挟持了怎么办？中间人拿到私钥之后，就可以解密通信双方的加密内容了，所以这样做肯定是不可行的。&lt;/p&gt;
&lt;p&gt;2、在浏览器里面预留服务器提供的私钥。如果我们浏览器一开始就预留了目标网站的私钥，那这样通信的时候，就只有天知地知你知我知了，这不就行了？但是问题的关键是，世界上的网站千千万，浏览器要预留全部&lt;code&gt;HTTPS&lt;/code&gt;协议网站的私钥，这显然不可能啊。&lt;/p&gt;
&lt;p&gt;很显然，以上两种假设，都不能实现我们想要的加密效果，所以&lt;code&gt;对称加密&lt;/code&gt;暂时被我们 &lt;code&gt;pass&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="什么是非对称加密"&gt;什么是非对称加密&lt;/h2&gt;
&lt;p&gt;既然对称加密不行，那么我们就需要考虑&lt;code&gt;非对称加密&lt;/code&gt;了，那&lt;code&gt;非对称加密&lt;/code&gt;又是什么呢？&lt;/p&gt;
&lt;p&gt;我们还是来看看还是刚刚上面👆那个&lt;code&gt;运送货物&lt;/code&gt;的例子：&lt;/p&gt;
&lt;p&gt;两个港口需要运送一批货物，发货方发货时，将货物装进集装箱并用一把锁（我们将其称为公钥）将集装箱锁起来，收货方收到货物时，需要用另外一把钥匙（我们将其称为私钥）将集装箱打开，从而取出货物。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;注意这里的关键是：当通信的一方使用公钥时，另外一方只能使用私钥，反之亦然。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;简单的来说就是有两把密钥，一把叫做公钥、一把叫私钥。用公钥加密的内容必须用私钥才能解开，同理，私钥加密的内容只有公钥能解开。公钥对于私钥来说是非对称的，所以我们把这种加密方式称为&lt;code&gt;非对称加密&lt;/code&gt;：&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://amatsuzero.github.io/LastStand/posts/frontend/security/https/image-06.webp"&gt;&lt;/p&gt;
&lt;h2 id="https用非对称加密可行吗"&gt;HTTPS用非对称加密可行吗&lt;/h2&gt;
&lt;p&gt;我们利用非对称加密来模拟一下浏览器和服务器通信的过程。&lt;/p&gt;
&lt;p&gt;浏览器向服务器发起请求，服务器收到请求之后，将公钥传输给浏览器，然后在接下来的通信中，浏览器要向服务器发送数据时，先用公钥将数据加密，然后发送给服务器，服务器收到之后，再用对应的私钥进行解密，这样就保证了&lt;code&gt;浏览器-&amp;gt;服务器&lt;/code&gt;这条路的数据安全。因为浏览器发送给服务器的数据，只有服务器有私钥能够解密它。那么反过来，&lt;code&gt;服务器-&amp;gt;浏览器&lt;/code&gt;这条路的通信是否安全呢？&lt;/p&gt;
&lt;p&gt;捋一捋刚刚的过程，我们就会发现，一开始我们的服务器将公钥传输给浏览器这一步骤，显然是在明文形式下进行传输的。假设这一过程，我们的公钥被中间人挟持了，想想会发生什么情况？显然有了这个公钥，中间人就能解密由服务器利用私钥加密的数据了，虽然他不能解密浏览器端的数据，但是此时他可以伪造请求，服务器收到请求之后，利用私钥解密请求数据，之后响应请求，并用私钥对响应数据加密，接着返回给请求方，由于此时这个中间人是有对应的公钥的，所以他就能直接解密服务器返回的数据。&lt;/p&gt;</description></item><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><item><title>第三方库的安全</title><link>https://amatsuzero.github.io/LastStand/posts/frontend/security/security-005/</link><pubDate>Wed, 02 Oct 2024 00:00:00 +0800</pubDate><guid>https://amatsuzero.github.io/LastStand/posts/frontend/security/security-005/</guid><description>&lt;h2 id="从一个安全漏洞说起"&gt;从一个安全漏洞说起&lt;/h2&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://amatsuzero.github.io/LastStand/posts/frontend/security/security-005/image-01.webp"&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Lodash&lt;/code&gt; 是一款非常流行的 &lt;code&gt;npm&lt;/code&gt; 库，每月的下载量超过 &lt;code&gt;8000&lt;/code&gt; 万次，&lt;code&gt;GitHub&lt;/code&gt; 上使用它的项目有超过 &lt;code&gt;400&lt;/code&gt; 万。之前有段时间， &lt;code&gt;Lodash&lt;/code&gt; 的一个安全漏洞刷爆了朋友圈，我们先来回忆下这个安全漏洞：&lt;/p&gt;
&lt;p&gt;攻击者可以通过 &lt;code&gt;Lodash&lt;/code&gt; 的一些函数覆盖或污染应用程序。例如：通过 &lt;code&gt;Lodash&lt;/code&gt; 库中的函数 &lt;code&gt;defaultsDeep&lt;/code&gt; 可以修改 &lt;code&gt;Object.prototype&lt;/code&gt; 的属性。&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://amatsuzero.github.io/LastStand/posts/frontend/security/security-005/image-02.webp"&gt;&lt;/p&gt;
&lt;p&gt;我们都知道，&lt;code&gt;JavaScript&lt;/code&gt; 在读取对象中的某个属性时，如果查找不到就会去其原型链上查找。试想一下，如果被修改的属性是 &lt;code&gt;toString&lt;/code&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-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;payload&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;{&amp;#34;constructor&amp;#34;: {&amp;#34;prototype&amp;#34;: {&amp;#34;toString&amp;#34;: true}}}&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;_&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;defaultsDeep&lt;/span&gt;({}, &lt;span style="color:#a6e22e"&gt;JSON&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;parse&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;payload&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;每个对象都有一个 &lt;code&gt;toString()&lt;/code&gt; 方法，当该对象被表示为一个文本值时，或者一个对象以预期的字符串方式引用时自动调用。默认情况下，&lt;code&gt;toString()&lt;/code&gt; 方法被每个 &lt;code&gt;Object&lt;/code&gt; 对象继承。如果此方法在自定义对象中未被覆盖，&lt;code&gt;toString()&lt;/code&gt; 返回 &lt;code&gt;[object type]&lt;/code&gt;，其中 &lt;code&gt;type&lt;/code&gt; 是对象的类型。如果覆盖了 &lt;code&gt;toString()&lt;/code&gt; 方法，那么给应用带来的影响就是非常大的。&lt;/p&gt;
&lt;p&gt;其实上述的问题就属于一个很常见的安全漏洞 —— 原型污染&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;原型污染：攻击者通过某种手段修改 JavaScript 对象的原型（prototype）&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;然而这并不是 &lt;code&gt;Lodash&lt;/code&gt; 第一次爆出安全漏洞了。事实上，像这样的安全漏洞还可能存在于我们使用的千千万万个不同的开源依赖中，如果我们平时不重视他们，一旦出现问题对我们的项目造成的损失是不可估计的。这相当于你的项目中埋着很多不知道什么时候就会爆炸的炸弹。&lt;/p&gt;
&lt;h2 id="安全调查"&gt;安全调查&lt;/h2&gt;
&lt;p&gt;其实开发人员对开源代码的安全性的信任程度要大于对自己编写的代码的安全性的信任程度，但是在确保代码安全性和质量的工具还有很多不足之处。在 &lt;code&gt;npm&lt;/code&gt; 还没有一个完善的安全检测机制之前，&lt;code&gt;npm&lt;/code&gt; 和 &lt;code&gt;NodeJs&lt;/code&gt; 团队曾经对数万名 &lt;code&gt;JavaScript&lt;/code&gt; 开发者发起过一个调查，第一个问题就是安全问题，具体就是开发人员如何看待他们编写的代码和所使用的开源项目的安全性。&lt;/p&gt;
&lt;p&gt;调查结果显示：全球 &lt;code&gt;97％&lt;/code&gt; 的 &lt;code&gt;JavaScript&lt;/code&gt; 开发人员在自己开发的项目中都依赖开源代码，&lt;code&gt;77％&lt;/code&gt; 的开发人员对他们使用的开源代码是否安全表示担忧。更有趣的是，有 &lt;code&gt;87％&lt;/code&gt; 的人表示担心自己的代码的安全性。&lt;/p&gt;</description></item><item><title>密码存储</title><link>https://amatsuzero.github.io/LastStand/posts/frontend/security/security-006/</link><pubDate>Wed, 02 Oct 2024 00:00:00 +0800</pubDate><guid>https://amatsuzero.github.io/LastStand/posts/frontend/security/security-006/</guid><description>&lt;p&gt;我们在开发网站或者APP时，首先要解决的问题，就是&lt;strong&gt;如何安全地传输和存储用户的密码&lt;/strong&gt;。一些大公司的用户数据库泄露事件也时有发生，带来非常大的负面影响。因此，如何安全传输存储用户密码，是每位程序员必备的基础。本文将跟大家一起学习，如何安全传输存储用户的密码。&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://amatsuzero.github.io/LastStand/posts/frontend/security/security-006/image-01.webp"&gt;&lt;/p&gt;
&lt;h3 id="1-如何安全地传输用户的密码"&gt;1. 如何安全地传输用户的密码&lt;/h3&gt;
&lt;p&gt;要拒绝用户密码在网络上裸奔，我们很容易就想到使用https协议，那先来回顾下https相关知识吧~&lt;/p&gt;
&lt;h4 id="11-https-协议"&gt;1.1 https 协议&lt;/h4&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://amatsuzero.github.io/LastStand/posts/frontend/security/security-006/image-02.webp"&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;「http的三大风险」&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;为什么要使用https协议呢？&lt;strong&gt;http它不香&lt;/strong&gt;吗? 因为http是明文信息传输的。如果在茫茫的网络海洋，使用http协议，有以下三大风险：&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;窃听/嗅探风险：第三方可以截获通信数据。&lt;/li&gt;
&lt;li&gt;数据篡改风险：第三方获取到通信数据后，会进行恶意修改。&lt;/li&gt;
&lt;li&gt;身份伪造风险：第三方可以冒充他人身份参与通信。&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;如果传输不重要的信息还好，但是传输用户密码这些敏感信息，那可不得了。所以一般都要使用&lt;strong&gt;https协议&lt;/strong&gt;传输用户密码信息。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;「https 原理」&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;https原理是什么呢？为什么它能解决http的三大风险呢？&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;https = http + SSL/TLS, SSL/TLS 是传输层加密协议，它提供内容加密、身份认证、数据完整性校验，以解决数据传输的安全性问题。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;为了加深https原理的理解，我们一起复习一下 &lt;strong&gt;一次完整https的请求流程&lt;/strong&gt;吧~&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://amatsuzero.github.io/LastStand/posts/frontend/security/security-006/image-03.webp"&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;ol&gt;
&lt;li&gt;客户端发起https请求&lt;/li&gt;
&lt;li&gt;服务器必须要有一套数字证书，可以自己制作，也可以向权威机构申请。这套证书其实就是一对公私钥。&lt;/li&gt;
&lt;li&gt;服务器将自己的数字证书（含有公钥、证书的颁发机构等）发送给客户端。&lt;/li&gt;
&lt;li&gt;客户端收到服务器端的数字证书之后，会对其进行验证，主要验证公钥是否有效，比如颁发机构，过期时间等等。如果不通过，则弹出警告框。如果证书没问题，则生成一个密钥（对称加密算法的密钥，其实是一个随机值），并且用证书的公钥对这个随机值加密。&lt;/li&gt;
&lt;li&gt;客户端会发起https中的第二个请求，将加密之后的客户端密钥(随机值)发送给服务器。&lt;/li&gt;
&lt;li&gt;服务器接收到客户端发来的密钥之后，会用自己的私钥对其进行非对称解密，解密之后得到客户端密钥，然后用客户端密钥对返回数据进行对称加密，这样数据就变成了密文。&lt;/li&gt;
&lt;li&gt;服务器将加密后的密文返回给客户端。&lt;/li&gt;
&lt;li&gt;客户端收到服务器发返回的密文，用自己的密钥（客户端密钥）对其进行对称解密，得到服务器返回的数据。&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;「https一定安全吗？」&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;https的数据传输过程，数据都是密文的，那么，使用了https协议传输密码信息，一定是安全的吗？其实不然&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;比如，https 完全就是建立在证书可信的基础上的呢。但是如果遇到中间人伪造证书，一旦客户端通过验证，安全性顿时就没了哦！平时各种钓鱼不可描述的网站，很可能就是黑客在诱导用户安装它们的伪造证书！&lt;/li&gt;
&lt;li&gt;通过伪造证书，https也是可能被抓包的哦。&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h4 id="12-对称加密算法"&gt;1.2 对称加密算法&lt;/h4&gt;
&lt;p&gt;既然使用了https协议传输用户密码，还是 &lt;strong&gt;「不一定安全」&lt;/strong&gt;，那么，我们就给用户密码 &lt;strong&gt;「加密再传输」&lt;/strong&gt; 呗~&lt;/p&gt;
&lt;p&gt;加密算法有 &lt;strong&gt;「对称加密」&lt;/strong&gt; 和 &lt;strong&gt;「非对称加密」&lt;/strong&gt; 两大类。用哪种类型的加密算法 &lt;strong&gt;「靠谱」&lt;/strong&gt; 呢？&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;对称加密：加密和解密使用 &lt;strong&gt;「相同密钥」&lt;/strong&gt; 的加密算法。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://amatsuzero.github.io/LastStand/posts/frontend/security/security-006/image-04.webp"&gt; 常用的对称加密算法主要有以下几种哈：&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://amatsuzero.github.io/LastStand/posts/frontend/security/security-006/image-05.webp"&gt; 如果使用对称加密算法，需要考虑 &lt;strong&gt;「密钥如何给到对方」&lt;/strong&gt; ，如果密钥还是网络传输给对方，传输过程，被中间人拿到的话，也是有风险的哦。&lt;/p&gt;
&lt;h4 id="13-非对称加密算法"&gt;1.3 非对称加密算法&lt;/h4&gt;
&lt;p&gt;再考虑一下非对称加密算法呢？&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;「非对称加密：」&lt;/strong&gt; 非对称加密算法需要两个密钥（公开密钥和私有密钥）。公钥与私钥是成对存在的，如果用公钥对数据进行加密，只有对应的私钥才能解密。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://amatsuzero.github.io/LastStand/posts/frontend/security/security-006/image-06.webp"&gt;&lt;/p&gt;</description></item><item><title>文件上传安全</title><link>https://amatsuzero.github.io/LastStand/posts/frontend/security/security-007/</link><pubDate>Wed, 02 Oct 2024 00:00:00 +0800</pubDate><guid>https://amatsuzero.github.io/LastStand/posts/frontend/security/security-007/</guid><description>&lt;h2 id="文件上传漏洞简介"&gt;文件上传漏洞简介&lt;/h2&gt;
&lt;h3 id="原理"&gt;&lt;strong&gt;原理&lt;/strong&gt;&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;攻击者可以上传一个与网站脚本语言相对应的恶意代码动态脚本到服务器上,然后访问这些恶意脚本中包含的恶意代码,从而获得了执行服务器端命令的能力,进一步影响服务器安全。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="危害"&gt;危害&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;文件上传漏洞最直接的威胁就是上传任意文件，包括恶意脚本、可执行程序等。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;如果Web 服务器所保存上传文件的可写目录具有执行权限，那么就可以直接上传后门文件，导致网站沦陷。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;如果攻击者通过其他漏洞进行提权操纵，拿到系统管理权限，那么直接导致服务器沦陷。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;同服务器下的其他网站无一幸免，均会被攻击者控制。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="利用"&gt;利用&lt;/h3&gt;
&lt;p&gt;对于利用，我们只需要有个文件上传的点，以及我们知道我们所传的文件所在目录并且上传的恶意文件能够被web容器解析执行，便可能存在文件上传漏洞。&lt;/p&gt;
&lt;h2 id="实战"&gt;实战&lt;/h2&gt;
&lt;p&gt;说是实战但是因为不能随便入侵别人的机器(有概率获取银手镯一套)，这里给大家推荐一个专门用来练习文件上传漏洞的不同利用方法的靶场。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://github.com/c0ny1/upload-labs"&gt;github.com/c0ny1/uploa…&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://amatsuzero.github.io/LastStand/posts/frontend/security/security-007/image-01.webp"&gt; 可以看到里面有很多关卡，对于环境的搭建，这里我推荐用phpstudy去进行一键搭建，比较适合入门的萌新，具体搭建方法不是本文的重点，于是我们跳过，接下来给大家带来文件上传漏洞一些常见的绕过方法。&lt;/p&gt;
&lt;h3 id="客户端检测绕过"&gt;客户端检测绕过&lt;/h3&gt;
&lt;p&gt;有的客户端会存在客户端校验，校验上传文件的后缀名，当我们传入php木马时可能会因为类型不同被禁止，此时我们要怎么进行上传一句话木马呢，这里给大家提供两个思路，第一个我们可以禁用浏览器的JS脚本，第二种方法便是使用渗透中常用工具burpsuit进行抓包，然后修改文件后缀为php即可绕过，因为他只是做了一个前端的简单验证。&lt;/p&gt;
&lt;h3 id="修改mime-类型"&gt;修改MIME 类型&lt;/h3&gt;
&lt;p&gt;有的服务器端将会对上传文件content-type类型进行检查以此来防范恶意文件的上传，这时我们打开burp suite将php文件上传，因为content-type的类型不是服务器认可的类型，那么我们就可以使用burpsuite进行修改该文件类型，并将该文件进行上传。&lt;/p&gt;
&lt;p&gt;常见的content-type对应类型如下：&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://amatsuzero.github.io/LastStand/posts/frontend/security/security-007/image-02.webp"&gt;&lt;/p&gt;
&lt;h3 id="00截断绕过"&gt;&lt;strong&gt;00截断绕过&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;运用此漏洞需要满足两个条件：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;1.php版本小于5.3.4&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;2.php的magic_quotes_gpc为OFF状态&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;0x开头表示16进制，0在十六进制中是00, 0x00就是%00解码成的16进制，具体运用方法如下，假如我们上传一个一句话木马：&lt;/p&gt;
&lt;p&gt;攻击者修改了path以后的拼接结果为：uploads/XINO.php%00/20190818.php，移动文件的时候会将文件保存为：uploads/XINO.php，以此我们便可以绕过检测来上传一句话木马。&lt;/p&gt;
&lt;h3 id="htaccess文件攻击"&gt;&lt;strong&gt;.htaccess文件攻击&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;.htaccess&lt;/strong&gt;文件(或者&amp;quot;分布式配置文件&amp;quot;）,全称是&lt;strong&gt;Hypertext Access&lt;/strong&gt;(超文本入口)。提供了针对目录改变配置的方法， 即，在一个特定的文档目录中放置一个包含一个或多个&lt;strong&gt;指令&lt;/strong&gt;的文件， 以作用于此目录及其所有子目录。&lt;/p&gt;
&lt;p&gt;简单来说该文件的作用就是根据里面的内容解析为我们想要的类型，这么说可能很难理解，比如我上传一个图片马（JPG文件里插入了一句话木马），因为网站对我们的上传类型做了限制，我们上传不了PHP文件，我们先上传一个JPG的图片马，然后上传 &lt;strong&gt;.htaccess文件，&lt;/strong&gt; 将图片解析为php语言，来达到getshell的目的。具体的文件内的内容为：&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-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;FilesMatch &lt;span style="color:#e6db74"&gt;&amp;#34;evil.gif&amp;#34;&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;SetHandler application/x-httpd-php#在当前目录下，如果匹配到evil.gif文件，则被解析成PHP代码执行
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;AddHandler php5-script .gif &lt;span style="color:#75715e"&gt;#在当前目录下，如果匹配到evil.gif文件，则被解析成PHP代码执行&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;/FilesMatch&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&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-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;AddHandler php5-script .jpg
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;AddType application/x-httpd-php .jpg
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Sethandler application/x-httpd-php
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="文件头检测"&gt;文件头检测&lt;/h3&gt;
&lt;p&gt;当我们上传一些文件时，有些拦截会检测我们文件里的具体内容，如果匹配了正确的文件头则会通过检测，反之则会拦截我们的文件，针对如此我们可以利用在文件前写入适当文件类型的文件头来绕过。常用的文件头如下：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;JPG：FF D8 FF E0 00 10 4A 46 49 46&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;GIF ：47 49 46 38 39 61 (GIF89a)&lt;/p&gt;</description></item><item><title>点击劫持</title><link>https://amatsuzero.github.io/LastStand/posts/frontend/security/security-008/</link><pubDate>Wed, 02 Oct 2024 00:00:00 +0800</pubDate><guid>https://amatsuzero.github.io/LastStand/posts/frontend/security/security-008/</guid><description>&lt;h2 id="一简介"&gt;一、简介&lt;/h2&gt;
&lt;p&gt;点击劫持是一种视觉上的欺骗手段。攻击者使用一个透明的、不可见的iframe,覆盖在一个网页上，然后诱使用户在该网页上进行操作，此时用户在不知情的情况下点击透明的iframe页面。通过调整iframe页面的位置，可以诱使用户恰好点击在iframe页面的一些功能性按钮上。&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://amatsuzero.github.io/LastStand/posts/frontend/security/security-008/image-01.webp"&gt;&lt;/p&gt;
&lt;p&gt;虽然受害者点击的是他所看到的网页，但其实他所点击的是被&lt;strong&gt;黑客精心构建的另一个置于原网页上面的透明页面&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Clickjacking 是仅此于 XSS 和 CSRF 的前端漏洞，因为需要诱使用户交互，攻击成本高，所以不被重视，但危害不容小觑。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;点击劫持的步骤&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;黑客创建一个网页利用 iframe 包含目标网站；&lt;/li&gt;
&lt;li&gt;隐藏目标网站，使用户无法无法察觉到目标网站存在；&lt;/li&gt;
&lt;li&gt;构造网页，诱变用户点击特点按钮；&lt;/li&gt;
&lt;li&gt;用户在不知情的情况下点击按钮，触发执行恶意网页的命令；&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="二劫持类型"&gt;二、劫持类型&lt;/h2&gt;
&lt;h3 id="21-flash点击劫持"&gt;2.1 Flash点击劫持&lt;/h3&gt;
&lt;p&gt;攻击者通过flash构造了点击劫持，在完成一系列复杂的动作后，最终控制了用户的摄像头。&lt;/p&gt;
&lt;p&gt;攻击者制作了一个Flash游戏，这个游戏就是让用户去点击“CLICK”按钮，每次点击后这个按钮的位置都会发生变化。在Flash上面隐藏了一个看不见的iframe，游戏中某些点击时是有意义的，有些点击是无效的。 攻击通过诱导用户鼠标点击就能完成较复杂的动作。最终通过这一步步操作，打开了用户的摄像头。&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://amatsuzero.github.io/LastStand/posts/frontend/security/security-008/image-02.webp"&gt; &lt;img loading="lazy" src="https://amatsuzero.github.io/LastStand/posts/frontend/security/security-008/image-03.webp"&gt;&lt;/p&gt;
&lt;h3 id="22-图片覆盖攻击"&gt;2.2 图片覆盖攻击&lt;/h3&gt;
&lt;p&gt;点击劫持是一种视觉上的欺骗手段。那么图片覆盖也可以起到类似的作用。简称XSIO（Cross Site Image Overlaying）&lt;/p&gt;
&lt;p&gt;&lt;em&gt;原理：&lt;/em&gt; 利用的是图片的style,或者能够控制CSS。如果应用没有限制style的position为absolute的话，图片可以覆盖到页面上的任意位置。&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;img&lt;/span&gt; &lt;span style="color:#f92672"&gt;style&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;position: absolute; left: 100px; top: 100px&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;/p&gt;
&lt;p&gt;图片还可以伪装得像一个正常的链接、按钮；或者在图片中构造一些文字，覆盖在关键的位置，就有可能完全改变页面中想表达的意思。这种情况下，不需要用户点击，也能达到欺骗的目的。&lt;/p&gt;
&lt;p&gt;由于img标签在很多系统中是对用户开放的，因此在现实生活中有非常多的站点存在在XSIO攻击的可能。在防御XSIO时，需要检查用户提交的HTML代码中，img标签的style属性是否可能导致浮出。&lt;/p&gt;
&lt;h3 id="23-拖拽劫持与数据窃取"&gt;2.3 拖拽劫持与数据窃取&lt;/h3&gt;
&lt;p&gt;目前，许多浏览器都开始支持Drag和Drop的API。对于用户来说，拖拽使他们的操作更加简单。浏览器中的拖拽对象可以是一个链接，也可以是一段文字，还可以从一个窗口拖拽到另一个窗口，因此拖拽是_不受同源策略限制_的。&lt;/p&gt;
&lt;p&gt;拖拽劫持的思路是诱使用户从隐藏不可见iframe中拖拽出攻击者希望得到的数据，然后放到攻击者能控制的另外一个页面，从而窃取数据。在JavaScript的支持下，这个攻击过程会变得非常隐蔽，因为它突破了传统ClickJacking一些先天的局限，所以这种新型的拖拽劫持能够造成更大的破坏。&lt;/p&gt;
&lt;h3 id="24-clickjacking30触屏劫持"&gt;2.4 ClickJacking3.0：触屏劫持&lt;/h3&gt;
&lt;p&gt;智能手机的 &lt;em&gt;触屏劫持&lt;/em&gt; 攻击被斯坦福的&lt;a href="http://seclab.stanford.edu/websec/framebusting/tapjacking.pdf"&gt;安全研究者公布&lt;/a&gt;，这意味着ClickJacking的攻击方式更进一步，斯坦福安全研究者的将其称为TapJacking。&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-makefile" data-lang="makefile"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;touchstart&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:#a6e22e"&gt;touchend&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:#a6e22e"&gt;touchmove&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:#a6e22e"&gt;touchcancel&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; 系统可取消touch事件
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;将一个不可见的iframe覆盖到当前网页上，就可以劫持用户的触屏操作。&lt;/p&gt;
&lt;p&gt;在未来，随着移动设备中浏览器功能的丰富，我们会看到更多的TapJacking&lt;/p&gt;
&lt;h2 id="三防御"&gt;三、防御&lt;/h2&gt;
&lt;h3 id="31-防御clickjacking"&gt;3.1 防御ClickJacking&lt;/h3&gt;
&lt;h4 id="311-frame-busting"&gt;3.1.1 frame busting&lt;/h4&gt;
&lt;p&gt;通过可以写一段JavaScript代码，以禁止iframe的嵌套。这种方法叫作frame busting。比如&lt;/p&gt;</description></item><item><title>中间人攻击</title><link>https://amatsuzero.github.io/LastStand/posts/frontend/security/security-009/</link><pubDate>Wed, 04 Dec 2024 00:00:00 +0800</pubDate><guid>https://amatsuzero.github.io/LastStand/posts/frontend/security/security-009/</guid><description>&lt;p&gt;一句话总结：中间人攻击的关键在于&lt;strong&gt;获取公钥&lt;/strong&gt;。&lt;/p&gt;
&lt;h2 id="一我和小美传纸条"&gt;一、我和小美传纸条&lt;/h2&gt;
&lt;p&gt;我和隔壁班的小美互相喜欢，经常互相传纸条。但我懒得动，一般让老王帮我顺路带过去，我信任老王，所以就是简单把纸对折一下就交给老王了。&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://amatsuzero.github.io/LastStand/posts/frontend/security/security-009/image-01.webp"&gt;&lt;/p&gt;
&lt;h2 id="二带锁的盒子"&gt;二、带锁的盒子&lt;/h2&gt;
&lt;p&gt;有一天我发现，老王居然偷看我的纸条！&lt;/p&gt;
&lt;p&gt;我很生气，于是买了一个带锁的盒子，并配了两把钥匙🔑，我留一把，另一把让老王交给小美。我心想这下子老王没钥匙，看不了我们的纸条了。&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://amatsuzero.github.io/LastStand/posts/frontend/security/security-009/image-02.webp"&gt;&lt;/p&gt;
&lt;h2 id="三一个需要两把钥匙的盒子"&gt;三、一个需要两把钥匙的盒子&lt;/h2&gt;
&lt;p&gt;又过了几天，我发现老王还是会偷看，为什么呢？原来这老小子当初传递钥匙的时候，自己去复刻了一把！&lt;/p&gt;
&lt;p&gt;于是我又想了一个办法，换了一个更高级的盒子，这个盒子必须用一对钥匙才能使用，使用公钥上锁，必须使用私钥才能打开。我委托老王把我的公钥交给小美，把小美的公钥拿给我。&lt;/p&gt;
&lt;p&gt;以后我们都用对方的公钥来进行加密，对方用自己的私钥就能解密。而且就算老王把公钥拿去复刻一把也没关系，没有私钥他就打不开箱子，完美！&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://amatsuzero.github.io/LastStand/posts/frontend/security/security-009/image-03.webp"&gt;&lt;/p&gt;
&lt;h2 id="四班主任"&gt;四、班主任&lt;/h2&gt;
&lt;p&gt;过了几天，我发现老王还是能偷看我们的纸条，为什么呢？？？？？？&lt;/p&gt;
&lt;p&gt;我想了好几天终于想明白了！原来老王当初传递钥匙的时候，他把我俩的公钥自己留下了，这老小子把自己的公钥给了我们俩。他现在有手里有四把钥匙，想看什么看什么！&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://amatsuzero.github.io/LastStand/posts/frontend/security/security-009/image-04.webp"&gt;&lt;/p&gt;
&lt;p&gt;这次我们终于意识到问题的关键，不管什么方案，让老王传钥匙就得坏事！于是我和小美商量好，这次不通过老王，而是通过我的班主任传递公钥，终于可以愉快的聊天了！&lt;/p&gt;
&lt;h2 id="五网络中的加密知识"&gt;五、网络中的加密知识&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;对称加密&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;对称加密使用&lt;code&gt;同一个密钥&lt;/code&gt;进行加密和解密。它的优点是速度快，它的问题是密钥传播过程中一旦泄露，就功亏一篑了。&lt;/p&gt;
&lt;ol start="2"&gt;
&lt;li&gt;非对称加密&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;非对称加密使用一对密钥：公钥和私钥。&lt;code&gt;公钥用于加密，私钥用于解密&lt;/code&gt;。它的优点是密钥分发问题得到解决，公钥可以公开传播。缺点是速度较慢，通常用于加密小数据量或密钥交换。常见做法是通过非对称加密建立链接，交换对称加密密钥，然后使用对称加密的方式进行消息传递。&lt;/p&gt;
&lt;ol start="3"&gt;
&lt;li&gt;证书&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;数字证书是由认证机构（CA）签发的，包含公钥及其持有者身份信息的电子文档。它通过 CA 的数字签名验证其真实性，确保通信双方的身份和公钥的可信性。（证书就是上面例子中的班主任，是一个可信任的获取对方公钥的机构。）&lt;/p&gt;
&lt;h2 id="六中间人攻击"&gt;六、中间人攻击&lt;/h2&gt;
&lt;p&gt;中间人攻击的关键在于攻击者成功获取并提供&lt;strong&gt;可信公钥&lt;/strong&gt;，欺骗用户使其认为其公钥是合法服务器的公钥。这可以通过伪造证书或利用受损的 CA 来实现。（用上面例子来说，就是老王把自己的公钥伪装成小美的公钥给了我）&lt;/p&gt;
&lt;p&gt;作为普通用户防御措施很简单，当访问一个网站时，如果浏览器弹出“证书不可信”告警的时候，不要点“我信任”。&lt;/p&gt;
&lt;h2 id="常见考点"&gt;常见考点&lt;/h2&gt;
&lt;h3 id="1-中间人攻击的基本概念"&gt;&lt;strong&gt;1. 中间人攻击的基本概念&lt;/strong&gt;&lt;/h3&gt;
&lt;h4 id="问题"&gt;&lt;strong&gt;问题&lt;/strong&gt;：&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;什么是中间人攻击？请用通俗的语言解释。&lt;/li&gt;
&lt;li&gt;中间人攻击有哪些典型的攻击方式？&lt;br&gt;
&lt;ul&gt;
&lt;li&gt;被动攻击（如窃听）。&lt;/li&gt;
&lt;li&gt;主动攻击（如数据篡改）。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;中间人攻击的危害有哪些？&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;关键点&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;中间人攻击是一种攻击者拦截并篡改通信内容的攻击。&lt;/li&gt;
&lt;li&gt;危害包括：窃取敏感数据（如密码）、篡改通信内容、伪装身份等。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id="2-中间人攻击的原理"&gt;&lt;strong&gt;2. 中间人攻击的原理&lt;/strong&gt;&lt;/h3&gt;
&lt;h4 id="问题-1"&gt;&lt;strong&gt;问题&lt;/strong&gt;：&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;中间人攻击是如何实现的？请简要描述其工作流程。&lt;/li&gt;
&lt;li&gt;在 HTTP 中，为什么容易发生中间人攻击？&lt;/li&gt;
&lt;li&gt;HTTPS 是否完全能防止中间人攻击？为什么？&lt;/li&gt;
&lt;li&gt;DNS 劫持和 ARP 欺骗是如何帮助实现中间人攻击的？&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;关键点&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;工作流程&lt;/strong&gt;：&lt;br&gt;
&lt;ol&gt;
&lt;li&gt;攻击者充当通信双方之间的“中间人”。&lt;/li&gt;
&lt;li&gt;拦截通信数据，可能进行监听或篡改。&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;常见技术&lt;/strong&gt;：&lt;br&gt;
&lt;ul&gt;
&lt;li&gt;ARP 欺骗：伪装网关。&lt;/li&gt;
&lt;li&gt;DNS 劫持：将域名解析到攻击者控制的服务器。&lt;/li&gt;
&lt;li&gt;Wi-Fi 劫持：在公共网络中拦截通信数据。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id="3-防御中间人攻击的技术措施"&gt;&lt;strong&gt;3. 防御中间人攻击的技术措施&lt;/strong&gt;&lt;/h3&gt;
&lt;h4 id="问题-2"&gt;&lt;strong&gt;问题&lt;/strong&gt;：&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;HTTPS 如何防御中间人攻击？它的安全机制是什么？&lt;/li&gt;
&lt;li&gt;什么是证书信任链？如何防止伪造的证书？&lt;/li&gt;
&lt;li&gt;什么是 HSTS（HTTP Strict Transport Security）？它如何防御中间人攻击？&lt;/li&gt;
&lt;li&gt;什么是双向 SSL/TLS？它如何进一步提高安全性？&lt;/li&gt;
&lt;li&gt;如何防止公共 Wi-Fi 中的中间人攻击？&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;关键点&lt;/strong&gt;：&lt;/p&gt;</description></item><item><title>浏览器的同源策略</title><link>https://amatsuzero.github.io/LastStand/posts/frontend/security/security-010/</link><pubDate>Tue, 17 Dec 2024 00:00:00 +0800</pubDate><guid>https://amatsuzero.github.io/LastStand/posts/frontend/security/security-010/</guid><description>&lt;h2 id="概述"&gt;概述&lt;/h2&gt;
&lt;p&gt;本文从以下三个问题，循序渐进，一步步拆解，何为浏览器的同源策略和跨域问题：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;什么是同源策略和跨域问题？&lt;/li&gt;
&lt;li&gt;怎样才算同源？&lt;/li&gt;
&lt;li&gt;同源策略下会有什么限制？&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="什么是同源策略和跨域问题"&gt;什么是同源策略和跨域问题？&lt;/h2&gt;
&lt;p&gt;同源政策是 1995 年由 Netscape 公司（就是创造了 JS 的那家网景公司）引入浏览器的一种策略。&lt;/p&gt;
&lt;p&gt;想要理解同源策略的话，可以先假设如果没有同源策略会发生什么事情。接下来我们通过一则恐怖故事代入理解一下没有同源策略的世界：&lt;/p&gt;
&lt;p&gt;在某个深夜，小明独自一人在家浏览网页，无意间打开了一些特殊网站，而恰巧的是，小明之前刚好打开过某些重要支付平台的网站且还没关闭，这时特殊网站里面可能有一些特殊 JS 脚本，在偷偷获取小明支付平台上的信息，并且偷偷利用了这些信息再结合某些手段，成功把小明支付平台上的钱转走了，小明上完厕所回来后，突然收到支付平台转账成功的短信，然后然后然后瘫坐在地上，泣不成声，仰天长啸，大喊一声：“还我攒了半年的 9.99~”&lt;/p&gt;
&lt;p&gt;恐怖故事听完了，我们来先上个概念，什么是同源策略？&lt;/p&gt;
&lt;p&gt;&lt;a href="https://developer.mozilla.org/zh-CN/docs/Web/Security/Same-origin_policy"&gt;借用 MDN 上的描述&lt;/a&gt;：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;同源策略&lt;/strong&gt;是一个重要的安全策略，它用于限制一个origin的文档或者它加载的脚本如何能与另一个源的资源进行交互。它能帮助阻隔恶意文档，减少可能被攻击的媒介。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;怎么理解这个概念呢？举个栗子，随着汽车数量的上升，现在很多城市都有各种限行政策，就拿广州来说，如果不是 &lt;code&gt;粤A&lt;/code&gt; 的车牌进入城区的话会有开四停四的限行限制。&lt;/p&gt;
&lt;p&gt;同源策略跟汽车限行政策有一点点像，同源策略规定在“同源”下的脚本、文档等资源访问不受限（有点像 &lt;code&gt;粤A&lt;/code&gt; 牌的汽车在广州内行驶不会被限行），如果不是“同源”则无法互相访问脚本、文档等资源（非 &lt;code&gt;粤A&lt;/code&gt; 牌的汽车在广州市区内受开四停四政策限制）&lt;/p&gt;
&lt;p&gt;理解了同源策略后，对于跨域就很好理解了，同源策略是好，我们也需要同源策略，但有些时候我们确实需要不同源的两个网页互相读取信息，这是就产生了跨域问题。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;额外补充&lt;/strong&gt;，同源策略是浏览器的行为，是浏览器的行为，是浏览器的行为（对于这点的解析可以参考：&lt;a href="https://blog.csdn.net/l_z_jay/article/details/121431204"&gt;同源策略下，服务器会收到浏览器的请求吗？&lt;/a&gt;）&lt;/p&gt;
&lt;h2 id="怎样才算同源"&gt;怎样才算同源？&lt;/h2&gt;
&lt;p&gt;所谓“同源”，就是以下三者必须&lt;strong&gt;都相同&lt;/strong&gt;：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;协议相同&lt;br&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;协议&lt;strong&gt;相同&lt;/strong&gt;的两个域名：（都是 &lt;code&gt;https&lt;/code&gt; 协议）&lt;br&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;https://juejin.cn&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;https://juejin.cn&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;协议&lt;strong&gt;不同&lt;/strong&gt;的两个域名：（一个是 &lt;code&gt;http&lt;/code&gt; 协议，一个是 &lt;code&gt;https&lt;/code&gt; 协议）&lt;br&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;http://juejin.cn&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;https://juejin.cn&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start="2"&gt;
&lt;li&gt;域名相同&lt;br&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;域名&lt;strong&gt;相同&lt;/strong&gt;的两个域名：&lt;br&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;https://juejin.cn&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;https://juejin.cn&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;域名&lt;strong&gt;不同&lt;/strong&gt;的两个域名：（一个是&lt;a href="https://help.aliyun.com/document_detail/155782.html#h2-u4EC0u4E48u53EBu5B50u57DFu540D1"&gt;二级域名&lt;/a&gt;，一个是&lt;a href="https://help.aliyun.com/document_detail/155782.html#h2-u4EC0u4E48u53EBu5B50u57DFu540D1"&gt;三级域名&lt;/a&gt;）（可能这个是最容易记错的）&lt;br&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;https://juejin.cn&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;https://www.juejin.cn&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start="3"&gt;
&lt;li&gt;端口相同&lt;br&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;端口&lt;strong&gt;相同&lt;/strong&gt;的两个域名：&lt;br&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;https://juejin.cn&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;https://juejin.cn&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;端口&lt;strong&gt;不同&lt;/strong&gt;的两个域名：&lt;br&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;https://juejin.cn&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;https://juejin.cn:8081&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;再重复一遍，&lt;/p&gt;
&lt;p&gt;同协议、同域名、同端口，才算同源&lt;/p&gt;
&lt;p&gt;同协议、同域名、同端口，才算同源&lt;/p&gt;
&lt;p&gt;同协议、同域名、同端口，才算同源&lt;/p&gt;
&lt;h2 id="同源策略下会有什么限制"&gt;同源策略下会有什么限制？&lt;/h2&gt;
&lt;p&gt;在同源策略下，如果&lt;strong&gt;非同源&lt;/strong&gt;，会有以下三个方面的行为受到限制：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;DOM&lt;br&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;如果非同源，其 JS 脚本，不能互相对 DOM 进行读写操作&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start="2"&gt;
&lt;li&gt;数据&lt;br&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;如果非同源，不能互相读写 Cookies、LocalStorage、SessionStorage 和 IndexedDB&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start="3"&gt;
&lt;li&gt;网络请求&lt;br&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;如果非同源，不能通过 AJAX 的方式互相发送、接收数据&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;为了方便理解，接下来我们展开说说这三条规则 ↓↓↓&lt;/p&gt;</description></item><item><title>跨域资源共享（CORS）</title><link>https://amatsuzero.github.io/LastStand/posts/frontend/security/security-011/</link><pubDate>Tue, 17 Dec 2024 00:00:00 +0800</pubDate><guid>https://amatsuzero.github.io/LastStand/posts/frontend/security/security-011/</guid><description>&lt;p&gt;跨域资源共享（CORS，Cross-Origin Resource Sharing）是浏览器用来放宽同源策略限制的一种机制，是前端跨域请求的主流解决方案。面试时考察点主要围绕它的原理、工作流程、配置细节及相关安全问题。&lt;/p&gt;
&lt;h2 id="一cors-基础概念"&gt;一、CORS 基础概念&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;作用&lt;/strong&gt;：允许浏览器从不同源的服务器请求资源，突破同源策略限制。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;原理&lt;/strong&gt;：服务器通过设置特定的 HTTP 响应头，告诉浏览器允许跨域访问。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="二cors-的关键响应头"&gt;二、CORS 的关键响应头&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;头部&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Access-Control-Allow-Origin&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;指明允许访问的源，可以是具体域名（如 &lt;code&gt;https://example.com&lt;/code&gt;）或 &lt;code&gt;*&lt;/code&gt;（表示允许所有域访问）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Access-Control-Allow-Methods&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;允许的请求方法（GET、POST、PUT、DELETE 等）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Access-Control-Allow-Headers&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;允许请求携带的自定义头部字段&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Access-Control-Allow-Credentials&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;是否允许携带 Cookie 或 HTTP 认证信息，值为 &lt;code&gt;true&lt;/code&gt; 时允许&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Access-Control-Max-Age&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;预检请求的结果缓存时间，单位秒&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="三cors-请求分类"&gt;三、CORS 请求分类&lt;/h2&gt;
&lt;h3 id="1-简单请求"&gt;1. &lt;strong&gt;简单请求&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;满足以下条件，浏览器直接发请求：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;请求方法是 &lt;code&gt;GET&lt;/code&gt;、&lt;code&gt;POST&lt;/code&gt;、&lt;code&gt;HEAD&lt;/code&gt; 中之一。&lt;/li&gt;
&lt;li&gt;请求头只包含简单头（如 &lt;code&gt;Accept&lt;/code&gt;, &lt;code&gt;Content-Type&lt;/code&gt; 仅限 &lt;code&gt;application/x-www-form-urlencoded&lt;/code&gt;、&lt;code&gt;multipart/form-data&lt;/code&gt; 或 &lt;code&gt;text/plain&lt;/code&gt;）。&lt;/li&gt;
&lt;li&gt;不携带自定义 Cookie、认证信息。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="2-预检请求preflight"&gt;2. &lt;strong&gt;预检请求（Preflight）&lt;/strong&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;当请求不满足简单请求条件时，浏览器先发送 &lt;code&gt;OPTIONS&lt;/code&gt; 请求询问服务器是否允许该跨域请求。&lt;/li&gt;
&lt;li&gt;服务器响应通过特定头部告诉浏览器是否放行。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="四cors-工作流程"&gt;四、CORS 工作流程&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;浏览器发送跨域请求。&lt;/li&gt;
&lt;li&gt;如果是简单请求，直接带上请求头发送实际请求，服务器返回响应带有 CORS 相关头，浏览器决定是否允许。&lt;/li&gt;
&lt;li&gt;如果是非简单请求，浏览器先发 &lt;code&gt;OPTIONS&lt;/code&gt; 预检请求。&lt;/li&gt;
&lt;li&gt;服务器响应预检，决定是否允许后，浏览器再发实际请求。&lt;/li&gt;
&lt;li&gt;浏览器根据响应头决定是否允许前端访问响应内容。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="五携带-cookie-的跨域请求"&gt;五、携带 Cookie 的跨域请求&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;默认情况下，跨域请求不发送 Cookie。&lt;/li&gt;
&lt;li&gt;前端请求时必须设置：&lt;code&gt;xhr.withCredentials = true&lt;/code&gt; 或 &lt;code&gt;fetch&lt;/code&gt; 的 &lt;code&gt;credentials: 'include'&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;服务器必须设置：&lt;code&gt;Access-Control-Allow-Credentials: true&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Access-Control-Allow-Origin&lt;/code&gt; 不能使用 &lt;code&gt;*&lt;/code&gt;，必须指定具体域名。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="常见考点"&gt;常见考点&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;CORS 是什么？为什么需要它？&lt;/li&gt;
&lt;li&gt;同源策略和 CORS 的关系？&lt;/li&gt;
&lt;li&gt;简单请求和预检请求的区别？&lt;/li&gt;
&lt;li&gt;预检请求的触发条件有哪些？&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Access-Control-Allow-Origin&lt;/code&gt; 设置为 &lt;code&gt;*&lt;/code&gt; 有什么限制？&lt;/li&gt;
&lt;li&gt;如何支持带 Cookie 的跨域请求？&lt;/li&gt;
&lt;li&gt;CORS 配置中的常用响应头说明。&lt;/li&gt;
&lt;li&gt;如何解决跨域请求失败问题？&lt;/li&gt;
&lt;li&gt;JSONP 和 CORS 的区别？&lt;/li&gt;
&lt;li&gt;服务器如何配置支持 CORS？&lt;/li&gt;
&lt;/ol&gt;</description></item><item><title>浏览器的安全性</title><link>https://amatsuzero.github.io/LastStand/posts/frontend/security/security-012/</link><pubDate>Tue, 17 Dec 2024 00:00:00 +0800</pubDate><guid>https://amatsuzero.github.io/LastStand/posts/frontend/security/security-012/</guid><description>&lt;p&gt;浏览器安全性是前端开发中的重要考察点之一，主要指浏览器在访问网站过程中如何防止攻击者利用漏洞或机制实施攻击、窃取数据、破坏用户体验等。&lt;/p&gt;
&lt;h2 id="一常见的浏览器安全威胁"&gt;一、常见的浏览器安全威胁&lt;/h2&gt;
&lt;h3 id="1-xss跨站脚本攻击"&gt;1. &lt;strong&gt;XSS（跨站脚本攻击）&lt;/strong&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;原理：攻击者注入恶意脚本到网页中，在用户浏览页面时执行。&lt;/li&gt;
&lt;li&gt;危害：窃取 cookie、伪造操作、传播蠕虫。&lt;/li&gt;
&lt;li&gt;防御：&lt;br&gt;&lt;/li&gt;
&lt;li&gt;对输出进行&lt;strong&gt;HTML转义&lt;/strong&gt;；&lt;/li&gt;
&lt;li&gt;使用 &lt;strong&gt;Content Security Policy（CSP）&lt;/strong&gt;；&lt;/li&gt;
&lt;li&gt;严格控制用户输入（白名单）；&lt;/li&gt;
&lt;li&gt;使用框架自动防御（如 React 的 JSX 自动转义）。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id="2-csrf跨站请求伪造"&gt;2. &lt;strong&gt;CSRF（跨站请求伪造）&lt;/strong&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;原理：用户登录目标网站后，被诱导访问恶意链接，触发网站上的有状态请求。&lt;/li&gt;
&lt;li&gt;危害：修改密码、转账等敏感操作被伪造。&lt;/li&gt;
&lt;li&gt;防御：&lt;br&gt;&lt;/li&gt;
&lt;li&gt;使用 CSRF Token；&lt;/li&gt;
&lt;li&gt;Referer 验证；&lt;/li&gt;
&lt;li&gt;SameSite Cookie 属性限制第三方请求。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id="3-点击劫持clickjacking"&gt;3. &lt;strong&gt;点击劫持（Clickjacking）&lt;/strong&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;原理：攻击者在页面上嵌入透明 iframe，引诱用户点击。&lt;/li&gt;
&lt;li&gt;防御：&lt;br&gt;&lt;/li&gt;
&lt;li&gt;禁止网页被嵌入 iframe：&lt;code&gt;X-Frame-Options: DENY / SAMEORIGIN&lt;/code&gt;；&lt;/li&gt;
&lt;li&gt;使用 CSP 中的 &lt;code&gt;frame-ancestors&lt;/code&gt; 指定允许嵌入的来源。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id="4-恶意文件上传"&gt;4. &lt;strong&gt;恶意文件上传&lt;/strong&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;原理：上传可执行脚本，触发服务端或客户端执行。&lt;/li&gt;
&lt;li&gt;防御：&lt;br&gt;&lt;/li&gt;
&lt;li&gt;严格限制文件类型与大小；&lt;/li&gt;
&lt;li&gt;不在上传目录下执行脚本；&lt;/li&gt;
&lt;li&gt;设置 CDN 或存储桶只读访问权限。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id="5-恶意第三方脚本供应链攻击"&gt;5. &lt;strong&gt;恶意第三方脚本（供应链攻击）&lt;/strong&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;原理：攻击者污染 CDN 或依赖源，注入恶意代码。&lt;/li&gt;
&lt;li&gt;防御：&lt;br&gt;&lt;/li&gt;
&lt;li&gt;使用子资源完整性校验（Subresource Integrity, SRI）；&lt;/li&gt;
&lt;li&gt;只信任可靠的依赖源；&lt;/li&gt;
&lt;li&gt;上线前锁定依赖版本。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="二浏览器原生安全机制"&gt;二、浏览器原生安全机制&lt;/h2&gt;
&lt;h3 id="1-同源策略same-origin-policy"&gt;1. &lt;strong&gt;同源策略（Same-Origin Policy）&lt;/strong&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;限制不同源之间访问 Cookie、DOM、LocalStorage 等。&lt;/li&gt;
&lt;li&gt;同源指：协议、域名、端口号都相同。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="2-cors跨域资源共享"&gt;2. &lt;strong&gt;CORS（跨域资源共享）&lt;/strong&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;浏览器通过预检请求和响应头判断是否允许跨域访问。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="3-content-security-policycsp"&gt;3. &lt;strong&gt;Content Security Policy（CSP）&lt;/strong&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;通过设置 HTTP Header 控制资源加载策略，防止 XSS 和数据泄露。&lt;/li&gt;
&lt;li&gt;示例：&lt;br&gt;&lt;/li&gt;
&lt;/ul&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-http" data-lang="http"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;Content-Security-Policy: default-src &amp;#39;self&amp;#39;; script-src &amp;#39;self&amp;#39; https://trust.cdn.com;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="4-http-only--secure-cookie"&gt;4. &lt;strong&gt;HTTP-only &amp;amp; Secure Cookie&lt;/strong&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;HttpOnly&lt;/code&gt;: 防止 JavaScript 读取 Cookie；&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Secure&lt;/code&gt;: 仅在 HTTPS 下传输 Cookie；&lt;/li&gt;
&lt;li&gt;&lt;code&gt;SameSite&lt;/code&gt;: 限制第三方请求携带 Cookie。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="5-sandboxiframe-安全沙箱"&gt;5. &lt;strong&gt;Sandbox（iframe 安全沙箱）&lt;/strong&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;iframe sandbox&amp;gt;&lt;/code&gt; 属性限制 iframe 的行为；&lt;/li&gt;
&lt;li&gt;可防止脚本执行、表单提交等危险操作。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="三前端开发中的安全实践"&gt;三、前端开发中的安全实践&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;安全措施&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;输入校验&lt;/td&gt;
&lt;td&gt;客户端和服务端都要做，优先使用白名单策略&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;输出编码&lt;/td&gt;
&lt;td&gt;HTML、JavaScript、URL 编码避免 XSS 注入&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HTTPS&lt;/td&gt;
&lt;td&gt;加密传输防止中间人攻击（MITM）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;使用现代框架&lt;/td&gt;
&lt;td&gt;React/Vue/Angular 等框架天然防御 XSS&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;限制权限&lt;/td&gt;
&lt;td&gt;用户行为应严格授权与验证&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CSP 策略&lt;/td&gt;
&lt;td&gt;强制资源加载来源、禁止内联脚本&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="四总结"&gt;四、总结&lt;/h2&gt;
&lt;p&gt;浏览器安全是前端必须掌握的重要基础知识，核心目标是 &lt;strong&gt;防止前端受到攻击者控制或操纵&lt;/strong&gt;。它涉及浏览器机制、HTTP协议、安全头部、数据验证等多个维度，需要前端开发者在日常开发中养成良好安全意识与编码习惯。&lt;/p&gt;</description></item><item><title>前端安全 面试题</title><link>https://amatsuzero.github.io/LastStand/posts/frontend/interview-questions/tag-12-28b9d64b/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://amatsuzero.github.io/LastStand/posts/frontend/interview-questions/tag-12-28b9d64b/</guid><description>&lt;p&gt;共 35 道 前端安全 面试题。答案默认折叠，便于先自行作答。&lt;/p&gt;
&lt;h2 id="question-bbf8b7ee-035e-4f2b-b64c-40d560e6dc19"&gt;1. 如果发现JWT Token泄露，如何快速响应？&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;难度：3 · 类型：QA&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="题目要点"&gt;题目要点&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;定位&lt;/strong&gt;：确认泄露的是单个用户 Token 还是全局密钥。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;拉黑&lt;/strong&gt;：立即将泄露的 Token &lt;code&gt;jti&lt;/code&gt; 加入 Redis 禁用名单。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;阻断&lt;/strong&gt;：如果是密钥泄露，立即更新环境变量中的 &lt;code&gt;JWT_SECRET&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;通知&lt;/strong&gt;：提醒受影响用户，并建议其修改密码（以防攻击者通过其他渠道获取了账号控制权）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;审计&lt;/strong&gt;：检查该 Token 泄露期间产生的异常操作日志，进行回滚或补偿。&lt;/li&gt;
&lt;/ol&gt;
&lt;details&gt;
&lt;summary&gt;参考答案&lt;/summary&gt;
&lt;p&gt;由于 JWT 是&lt;strong&gt;无状态&lt;/strong&gt;的（服务器默认不存储 Token，无法像 Session 那样轻易在服务端作废），快速响应的核心思路在于&lt;strong&gt;阻断该 Token 的有效性&lt;/strong&gt;或&lt;strong&gt;强制变更鉴权环境&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;以下是针对不同场景的快速响应方案：&lt;/p&gt;
&lt;h3 id="1-服务端拦截引入黑名单机制最快响应"&gt;1. 服务端拦截：引入“黑名单”机制（最快响应）&lt;/h3&gt;
&lt;p&gt;这是最直接的补救措施。虽然 JWT 旨在去中心化校验，但在紧急情况下，必须引入中心化检查。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;操作&lt;/strong&gt;：将泄露的 Token 唯一标识（通常是 &lt;code&gt;jti&lt;/code&gt; 载荷）或整个 Token 字符串存入 Redis 等极速缓存中，并设置过期时间（等于该 Token 的剩余有效期）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;逻辑更新&lt;/strong&gt;：修改后端的鉴权中间件，在校验 JWT 签名通过后，额外多一步检查：&lt;strong&gt;“该 Token 是否在 Redis 黑名单中？”&lt;/strong&gt;。如果在，则拒绝请求。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;优点&lt;/strong&gt;：秒级生效，精准拦截。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="2-变更签名密钥最彻底但代价大"&gt;2. 变更签名密钥（最彻底但代价大）&lt;/h3&gt;
&lt;p&gt;如果怀疑是大规模泄露，或者加密私钥（Secret Key）本身已暴露：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;操作&lt;/strong&gt;：立即在服务端更换用于签署 JWT 的 &lt;strong&gt;Secret Key&lt;/strong&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;后果&lt;/strong&gt;：由于密钥变了，之前所有基于旧密钥生成的 Token（包括合法用户的）都会瞬间失效。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;适用场景&lt;/strong&gt;：密钥泄露或遭受系统性攻击。虽然这会导致全服用户强制下线（需重新登录），但在极端安全风险下是必要的“熔断”。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="3-强制用户重新登录变更-user-secret"&gt;3. 强制用户重新登录：变更 User Secret&lt;/h3&gt;
&lt;p&gt;如果你的 JWT 签名逻辑中引入了用户特有的变量（例如：&lt;code&gt;HMAC256(payload, base_secret + user_password_hash)&lt;/code&gt;）：&lt;/p&gt;</description></item></channel></rss>