Jacleklm's Blog

Web安全

2019/10/27

XSS

定义

跨站脚本攻击(Cross Site Scripting),缩写为XSS(避免和CSS混淆就没缩写成CSS)。恶意攻击者往Web页面里插入恶意Script代码,当用户浏览该页之时,嵌入其中Web里面的Script代码会被执行,从而达到恶意攻击用户的目的

XSS攻击注入点

HTML节点内容

节点中包含用户输入的内容。例如

1
2
3
<div>#{content}</div>
// content能被输入成包含一段脚本
<div><script> </script></div>

HTML属性

1
2
3
4
// 例如,这个img的src的属性来自用户的输入或者是数据库存储的用户之前提交的
<img src="#{img}"/>
// 如果用户输入的时候输入了 1" onerror="alert(1) ,则能被执行成
<img src="1" onerror="alert(1)"/>

JS代码

跟之前的原理一样,某个属性是来自于用户的输入,用户可以通过输入引号的方式增加一些代码

1
2
3
var data = "#{data}"
// 能被用户输入写成
var data = "hello";alert(1);"";

富文本

写邮件的时候我们能定义字体的各种格式,提交的时候其实就是提交这一段的html。提交这么多一段html是有XSS攻击风险的。这种情况要用白名单防御方法

攻击类型

  • 反射型: 通过修改 URL 参数的方式加入攻击代码,诱导用户访问链接从而进行攻击
    1
    2
    // http://www.domain.com?name=<script>alert(1)</script>
    <div>{{name}}</div>
    上述 URL 输入可能会将 HTML 改为<div><script>alert(1)</script></div> ,这样页面中就凭空多了一段可执行脚本。这种攻击类型是反射型攻击,也可以说是 DOM-based 攻击
    还有另一个例子见Web安全之XSS攻防
  • 存储型: 攻击的代码被服务端写入进数据库中。比如在一些论坛的评论中,写script标签加alert语句,如果前后端没有做好防御的话,这段评论就会被存储到数据库中,这样每个打开该页面的用户都会被攻击到

防御措施

转义字符(普遍)

转义输入输出的内容,对于引号,尖括号,斜杠进行转义

1
2
3
4
5
6
7
8
9
10
function escape(str) {
str = str.replace(/&/g, "&amp;");
str = str.replace(/</g, "&lt;");
str = str.replace(/>/g, "&gt;");
str = str.replace(/"/g, "&quto;");
str = str.replace(/'/g, "&##39;");
str = str.replace(/`/g, "&##96;");
str = str.replace(/\//g, "&##x2F;");
return str
}

通过转义可以将攻击代码<script>alert(1)</script>变成

1
2
// -> &lt;script&gt;alert(1)&lt;&##x2F;script&gt;
escape('<script>alert(1)</script>')

CSP白名单

对于显示富文本来说,不能通过上面的办法来转义所有字符,因为这样会把需要的格式也过滤掉。这种情况通常采用白名单过滤的办法,明确告诉浏览器哪些外部资源可以加载和执行。
通过两种方式来开启 CSP:

  • 设置 HTTP Header 中的 Content-Security-Policy: ‘某某策略’

    写法以多个键值对的形式存在,键和值用空格隔开,不同对用分号分开。键的类型有限制全局default-src,资源类型的connect-src、mainfest-src、img-src、font-src、media-src、style-src、frame-src、script-src… ; 值可以写成 * ,或某个url

  • 设置 meta 标签的方式 <meta http-equiv="Content-Security-Policy" content="某某策略">

CSRF

概念及攻击原理

跨站请求伪造(Cross-site request forgery),
CSRF攻击的本质在于利用用户的身份,执行非本意的操作。重点在于:CSRF的请求是跨域且伪造的
跨站请求伪造的攻击是攻击者通过一些技术手段欺骗用户的浏览器去访问用户曾经认证过的网站并执行一些操作(如发送邮件、发消息、甚至财产操作如转账和购买商品等。攻击者的网站借用用户身份向目标网站发送一些请求)。由于浏览器曾经认证过,所以被访问的网站会认为是真正的用户操作而去执行。这利用了web登录身份认证的一个漏洞:简单的身份认证只能保证请求来自用户的浏览器,但不能识别请求是用户自愿发出的

假设网站中有一个通过 Get 请求提交用户评论的接口,那么攻击者就可以在钓鱼网站中加入一个图片,图片的地址就是评论接口

1
<img src="http://www.domain.com/xxx?comment='attack'"/>

如何防范

可以遵循以下几种规则:

  1. Get 请求不对数据进行修改
  2. 不让第三方网站访问到用户 Cookie
  3. 阻止第三方网站请求接口
  4. 请求时附带验证信息,比如验证码或者 Token

对Cookie设置SameSite属性

该属性表示 Cookie 不随着跨域请求发送,可以很大程度减少 CSRF 的攻击,但是该属性目前并不是所有浏览器都兼容

验证Referer

可以通过验证 Referer 来判断该请求是否为第三方网站发起的

利用Token

服务器下发一个随机 Token,每次发起请求时将 Token 携带上,服务器验证 Token 是否有效

Cookie的安全策略

属性 作用
value 如果用于保存用户登录态,应该将该值加密,不能使用明文的用户标识
http-only 不能通过 JS 访问 Cookie,减少 XSS 攻击
secure 只能在协议为 HTTPS 的请求中携带
same-site 规定浏览器不能在跨域请求中携带 Cookie,减少 CSRF 攻击

点击劫持

概念

点击劫持是一种视觉欺骗的攻击手段。攻击者将需要攻击的网站通过 iframe 嵌套的方式嵌入自己的网页中,并将 iframe 设置为透明,在页面中透出一个按钮诱导用户点击。

防范措施

设置HTTP头:X-FRAME-OPTIONS
这个 HTTP 响应头 就是为了防御用 iframe 嵌套的点击劫持攻击
该响应头有三个值可选,分别是

  • DENY,表示页面不允许通过 iframe 的方式展示
  • SAMEORIGIN,表示页面可以在相同域名下通过 iframe 的方式展示
  • ALLOW-FROM,表示页面可以在指定来源的 iframe 中展示

JS 防御

对于某些远古浏览器来说,并不能支持上面的这种方式,那我们只有通过 JS 的方式来防御点击劫持了
当通过 iframe 的方式加载页面时,攻击者的网页直接不显示所有内容了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<head>
<style id="click-jack">
html {
display: none !important;
}
</style>
</head>
<body>
<script>
if (self == top) {
var style = document.getElementById('click-jack')
document.body.removeChild(style)
} else {
top.location = self.location
}
</script>
</body>

中间人攻击

概念

中间人攻击是攻击方同时与服务端和客户端建立起了连接,并让对方认为连接是安全的,但是实际上整个通信过程都被攻击者控制了。攻击者不仅能获得双方的通信信息,还能修改通信信息

如何防范

防御中间人攻击其实并不难,只需要增加一个安全通道来传输信息。HTTPS 就可以用来防御中间人攻击,但是并不是说使用了 HTTPS 就可以高枕无忧了,因为如果你没有完全关闭 HTTP 访问的话,攻击方可以通过某些方式将 HTTPS 降级为 HTTP 从而实现中间人攻击

参考资料
慕课网-Web前后端漏洞分析与防御
《白帽子讲Web安全》
Web安全之XSS攻防
呓语
poetries

CATALOG
  1. 1. XSS
    1. 1.1. 定义
    2. 1.2. XSS攻击注入点
      1. 1.2.1. HTML节点内容
      2. 1.2.2. HTML属性
      3. 1.2.3. JS代码
      4. 1.2.4. 富文本
    3. 1.3. 攻击类型
    4. 1.4. 防御措施
      1. 1.4.1. 转义字符(普遍)
      2. 1.4.2. CSP白名单
  2. 2. CSRF
    1. 2.1. 概念及攻击原理
    2. 2.2. 如何防范
      1. 2.2.1. 对Cookie设置SameSite属性
      2. 2.2.2. 验证Referer
      3. 2.2.3. 利用Token
  3. 3. Cookie
    1. 3.1. Cookie的安全策略
  4. 4. 点击劫持
    1. 4.1. 概念
    2. 4.2. 防范措施
    3. 4.3. JS 防御
  5. 5. 中间人攻击
    1. 5.1. 概念
    2. 5.2. 如何防范