1.能不能说一说XSS攻击
1.1 什么是 XSS 攻击?
XSS
全称是 Cross Site Scripting
(即跨站脚本
),为了和 CSS 区分,故叫它XSS
。XSS 攻击是指浏览器中执行恶意脚本(无论是跨域还是同域),从而拿到用户的信息并进行操作。
这些操作一般可以完成下面这些事情:
- 窃取
Cookie
。 - 监听用户行为,比如输入账号密码后直接发送到黑客服务器。
- 修改 DOM 伪造登录表单。
- 在页面中生成浮窗广告。
通常情况,XSS 攻击的实现有三种方式——存储型、反射型和文档型。原理都比较简单,先来一一介绍一下。
存储型存储型
,顾名思义就是将恶意脚本存储了起来,确实,存储型的 XSS 将脚本存储到了服务端的数据库,然后在客户端执行这些脚本,从而达到攻击的效果。
常见的场景是留言评论区提交一段脚本代码,如果前后端没有做好转义的工作,那评论内容存到了数据库,在页面渲染过程中直接执行
, 相当于执行一段未知逻辑的 JS 代码,是非常恐怖的。这就是存储型的 XSS 攻击。
反射型反射型XSS
指的是恶意脚本作为网络请求的一部分。
比如我输入:
http://sanyuan.com?q=<script>alert("你完蛋了")</script>
这样,在服务器端会拿到q
参数,然后将内容返回给浏览器端,浏览器将这些内容作为HTML的一部分解析,发现是一个脚本,直接执行,这样就被攻击了。
之所以叫它反射型
, 是因为恶意脚本是通过作为网络请求的参数,经过服务器,然后再反射到HTML文档中,执行解析。和存储型
不一样的是,服务器并不会存储这些恶意脚本。
文档型
文档型的 XSS 攻击并不会经过服务端,而是作为中间人的角色,在数据传输过程劫持到网络数据包,然后修改里面的 html 文档!
这样的劫持方式包括WIFI路由器劫持
或者本地恶意软件
等。
1.2 防范措施
明白了三种XSS
攻击的原理,我们能发现一个共同点: 都是让恶意脚本直接能在浏览器中执行。
那么要防范它,就是要避免这些脚本代码的执行。
为了完成这一点,必须做到一个转义,两个利用。
转义字符**
首先,对于用户的输入应该是永远不信任的。最普遍的做法就是转义输入输出的内容,对于引号、尖括号、斜杠进行转义
function escape(str) {
str = str.replace(/&/g, '&')
str = str.replace(/</g, '<')
str = str.replace(/>/g, '>')
str = str.replace(/"/g, '&quto;')
str = str.replace(/'/g, ''')
str = str.replace(/`/g, '`')
str = str.replace(/\//g, '/')
return str
}
通过转义可以将攻击代码 <script>alert(1)</script>
变成
// -> <script>alert(1)</script>
escape('<script>alert(1)</script>')
但是对于显示富文本来说,显然不能通过上面的办法来转义所有字符,因为这样会把需要的格式也过滤掉。对于这种情况,通常采用白名单过滤的办法,当然也可以通过黑名单过滤,但是考虑到需要过滤的标签和标签属性实在太多,更加推荐使用白名单的方式。
const xss = require('xss')
let html = xss('<h1 id="title">XSS Demo</h1><script>alert("xss");</script>')
// -> <h1>XSS Demo</h1><script>alert("xss");</script>
console.log(html)
以上示例使用了 js-xss
来实现,可以看到在输出中保留了 h1
标签且过滤了 script
标签。
利用 CSP
CSP,即浏览器中的内容安全策略,它的核心思想就是服务器决定浏览器加载哪些资源,具体来说可以完成以下功能:
- 限制其他域下的资源加载。
- 禁止向其它域提交数据。
- 提供上报机制,能帮助我们及时发现 XSS 攻击。
CSP 本质上就是建立白名单,开发者明确告诉浏览器哪些外部资源可以加载和执行。我们只需要配置规则,如何拦截是由浏览器自己实现的。我们可以通过这种方式来尽量减少 XSS 攻击。
通常可以通过两种方式来开启 CSP:
- 设置 HTTP Header 中的
Content-Security-Policy
- 设置
meta
标签的方式<meta http-equiv="Content-Security-Policy">
这里以设置 HTTP Header 来举例
只允许加载本站资源
Content-Security-Policy: default-src ‘self’
只允许加载 HTTPS 协议图片
Content-Security-Policy: img-src https://*
允许加载任何来源框架
Content-Security-Policy: child-src 'none'
当然可以设置的属性远不止这些,你可以通过查阅 文档 的方式来学习,这里就不过多赘述其他的属性了。
对于这种方式来说,只要开发者配置了正确的规则,那么即使网站存在漏洞,攻击者也不能执行它的攻击代码,并且 CSP 的兼容性也不错。
利用 HttpOnly
很多 XSS 攻击脚本都是用来窃取Cookie, 而设置 Cookie 的 HttpOnly 属性后,JavaScript 便无法读取 Cookie 的值。这样也能很好的防范 XSS 攻击。1.3 总结
XSS
攻击是指浏览器中执行恶意脚本, 然后拿到用户的信息进行操作。主要分为存储型
、反射型
和文档型
。防范的措施包括:一个信念: 不要相信用户的输入,对输入内容转码或者过滤,让其不可执行。
两个利用: 利用 CSP,利用 Cookie 的 HttpOnly 属性。
2.能不能说一说CSRF攻击
2.1 什么是CSRF攻击?
CSRF(Cross-site request forgery), 即跨站请求伪造,指的是黑客诱导用户点击链接,打开黑客的网站,然后黑客利用用户目前的登录状态发起跨站请求。
举个例子, 你在某个论坛点击了黑客精心挑选的小姐姐图片,你点击后,进入了一个新的页面。
那么恭喜你,被攻击了:)
你可能会比较好奇,怎么突然就被攻击了呢?接下来我们就来拆解一下当你点击了链接之后,黑客在背后做了哪些事情。
可能会做三样事情。列举如下:1. 自动发 GET 请求
黑客网页里面可能有一段这样的代码:
<img src="https://xxx.com/info?user=hhh&count=100"></img>
进入页面后自动发送 get 请求,值得注意的是,这个请求会自动带上关于 xxx.com 的 cookie 信息(这里是假定你已经在 xxx.com 中登录过)。
假如服务器端没有相应的验证机制,它可能认为发请求的是一个正常的用户,因为携带了相应的 cookie,然后进行相应的各种操作,可以是转账汇款以及其他的恶意操作。2. 自动发 POST 请求
黑客可能自己填了一个表单,写了一段自动提交的脚本。
<form id='hacker-form' action="https://xxx.com/info" method="POST">
<input type="hidden" name="user" value="hhh" />
<input type="hidden" name="count" value="100" />
</form>
<script>document.getElementById('hacker-form').submit();</script>
同样也会携带相应的用户 cookie 信息,让服务器误以为是一个正常的用户在操作,让各种恶意的操作变为可能。
3. 诱导点击发送 GET 请求
在黑客的网站上,可能会放上一个链接,驱使你来点击:
<a href="https://xxx/info?user=hhh&count=100" taget="_blank">点击进入修仙世界</a>
点击后,自动发送 get 请求,接下来和
自动发 GET 请求
部分同理。
这就是CSRF
攻击的原理。和XSS
攻击对比,CSRF 攻击并不需要将恶意代码注入用户当前页面的html
文档中,而是跳转到新的页面,利用服务器的验证漏洞和用户之前的登录状态来模拟用户进行操作。2.2 防范措施
1. 利用Cookie的SameSite属性
CSRF攻击
中重要的一环就是自动发送目标站点下的Cookie
,然后就是这一份 Cookie 模拟了用户的身份。因此在Cookie
上面下文章是防范的不二之选。
恰好,在 Cookie 当中有一个关键的字段,可以对请求中 Cookie 的携带作一些限制,这个字段就是SameSite
。SameSite
可以设置为三个值,Strict
、Lax
和None
。
a. 在Strict
模式下,浏览器完全禁止第三方请求携带Cookie。比如请求sanyuan.com
网站只能在sanyuan.com
域名当中请求才能携带 Cookie,在其他网站请求都不能。
b. 在Lax
模式,就宽松一点了,但是只能在get 方法提交表单
况或者a 标签发送 get 请求
的情况下可以携带 Cookie,其他情况均不能。
c. 在None
模式下,也就是默认模式,请求会自动携带上 Cookie。2. 验证来源站点
这就需要要用到请求头中的两个字段: Origin和Referer。
其中,Origin只包含域名信息,而Referer包含了具体
的 URL 路径。
当然,这两者都是可以伪造的,通过 Ajax 中自定义请求头即可,安全性略差。3. CSRF Token
Django
作为 Python 的一门后端框架,用它开发过的同学就知道,在它的模板(template)中, 开发表单时,经常会附上这样一行代码:{% csrf_token %}
这就是
CSRF Token
的典型应用。那它的原理是怎样的呢?
首先,浏览器向服务器发送请求时,服务器生成一个字符串,将其植入到返回的页面中。
然后浏览器如果要发送请求,就必须带上这个字符串,然后服务器来验证是否合法,如果不合法则不予响应。这个字符串也就是CSRF Token
,通常第三方站点无法拿到这个 token, 因此也就是被服务器给拒绝。2.3 总结
CSRF(Cross-site request forgery), 即跨站请求伪造,指的是黑客诱导用户点击链接,打开黑客的网站,然后黑客利用用户目前的登录状态发起跨站请求。
CSRF
攻击一般会有三种方式:自动 GET 请求
- 自动 POST 请求
- 诱导点击发送 GET 请求。
防范措施: 利用 Cookie 的 SameSite 属性
、验证来源站点
和CSRF Token
。
3.中间人攻击
3.1 导语:
你可能听过中间人攻击(MiTM),你可能对它有一个模糊的概念。但是,你仍旧回想“到底什么是中间人攻击”,对吗?让我们来向你解释一下。正如它的名字所暗示的,当未授权的实体将自己置于两个通信系统之间并试图截获正在传递的信息时,便是发生这类攻击的时候。简单的来说,MiTM就是现代版的窃听。
我们几分钟的时间就可以进一步了解中间人(MITM)攻击。首先看看你周围的事物吧,看看你的智能手机,看看它里面的app,看看你的pc,看看这些互相八卦的智能连接设备,看看你正在访问的网站,是什么在驱动着所有这些东西?答案就是 数据/信息,数据的本质特征是它能够四处传播,无论他是一个pc到另一个pc,一个服务器到另一个服务器,还是一个国家到另一个国家——数据没有边界。
不幸的是,所有这些传播都无可避免的引入了安全和隐私问题。当数据离开一个端点前往另一个端点时。传输的期间便是对数据失去控制的时候,当一个攻击者将自己置于两个端点之间并试图获取和阻碍数据传输时,便称为中间人(MiTM)攻击,用通俗的话讲,这很像偷听。
没错,当你试图在不让两人知道的情况下,偷听他们的讲话,这就像是中间人攻击。
3.2 到底什么是中间人攻击
当数据传输发生在一个设备(pc/设备)和服务器之间时,攻击者使用其技能和工具将自己置于两个端点之间并截获数据,尽管交谈的双方认为他是在与对方交谈,但是实际上他们是在与攻击者进行交流,这便是中间人攻击。
3.3 它是如何工作的
谈及MiTM时,并不是只有一种方法可以造成损害——答案是四种,一般来说,有嗅探、数据包注入、会话劫持和ssl剥离。
1.嗅探
嗅探或数据包嗅探是一种用于捕获流进和流出系统/网络的数据包的技术。网络中的数据包嗅探就好像电话中的监听。记住,如果使用正确,数据包嗅探是合法的,许多公司出于“安全目的”都会使用它。
2.数据包注入
在这种技术中,攻击者会将恶意数据包注入常规数据中。这样用户便不会注意到文件/恶意软件。因为它们是合法通讯流的一部分。在中间人攻击和拒绝式攻击中,这种文件是很常见的。
3.会话劫持
你曾经遇到过“会话超时”这种错误嘛,如果你进行过网上支付或填写一个表格,你应该知道它们。在你登陆仅你的银行账户和退出登录这一段期间便称为一个会话,这些会话通常都是黑客的攻击目标,因为它们包含潜在的重要信息。在大多数案例中,黑客会潜伏在会话中,并最终控制它,这些攻击的执行方式有很多种。
4.ssl剥离
ssl剥离或ssl降级攻击是MiTM一种十分罕见的方式,但是也是最危险的一种。众所周知,ssl/tls证书通过加密保护着我们的通信安全。在ssl剥离攻击中,攻击者使ssl/tls连接剥落,随之协议便从安全的HTTPS变成了不安全的HTTP。
3.4 如何防止中间人攻击
- 确保在URL前你所访问的网站有HTTPS
- 点击电子邮件前,检查电子邮件的发件人
- 不要再公共WI-FI网络上购买或发送敏感数据
- 不要点击恶意邮件和网址连接
- 不下载盗版内容
- 将安全工具正确的安装在系统上
-
4.点击劫持
点击劫持是一种视觉欺骗的攻击手段。攻击者将需要攻击的网站通过
iframe
嵌套的方式嵌入自己的网页中,并将iframe
设置为透明,在页面中透出一个按钮诱导用户点击。
对于这种攻击方式,推荐防御的方法有两种。4.1 X-FRAME-OPTIONS
X-FRAME-OPTIONS
是一个 HTTP 响应头,在现代浏览器有一个很好的支持。这个 HTTP 响应头 就是为了防御用iframe
嵌套的点击劫持攻击。
该响应头有三个值可选,分别是 DENY
,表示页面不允许通过iframe
的方式展示SAMEORIGIN
,表示页面可以在相同域名下通过iframe
的方式展示ALLOW-FROM
,表示页面可以在指定来源的iframe
中展示4.2 JS 防御
对于某些远古浏览器来说,并不能支持上面的这种方式,那我们只有通过 JS 的方式来防御点击劫持了。
以上代码的作用就是当通过<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>
iframe
的方式加载页面时,攻击者的网页直接不显示所有内容了。