高级篇:前端安全

安全的重要性不言而喻,是所有互联网企业都绕不开的话题。

安全 是个很大的话题,各种安全问题的类型也是种类繁多。如果把安全问题按照所发生的区域来进行分类的话,那么所有发生在后端服务器、应用、服务当中的安全问题就是 后端安全问题,而所有发生在浏览器、单页面应用、Web 页面当中的安全问题则算是 前端安全问题

比如,SQL 注入漏洞发生在后端应用中,是后端安全问题;跨站脚本攻击(XSS)则是前端安全问题,因为它发生在用户的浏览器里。

本文收集了一些常用的前端安全问题及其防御措施。

XSS攻击

XSS 攻击全称跨站脚本攻击(Cross-Site Scripting),简单的说就是攻击者通过在目标网站上注入恶意脚本并运行,获取用户的敏感信息如 Cookie、SessionID 等,影响网站与用户数据安全。

XSS(Cross-Site Scripting,为了和 CSS 区分,把第一个字母改成了 X)是指跨站脚本攻击,是前端最常见的安全问题。攻击者通过在目标网站上注入恶意脚本,使之在用户的浏览器上运行,一旦成功运行,攻击者可以做以下危害用户的行为:

  • 获取用户的敏感信息如 Cookie、SessionID 等;
  • 以当前用户的身份发起一些非用户本意的操作请求,比如,删除网站好友、发帖、发私信等等;
  • 实现 DDos(Distributed Denial Of Service) 攻击,即分布式拒绝服务攻击,这种网络攻击形式尝试用恶意流量淹没网站或网络资源,从而导致网站或网络资源无法正常运行。

XSS 攻击的本质是因为网站没有对恶意代码进行过滤,与正常的代码混合在一起了,浏览器没有办法分辨哪些脚本是可信的,从而导致了恶意代码的执行。

XSS攻击类型

XSS 攻击可分为三类:反射型、存储型、DOM 型。

反射型

反射型 XSS 也被称为非持久性 XSS,是现在最容易出现的一种 XSS 漏洞。它指的是攻击者通过巧妙地构造一个带恶意代码的 URL,然后引导用户点击访问,用户打开该 URL 时,服务端将恶意代码从 URL 中取出,拼接在 HTML 文档中返回给浏览器,浏览器接收到响应后解析执行,混在其中的恶意代码也被执行。

反射型 XSS 的恶意代码存在 URL 里,常见于通过 URL 传递参数的功能,如网站搜索、跳转等。由于需要用户主动打开恶意的 URL 才能生效,攻击者往往会结合多种手段诱导用户点击。

POST 的内容也可以触发反射型 XSS,只不过其触发条件比较苛刻(需要构造表单提交页面,并引导用户点击),所以非常少见。

存储型

存储型 XSS 又被称为持久性 XSS,它是最危险的一种跨站脚本,它具有更高的隐蔽性、危害更大,不需要用户手动触发。它是将恶意代码提交到了网站的数据库中,被服务器端接收并存储,当浏览者访问页面时,服务端会将恶意代码从数据库取出,拼接在 HTML 文档中返回给浏览器,浏览器接收到响应后解析执行,混在其中的恶意代码也被执行。

存储型 XSS 的恶意代码存在数据库里,常见于带保存数据功能的网站,如论坛发帖、商品评论、用户私信等。

DOM型

DOM 型 XSS 是利用 DOM 本身存在的缺陷进行攻击。攻击者构建了特殊的 URL,其中包含恶意代码,用户打开带有恶意代码的 URL, JavaScript 取出 URL 中的恶意代码并执行,从而窃取用户数据并发送到攻击者的网站,或者冒充用户的行为,调用目标网站接口执行攻击者指定的操作。

DOM 型 XSS 跟前两种 XSS 的区别:DOM 型 XSS 攻击中,取出和执行恶意代码由浏览器端完成,属于前端 JavaScript 自身的安全漏洞,而其他两种 XSS 都属于服务端的安全漏洞。

XSS攻击示例

XSS 攻击常见的注入方式:

  • 在 HTML 中注入包含脚本的 script 标签、引用外部 Js 的 script 标签;
  • 在标签属性引用包含引号的恶意代码,从而注入其他属性或者标签;

  • 在标签的 href、src 等属性注入包含 javascript: 等可执行代码;

  • 样式中注入 url("javascript:...")、content("...")等代码;
  • 在 onload、onerror、onclick 等事件中,注入不受控制代码;
  • eval()setTimeout()setInterval()new Function() 等 API 中,注入不受控制代码。
<input type="text" value="<%= getUrlParam('keyword') %>">
<!--
    以上代码是,将 Url 中的 keyword 参数,填入 input 的 vaue 属性。
    假如页面传参数为 ?keyword="><script>alert(0)</script>,
    最终渲染会创建一个 script 标签,并执行里面代码,渲染结果如下:
-->
<input type="text" value=""><script>alert(0)</script>">
<a href="<%= getUrlParam('jumpUrl') %>">跳转</a>
<!--
    以上代码是,将 Url 中的 jumpUrl 参数作为 a 标签的跳转地址。
    假如页面传参数为 ?jumpUrl=javascript:alert(1),
    当点击 a 标签时,javascript: 后面的字符串,会作为 Js 脚本执行,渲染结果如下:
-->
<a href="javascript:alert(1)">跳转</a>

注意: 反射型 XSS 和 存储型 XSS 中,加载的 HTML 文档是经过服务端处理的,注入了一些业务相关的数据,导致恶意代码混入在 HTML 文档,也就是常说的服务端渲染,如 jsp、asp 等网页。如果是静态 HTML 或者单页面应用,也就是前端渲染,就不会出现这两种攻击,但仍要注意 DOM 型 XSS。

XSS防御措施

  • 限制输入,减少恶意代码的注入: 采用前端过滤不可靠输入、控制输入内容长度等方式,但这种方法的局限性也很明显,一是攻击者可以绕过过滤条件,直接调用 Ajax 写入数据库,二是对于输入值使用场景不确定或者有多个使用场景时,无法准确定义过滤条件,可能导致一些非异常的输入被过滤。
  • 转义输出,避免执行恶意代码: 对数据进行严格的输出编码,使得攻击者提供的数据不再被浏览器认为是脚本而被误执行。例如 <script> 在进行 HTML 编码后变成了 &lt;script&gt;,这段数据就会被浏览器认为只是一段普通的字符串,而不会被当做脚本执行,同时,尽量避免使用 innerHTMLdocument.writeouterHTMLeval 等方法,用安全性更高的 innerTextsetAttribute 等方法做替代;
  • 设置HttpOnly: 对于所有包含敏感信息的 cookie,都在服务端设置 httpOnly,设置了 httpOnly 的 cookie 字段无法通过 JS 获取,也就降低了 XSS 攻击时用户凭据隐私泄漏的风险;
  • 开启 CSP 防护: 内容安全策略(CSP)是一个额外的安全层,用于检测并削弱某些特定类型的攻击,包括跨站脚本(XSS)和数据注入攻击等;
  • 借助自动扫描工具寻找 XSS 漏洞,例如 Arachni、Mozilla HTTP Observatory、w3af 等。

CSRF攻击

CSRF(Cross-Site Request Forgeries)指的是跨站请求伪造攻击,简单的说就是,攻击者盗用了受害者的身份(Cookie、SessionID 等),以受害者的名义发送恶意请求。

攻击者在目标网站诱导受害者进入第三方网站,然后该网站向目标网站发送跨站请求,利用受害者在目标网站中保存的登录状态,绕过后台的用户验证,冒充用户发起请求(在用户不知情的情况下),完成一些违背用户意愿的事情。

CSRF 攻击的本质是利用了 目标网站保留在浏览器的 cookie,以某种方式绕过跨域限制,冒充受害者的身份,向目标网站的服务器发送请求,在用户不知情的情况下,完成某些操作。

CSRF 的攻击流程:

  • 受害者登录目标网站 A,并保留了登录凭证;
  • 受害者以某种方式接触到恶意网站 B 的链接;
  • 受害者点击链接访问网站 B,网站 B 中的 Javascript 代码执行,偷偷向目标网站 A 发送某个请求;
  • 由于受害者登录过网站 A,因此请求携带了网站 A 的相关 cookie 凭证,最后请求成功执行。

CSRF 攻击一般可分为:

  • GET 类型: img 标签的 src 属性指向一个 Http 请求,当用户进入网站时,会自动发起提交;
  • POST 类型:通常使用的是一个自动提交的表单;
  • 链接类型:链接类型的 CSRF 并不常见,比起其他两种用户打开页面就中招的情况,这种需要用户点击链接才会触发。这种类型通常是在论坛中发布的图片中嵌入恶意链接,或者以广告的形式诱导用户中招。

CSRF攻击示例

浏览器有同源策略,Ajax 直接发送跨域请求一般会被拦截,但 CSRF 通常可用以下方式发送跨域请求的:img 标签的 scr 属性,a 标签的 href 属性,CORS(跨域资源共享)、Form 提交等。

<!--在受害者访问含这个 img 的页面后,浏览器会自动向 http://target.example.com/delete?id=1 发出一次请求,由于请求会带上 target.example.com 域名下的 cookie,所以请求能成功。-->
<img src="http://target.example.com/delete?id=1" >
<!-- 页面中包含一个不可见的 Form 表单,当进入页面时,会自动发送一个请求,同样,由于请求会带上 target.example.com 域名下的 cookie,所以请求能成功。-->
<form action="http://target.example.com/update" method=POST>
  <input type="hidden" name="id" value="1" />
  <input type="hidden" name="name" value="hacker" />
  <input type="hidden" name="desc" value="modify something!" />
</form>
<script>
  document.querySelector("form").submit()
</script>
<a href="http://target.example.com/delete?id=1" taget="_blank">泪目!!惊爆!!突发。。。<a/>

CSRF防御

CSRF 通常从第三方网站发起,被攻击的网站无法防止攻击发生,只能通过增强自己网站针对 CSRF 的防护能力来提升安全性。

  • 同源检测: CSRF 攻击通常是发生在第三方网站的,因此可以通过域名判断来禁止第三方网站发送请求。服务器根据 HTTP 请求头中 origin、referer 信息来判断请求的来源域名,当域名不符,或者 origin、referer 为空时,则拒绝访问。

    这个方法的缺点是,有些情况下 referer 可能没有或者不可信:

    • IE6、7 下使用 location.href = url 进行界面的跳转,会丢失 referer;
    • IE6、7 下使用 window.open,也会缺失 referer;
    • HTTPS 页面跳转到 HTTP 页面,所有 referer 都丢失;
    • 点击 Flash 上到达另外一个网站的时候,referer 的情况就比较杂乱,不太可信。
  • CSRF Token 验证: 用户打开页面时,服务器创建一个 Token 存到 session,同时将 Token 返回给用户,当网站再次发起请求时,在请求参数中加入服务器端返回的 Token ,然后服务器验证请求中的 Token 与 session 中的是否一致,一致就允许访问,否则拒绝访问。

    这种方法的缺点是,需要给网站中的所有请求都添加上这个 Token,操作比较繁琐,还有就是对于不只一台服务器的网站,比如,请求经过负载平衡转移到了其他的服务器,而这个服务器的 session 中没有保留这个 Token 的话,就没有办法验证了。

  • 双重 cookie 验证: 用户打开页面时,服务器向请求域名注入一个 cookie,内容为随机字符串,然后当用户再次向服务器发送请求的时候,从 cookie 中取出这个字符串,添加到 URL 参数中,然后服务器通过对 cookie 中的数据和参数中的数据进行比较,来进行验证。

  • cookie 的 Samesite 属性: Samesite 一共有两种模式:严格模式(Strict),cookie 在任何情况下都不能跨站使用;宽松模式(Lax),cookie 可以被导航到目标网址的 GET 请求跨站使用,比如,跳转链接、预加载请求、GET 表单。

ClickJacking(点击劫持)

点击劫持(Clickjacking)技术又称为界面伪装攻击(UI redress attack),是一种视觉上的欺骗手段。攻击者使用一个或多个透明的 iframe 覆盖在一个正常的网页上,然后诱使用户在该网页上进行操作,当用户在不知情的情况下点击透明的 iframe 页面时,用户的操作已经被劫持到攻击者事先设计好的恶意按钮或链接上。

这是一种欺骗性比较强,同时也需要用户高度参与才能完成的一种攻击。

通常的攻击步骤是这样的:

  • 攻击者精心构造一个诱导用户点击的内容,比如 Web 页面小游戏;
  • 将目标网站的页面放入到 iframe 当中;
  • 利用 z-index 等样式将这个 iframe 叠加到小游戏的垂直方向的正上方,并把 iframe 设置为 100% 透明度;
  • 受害者访问到这个页面后,肉眼看到的是一个小游戏,如果受到诱导进行了点击的话,实际上点击到的却是 iframe 中目标网站的页面。

点击劫持的危害在于,攻击利用了受害者的用户身份,在其不知情的情况下进行一些操作。如果只是迫使用户关注某个微博账号的话,看上去仿佛还可以承受,但是如果是删除某个重要文件记录,或者窃取敏感信息,那么造成的危害就难以承受了。

点击劫持漏洞的防御

  • X-FRAME-OPTIONS 机制: 服务器响应头部字段 X-Frame-Options 用来给浏览器指示是否允许一个页面嵌套在 frameiframeobject 中,使用此可以禁止其他网页使用 iframe 载入页面;
  • 通过 Javascript 来禁止网站被其他网站的 iframe 引用,详见下一节;
  • 使用认证码:要求用户输入图形中的验证码;
  • 使用 CSP(Content Security Policy)内容安全策略。

其他安全漏洞

SQL 注入

SQL 注入就是通过给 Web 应用接口传入一些特殊字符,达到欺骗服务器执行恶意的 SQL 命令。

SQL 注入漏洞属于后端的范畴,但前端也可做体验上的优化。

原因: 当使用外部不可信任的数据作为参数进行数据库的增、删、改、查时,如果未对外部数据进行过滤,就会产生 SQL 注入漏洞。

sql = "select * from users where name=" + name;

由于 SQL 语句是直接拼接的,也没有进行过滤,所以,当用户输入 '' or '1'='1' 时,这个语句的功能就是搜索 users 全表的记录。

select * from users where name='' or '1'='1';

解决: 不信任任何外部输入,避免 SQL 语句拼接。

DDoS 攻击

DoS 攻击全称拒绝服务(Denial of Service),一般来说是指攻击者对目标网站在较短的时间内发起大量请求,大规模消耗目标网站的主机资源,让它无法正常服务。在线游戏、互联网金融等领域是 DDoS 攻击的高发行业。DDoS 攻击(分布式拒绝服务 Distributed Denial of Service)则是 DoS 的升级版。

简单来说:

  • 攻击者不断地提出服务请求,让合法用户的请求无法及时处理,这就是 DoS 攻击。

  • 攻击者使用多台计算机或者计算机集群进行 DoS 攻击,就是 DDoS 攻击。

XXE 漏洞

XXE 漏洞全称 XML 外部实体漏洞(XML External Entity),当应用程序解析 XML 输入时,如果没有禁止外部实体的加载,导致可加载恶意外部文件和代码,就会造成任意文件读取、命令执行、内网端口扫描、攻击内网网站等攻击。

场景1:攻击者尝试从服务端提取数据

<?xml version="1.0"?> 
<!DOCTYPE foo [ 
<!ELEMENT foo (#ANY)> 
<!ENTITY file SYSTEM "file:///etc/passwd">]> 
]> 
<foo>&xxe;</foo>

场景2.:攻击者通过将上面的实体行更改为一下内容来探测服务器的专用网络

<!ENTITY xxe SYSTEM "https://192.168.1.1/private">]>

场景3:攻击者通过恶意文件执行拒绝服务攻击

<!ENTITY xxe SYSTEM "file:///dev/random">]>

HTTP 报头追踪漏洞

HTTP/1.1(RFC2616)规范定义了 HTTP TRACE 方法,主要是用于客户端通过向 Web 服务器提交 TRACE 请求来进行测试或获得诊断信息。

当 Web 服务器启用 TRACE 时,提交的请求头会在服务器响应的内容(Body)中完整的返回,其中 HTTP 头很可能包括 Session Token、Cookies 或其它认证信息。攻击者可以利用此漏洞来欺骗合法用户并得到他们的私人信息。

目录遍历漏洞

攻击者向 Web 服务器发送请求,通过在 URL 中或在有特殊意义的目录中附加 ../、或者附加 ../ 的一些变形(如 ..\ 或 ..// 甚至其编码),导致攻击者能够访问未授权的目录,以及在 Web 服务器的根目录以外执行命令。

命令执行漏洞

命令执行漏洞是通过 URL 发起请求,在 Web 服务器端执行未授权的命令,获取系统信息、篡改系统配置、控制整个系统、使系统瘫痪等。

文件上传漏洞

如果对文件上传路径变量过滤不严,并且对用户上传的文件后缀以及文件类型限制不严,攻击者可通过 Web 访问的目录上传任意文件,包括网站后门文件(webshell),进而远程控制网站服务器。

其他安全隐患

CDN 劫持

出于性能考虑,前端应用通常会把一些静态资源(Js、Css 等)存放到 CDN(Content Delivery Networks,内容分发网络)上面。这么做可以显著提高前端应用的访问速度,但与此同时却也隐含了一个新的安全风险。如果攻击者劫持了 CDN,或者对 CDN 中的资源进行了污染,攻击者可以肆意篡改前端页面,对用户实施攻击。

现在的 CDN 以支持 SRI 为荣,script 和 link 标签有了新的属性 integrity。SRI 全称 Subresource Integrity - 子资源完整性,是指浏览器通过验证资源的完整性(通常从 CDN 获取)来判断其是否被篡改的安全特性。

<script src="//a.example.com/js/aaa.js" integrity="sha256-xxx" crossorigin="anonymous"></script>

integrity 值分成两个部分,第一部分指定哈希值的生成算法(sha256、sha384、sha512),第二部分是经过 base64 编码的实际哈希值,两者通过中划线(-)分割。integrity 值可以包含多个由空格分隔的哈希值,只要文件匹配其中任意一个哈希值,就可以通过校验并加载该资源。

注意: 使用 SRI 需要两个条件,一是要保证资源同域或开启跨域,二是在 script 标签中提供签名以供校验。

不安全的第三方依赖

现如今进行应用开发,无论是后端服务器应用还是前端应用开发,绝大多数时候都是在借助开发框架和各种类库进行快速开发。然而,一些第三方的依赖或者插件存在很多安全性问题,也会存在这样那样的漏洞,所以使用起来得谨慎。

解决方法:一是尽量减少第三方依赖,尽量选用相对成熟的依赖包;二是使用自动化工具检查第三方依赖是否安全,比如,NSP(Node Security Platform)、Snyk 等。

iframe

在需要用到第三方提供的页面时,通常会以 iframe 的方式引入。iframe 带来更多丰富的内容和能力的同时,也带来了不少的安全隐患。因为 iframe 中的内容是由第三方来提供的,默认情况下它们不受我们的控制,它们可以在 iframe 中运行 JavaScirpt 脚本、Flash 插件、弹出对话框等等,这可能会破坏前端用户体验。

如果说 iframe 只是有可能会给用户体验带来影响,看似风险不大,那么如果 iframe 中的域名因为过期而被恶意攻击者抢注,或者第三方被黑客攻破,iframe 中的内容被替换掉了,从而利用用户浏览器中的安全漏洞下载安装木马、恶意勒索软件等等,这问题可就大了。

一般可以通过 Javascript 来禁止网站被其他网站的 iframe 引用:

if(top.location != self.location){
  top.location.href = 'http://a.example.com'
}

另外,也可以使用 html5 的新属性 sandbox,sandbox 主要是提高 iframe 安全系数。 比如,A 网站需要 iframe 引用 B 网站,但是不想被 B 网站操作 DOM、不想加载某些 JS(广告、弹框等)、当前窗口被强行跳转链接等,我们可以设置 sandbox 属性。

<iframe sandbox src="..."> ... </iframe>

sandbox 属性值如下,多项可用空格分隔:

  • allow-same-origin:允许被视为同源,即可操作父级 DOM 或 cookie 等;
  • allow-top-navigation:允许当前 iframe 的引用网页通过 URL 跳转链接或加载;
  • allow-forms:允许表单提交;
  • allow-scripts:允许执行脚本文件;
  • allow-popups:允许浏览器打开新窗口进行跳转;
  • “”: 设置为空时上面所有允许全部禁止。

opener

通过 window.open 或者 a 标签带 target="_blank" 打开的页面,能使用 window.opener 来访问源页面的 window 对象进行篡改原页面,采用以下方法可以阻止:

window.open('http://target.example.com')

// 防御方式
const target = window.open()
target.opener = null
target.location = 'http://target.example.com'
<a target="_blank" href="http://target.example.com"></a>

<!-- 防御方式 -->
<a target="_blank" href="http://target.example.com" rel="noopener noreferrer nofollow"></a>

注意: 随着浏览器发展,其安全机制也越来越完善,大多数据情况,即使能访问源页面的 window 对象,能使用的方法和属性也有限制。

安全策略

HSTS(强制安全传输)

HSTS(HTTP Strict Transport Security)是国际互联网工程组织 IETF 发布的一种互联网安全策略机制。采用 HSTS 策略的网站将保证浏览器始终连接到该网站的 HTTPS 加密版本,不需要用户手动在URL地址栏中输入加密地址,以减少会话劫持风险。

在网站全站 HTTPS 后,如果用户手动敲入网站的 HTTP 地址,或者从其它地方点击了网站的 HTTP 链接,通常依赖于服务端 301/302 跳转才能使用 HTTPS 服务。而第一次的 HTTP 请求就有可能被劫持,导致请求无法到达服务器,从而构成 HTTPS 降级劫持。

HSTS 并不是 HTTP 会话劫持的完美解决方案。用户首次访问某网站是不受 HSTS 保护的。这是因为首次访问时,浏览器还未收到 HSTS,所以仍有可能通过明文 HTTP 来访问。解决方案:一是在浏览器预置 HSTS 域名列表,二是将 HSTS 信息加入到域名系统记录中。

HSTS并不是HTTP会话劫持的完美解决方案。用户首次访问某网站是不受HSTS保护的。这是因为首次访问时,浏览器还未收到HSTS,所以仍有可能通过明文HTTP来访问。

通过 Chrome 的 chrome://net-internals/#hsts 工具,可以查询某个网站是否在预置列表中,还可以手动把某个域名加到本机预置列表。

CSP(内容安全策略)

CSP(Content Security Policy)是一个额外的安全层,用于检测并削弱某些特定类型的攻击,包括 XSS 和数据注入攻击等。无论是数据盗取、网站内容污染还是散发恶意软件,这些攻击都是主要的手段。

CSP 的本质是建立一个白名单,告诉浏览器哪种类型资源可以从哪个或者哪些域名下加载和执行

为使 CSP 可用,可以配置服务器在响应头部返回 Content-Security-Policy (X-Content-Security-Policy 是旧版本写法,无须再如此指定) 来指定内容安全策略,一个策略由一系列策略指令所组成,每个策略指令都描述了一个针对某个特定类型资源以及生效范围的策略:

# 所有内容均来自站点的同一个源 (不包括其子域名)
Content-Security-Policy: default-src 'self'

# 允许内容来自信任的域名及其子域名 (域名不必须与CSP设置所在的域名相同)
Content-Security-Policy: default-src 'self' *.trusted.com

# 允许网页应用的用户在他们自己的内容中包含来自任何源的图片, 但是限制音频或视频需从信任的资源提供者(获得),所有脚本必须从特定主机服务器获取可信的代码
Content-Security-Policy: default-src 'self'; img-src *; media-src media1.com media2.com; script-src userscripts.example.com

除此之外, meta 元素也可以被用来配置该策略:

<meta http-equiv="Content-Security-Policy" content="default-src 'self'; img-src https://*; child-src 'none';">

相关问题

为什么不推荐使用 iframe?

iframes 提供了一种简单的方式把一个网站的内容嵌入到另一个网站中,其缺点是:

  • 阻塞页面加载:及时触发 window 的 onload 事件是非常重要的,而 window 的 onload 事件需要在所有 iframe 加载完毕后(包含里面的元素)才会触发。在 Safari 和 Chrome 里,通过 JavaScript 动态设置 iframe 的 src 可以避免这种阻塞情况。
  • 链接导航问题:使用 iframe 布局必须保证正确设定导航链接,否则,被链接的页面呈现在导航框架内,让浏览者无法退后,只能离开。
  • 分散访问者注意力:iframe 布局的网站除了有时会让浏览者迷惑,分散注意力之外,还会给浏览者带来浏览麻烦,滚动条会使 iframe 布局混乱,让浏览者望而止步。
  • 不利于 SEO 优化:引擎蜘蛛访问 iframe 布局的网站时,它只会看到框架,框架里面的内容是看不到的,也就无法按照顺序解读页面,会认为这个网站是个死站点,以后绝不会再来了。
  • 安全问题:点击劫持、源页面全局对象暴露等问题。

请求头 origin、referer、host 区别?

  • Host: 指明了请求服务器的域名/IP地址和端口号,在任何类型请求中,请求头都会包含此信息。

    HTTP/1.1 的所有请求报文中必须包含一个 Host 头字段。如果一个 HTTP/1.1 请求缺少 Host 头字段或者设置了超过一个的 Host 头字段,一个 400(Bad Request)状态码会被返回。

  • Referer: 指明了当前请求页面的来源页面的地址,即表示当前页面是通过此来源页面里的链接进入的,包括协议、域名、端口号、路径、参数(不包含 hash 值)。如,https://target.example.com/

    Referer 一般情况下,只要浏览器能获取到请求源都会携带,而以下场景不会携带 Referer:

    • 来源页面采用的协议为表示本地文件的 "file" 或者 "data" URI;
    • 当前请求页面采用的是非安全协议,而来源页面采用的是安全协议(HTTPS);
    • 直接输入网址或通过浏览器书签访问;
    • 使用 JavaScript 的 Location.href 或者是 Location.replace();
    • 使用 html5 中 noreferrer。
  • Origin: 指示了请求来自于哪个站点。该字段仅指示来源服务器的名称,并不包含任何路径信息。除了不包含路径信息,该字段与 Referer 字段相似。如,https://target.example.com

    只有跨域请求(响应头部有对应的 Access-Control-Allow-Origin),或者同域时发送 Post 请求,才会携带 Origin 请求头。如果浏览器不能获取请求源,那么 Origin 满足上面情况也会携带,不过其值为 null。

参考资料

前端安全系列(一):如何防止XSS攻击?

前端安全系列之二:如何防止CSRF攻击?

web安全之--点击劫持攻击与防御技术简介

开启HSTS让浏览器强制跳转HTTPS访问

前端安全汇总(持续更新)

8大前端安全问题(上) | 洞见

内容安全策略( CSP )

© lizhao all right reserved,powered by Gitbook文件修订时间: 2023-01-14 12:34:08

results matching ""

    No results matching ""