浏览器原理 32 # 跨站脚本攻击(XSS):为什么Cookie中有HttpOnly属性?

说明

浏览器工作原理与实践专栏学习笔记

前言

支持页面中的第三方资源引用和 CORS 也带来了很多安全问题,其中最典型的就是 XSS 攻击。

什么是 XSS 攻击

XSS 全称是 Cross Site Scripting,为了与“CSS”区分开来,故简称 XSS,翻译过来就是“跨站脚本”。XSS 攻击是指浏览器原理 32 # 跨站脚本攻击(XSS):为什么Cookie中有HttpOnly属性?

  1. 黑客利用站点信息等数据上传到服务器

典型例子:喜马拉雅存储性 XSS 漏洞

乌云网(由于某些原因被关停了)在 2015 年曝出来的,参见:https://bugs.shuimugan.com/bug/view?bug_no=138479

  1. 起因是在用户设置专辑名称时,服务器对关键字过滤不严格,导致黑客将恶意代码存储到漏洞服务器上。
浏览器原理 32 # 跨站脚本攻击(XSS):为什么Cookie中有HttpOnly属性?
  1. 然后用户打开了含有恶意脚本的页面,这段代码就会在用户的页面里执行,这样就可以窃取 Cookie 等数据信息
浏览器原理 32 # 跨站脚本攻击(XSS):为什么Cookie中有HttpOnly属性?
  1. 恶意脚本可以通过 XMLHttpRequest 或者 Fetch 将用户的 Cookie 数据上传到黑客的服务器
浏览器原理 32 # 跨站脚本攻击(XSS):为什么Cookie中有HttpOnly属性?
  1. 黑客利用 Cookie 信息登录用户账户
浏览器原理 32 # 跨站脚本攻击(XSS):为什么Cookie中有HttpOnly属性?

2. 反射型 XSS 攻击

在一个反射型 XSS 攻击过程中,恶意 JavaScript 脚本属于用户发送给网站请求中的一部分,随后网站又把恶意 JavaScript 脚本返回给用户。当恶意 JavaScript 脚本在用户页面中被执行时,黑客就可以利用该脚本做一些恶意操作。

接下来我们搭建一个简单的 Node 服务程序来看看什么是反射型 XSS

  1. 在一个新的文件夹里打开控制台输入下面两个命令进行初始化操作,以及依赖安装
npm init npm i express ejs 
浏览器原理 32 # 跨站脚本攻击(XSS):为什么Cookie中有HttpOnly属性?
  1. 测试代码编写

路由代码:index.js

var express = require('express'); var app = express(); var ejs = require('ejs');  // 设置html引擎 app.engine('html', ejs.renderFile); app.set('views', __dirname + '/'); // 设置视图引擎 app.set('view engine', 'html');  app.get('/', function(req, res, next) {   console.log('进入首页:哈哈哈哈');   res.render('index', {     title: '凯小默的 xss 测试页面',     xss: req.query.xss   }); });  app.listen(3000, () => {   console.log('服务启动成功!!!');   console.log("server listen on localhost:3000"); });  

视图代码:index.html

<!DOCTYPE html> <html> <head>   <title><%= title %></title> </head> <body>   <h1><%= title %></h1>   <p>Welcome to <%= title %></p>   <div>     <!-- 将 URL 中 xss 参数的内容显示在页面 -->     <%- xss %>   </div> </body> </html> 
  1. 启动服务,然后我们访问:http://localhost:3000/?xss=kaimo666
node index.js 
浏览器原理 32 # 跨站脚本攻击(XSS):为什么Cookie中有HttpOnly属性?
  1. 页面效果:xss参数被渲染到了页面
浏览器原理 32 # 跨站脚本攻击(XSS):为什么Cookie中有HttpOnly属性?
  1. 改变参数的值换成 http://localhost:3000/?xss=<script>alert('你被xss攻击了')</script>
浏览器原理 32 # 跨站脚本攻击(XSS):为什么Cookie中有HttpOnly属性?
  1. 看一下dom,发现恶意脚本插入到页面中了。
浏览器原理 32 # 跨站脚本攻击(XSS):为什么Cookie中有HttpOnly属性?

总结:从上面的例子我们可以看出,用户将一段含有恶意代码的请求提交给 Web 服务器,Web 服务器接收到请求时,又将恶意代码反射给了浏览器端,这就是反射型 XSS 攻击。

注意:Web 服务器不会存储反射型 XSS 攻击的恶意脚本,这是和存储型 XSS 攻击不同的地方。

3. 基于 DOM 的 XSS 攻击

基于 DOM 的 XSS 攻击是不牵涉到页面 Web 服务器的。主要是在 Web 资源传输过程或者在用户使用页面的过程中修改 Web 页面的数据。

比如:

  • 通过 WiFi 路由器劫持的
  • 通过本地恶意软件来劫持的

如何阻止 XSS 攻击

  • 存储型 XSS 攻击和反射型 XSS 攻击都是需要经过 Web 服务器来处理,属于服务端的:<script>alert('你被xss攻击了')</script>

    过滤

    code: 

    转码

    code:&lt;script&gt;alert(&#39;你被xss攻击了&#39;)&lt;/script&gt; 

    2. 充分利用 CSP

    CSP 功能:

    1. 限制加载其他域下的资源文件,这样即使黑客插入了一个 JavaScript 文件,这个 JavaScript 文件也是无法被加载的;
    2. 禁止向第三方域提交数据,这样用户数据也不会外泄;
    3. 禁止执行内联脚本和未授权的脚本;
    4. 还提供了上报机制,这样可以帮助我们尽快发现有哪些 XSS 攻击,以便尽快修复问题。

    3. 使用 HttpOnly 属性

    由于很多 XSS 攻击都是来盗用 Cookie 的,因此还可以通过使用 HttpOnly 属性来保护我们 Cookie 的安全。

    通常服务器可以将某些 Cookie 设置为 HttpOnly 标志,HttpOnly 是服务器通过 HTTP 响应头来设置的。

    比如:下面是打开 Google 时,HTTP 响应头中的一段:set-cookie 属性值最后使用了 HttpOnly 来标记该 Cookie。

    set-cookie: NID=189=M8q2FtWbsR8RlcldPVt7qkrqR38LmFY9jUxkKo3-4Bi6Qu_ocNOat7nkYZUTzolHjFnwBw0izgsATSI7TZyiiiaV94qGh-BzEYsNVa7TZmjAYTxYTOM9L_-0CN9ipL6cXi8l6-z41asXtm2uEwcOC5oh9djkffOMhWqQrlnCtOI; expires=Sat, 18-Apr-2020 06:52:22 GMT; path=/; domain=.google.com; HttpOnly 

    使用 HttpOnly 标记的 Cookie 只能使用在 HTTP 请求过程中,所以无法通过 JavaScript 来读取这段 Cookie。

    通过 Chrome 开发者工具来查看哪些 Cookie 被标记了 HttpOnly:比如下图里的 UserInfo 这个 Cookie 的 HttpOlny 属性是被勾选上的,所以 UserInfo 的内容是无法通过 document.cookie 是来读取的。

    浏览器原理 32 # 跨站脚本攻击(XSS):为什么Cookie中有HttpOnly属性?
    可以自己在控制台测试一下,输入 document.cookie ,然后 ctrl + f 去搜索 UserInfo 是找不到的。
    浏览器原理 32 # 跨站脚本攻击(XSS):为什么Cookie中有HttpOnly属性?

    因此一些比较重要的数据建议设置 HttpOnly 标志。