XSS与CSRF攻击
一、XSS
Cross Site Script,跨站脚本攻击。是指攻击者在网站上注入恶意客户端代码,通过恶意脚本对客户端网页进行篡改,从而在用户浏览网页时,对用户浏览器进行控制或者获取用户隐私数据的一种攻击方式。
1.容易发生的场景
(1)数据从一个不可靠的链接进入到一个web应用程序。
(2)没有过滤掉恶意代码的动态内容被发送给web用户。
2.XSS攻击的共同点
将一些隐私数据如cookie、session发送给攻击者,将受害者重定向到一个由攻击者控制的网站,在受害者机器上进行恶意操作。
3.XSS攻击的类型
分为存储性(持久型)、反射型(非持久型)、基于DOM
(1)反射型
反射型XSS攻击把用户输入的数据"反射"给浏览器。该攻击方式通常诱使用户 点击一个恶意链接,或者 提交一个表单, 在用户点击链接或提交表单的同时向用户访问的网站注入脚本。
实践:模拟反射型XSS攻击
在正常页面上添加一个恶意链接。恶意链接的地址指向localhost:3000。
然后攻击者有一个node服务来处理对localhost:3000的请求:
const Koa = require('koa');
const Router = require('koa-router');
const app = new Koa();
const router = new Router();
router.get('/', async ctx => {
ctx.body = '<script>alert("XSS攻击")</script>';
});
app.use(router.routes())
app.listen('3000', ()=> {
console.log('Listening 3000');
});
当用户点击恶意链接时,页面跳转到攻击者预先准备的页面,会发现在攻击者的页面执行了 js 脚本。这样就产生了反射型 XSS 攻击。攻击者可以注入任意的恶意脚本进行攻击,可能注入恶作剧脚本或注入能获取用户隐私数据(如cookie)的脚本。
(2)存储型
存储型XSS把用户输入的带有恶意脚本的数据存储在服务器端。当浏览器请求数据时,服务器返回脚本并执行。
常见的场景是攻击者在社区或论坛上写下一篇包含恶意 JavaScript 代码的文章或评论,文章或评论发表后,所有访问该文章或评论的用户,都会在他们的浏览器中执行这段恶意的 JavaScript 代码。
实践:模拟存储型XSS攻击
例如在一个论坛评论输入框内写下:
<script>alert("XSS攻击")</script>
该内容提交后会保存至该论坛数据库。而该论坛显示评论的页面则会把各用户提交的评论内容输出。例如显示评论页面可能是这样的:
<div>
<p>用户1</p>
<div>哈哈哈说得真好</div>
</div>
<div>
<p>用户2</p>
<div>赞同</div>
</div>
<div>
<p>XSS攻击者</p>
<div><script>alert("XSS攻击")</script>
</div>
</div>
其他用户访问该评论显示页面时,恶意脚本就会在浏览器端执行。
(4) 基于DOM
基于DOM的XSS是指通过恶意脚本修改页面的DOM结构。是纯粹发生在 客户端的攻击。
实践:模拟基于DOM的XSS攻击
某正常网站的内容会显示url地址的中的参数。例如url为:
http://xxx.com?name=abc
其页面smarty模板为:
<div><%$smarty.get.name%></div>
得到页面为:
<div>abc</div>
那么XSS攻击者可以制作出这样的链接;
http://xxx.com?name=<script>alert("XSS攻击")</script>
那么其页面最终得到的是:
<div>
<script>alert("XSS攻击")</script>
</div>
如果其他用户点击了XSS攻击者构造的链接,那么页面中就多了一段可执行脚本。这种攻击也可以说是反射型的。
4.XSS攻击的防范
(1) 现代主流浏览器内置CSP
内容安全策略(CSP)用于检测和减轻用于 Web 站点的特定类型的攻击,例如 XSS 和数据注入等。
CSP本质上是建立白名单,规定了浏览器只能执行特定来源的代码。
通过 Content-Security-PolicyHTTP头来开启CSP:
- 只允许加载本站资源Content-Security-Policy: default-src 'self'
- 只允许加载HTTPS协议图片
Content-Security-Policy: img-src https://* - 允许加载任何来源框架 Content-Security-Policy: child-src 'none'
(2) HttpOnly阻止Cookie劫持攻击
为避免跨域脚本 (XSS) 攻击,通过JavaScript的 Document.cookie API无法访问带有 HttpOnly 标记的Cookie,它们只应该发送给服务端。如果 Cookie 不想被客户端 JavaScript 脚本调用,那么就应该为其设置 HttpOnly 标记。
如上所述,发起XSS的攻击者既然可以通过注入恶意脚本获取用户的 Cookie 信息。所以,严格来说,HttpOnly 并非阻止 XSS 攻击,而是能阻止 XSS 攻击后的 Cookie 劫持攻击。
含有HttpOnly标志的Cookie在HTTP响应头Set-Cookie:
Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT; Secure; HttpOnly
实践
设置含有HttpOnly标志的Cookie:
document.cookie = encodeURIComponent('name')+ '=' + encodeURIComponent('BnnieWang') + ';secure;HttpOnly'
//"name=BnnieWang;secure;HttpOnly"
验证:执行上述代码后输入document.cookie,可以看到得到的cookie中没有刚刚设置的这个cookie。
Tips: Koa的ctx.cookies.set()方法是默认httpOnly为true
对比cookie的secure标记
标记为 Secure 的Cookie只能通过被HTTPS协议加密过的请求发送给服务端。
但即便设置了 Secure 标记,敏感信息也不应该通过Cookie传输,因为Cookie有其固有的不安全性,Secure 标记也无法提供确实的安全保障。也就是说,即使设置了Secure标志,还是可以从前端通过document.cookie获取该cookie。从 Chrome 52 和 Firefox 52 开始,不安全的站点(http:)无法使用Cookie的 Secure 标记。
(3) 输入检查/XSS Filter
对于用户的任何输入要进行检查、过滤和转义。一般是检查用户输入的数据中是否包含 <,>,script 等特殊字符,如果存在,则对特殊字符进行过滤或编码。
前端框架中自带的decodingMap
一些前端框架中,都有一份decodingMap,会对用户输入所包含的特殊字符或标签进行编码或过滤,以防止XSS攻击。例如vue中的decodingMap:
// 在 vuejs 中,如果输入带 script 标签的内容,会直接过滤掉
const decodingMap = {
'<': '<',
'>': '>',
'"': '"',
'&': '&',
'
': '\n'
}
手动对输入内容进行转义:
function escape(str) {
str = str.replace(/&/g, '&');
str = str.replace(/</g, '<');
str = str.replace(/>/g, '>');
str = str.replace(/"/g, '&quto;');
str = str.replace(/'/g, '&##39;');
str = str.replace(/\//g, '&##x2F;')
}
通过转义攻击脚本:
<script>alert("XSS攻击")</script>
可转变为字符串:
<script>alert(&quto;XSS攻击;&quto;)<&##x2F;script>
注意:富文本显示的转义
对于显示富文本来说,不能用上述方法转义所有字符,因为这样会把需要的格式也去掉。例如会把< h1>标题 < /h1>也转义掉。这种方法通常采用白名单过滤的办法,把需要的标签(如< h1>)保留。
例如使用'xss'库:
const xss = require('xss');
const html = xss('<h1>XSS Demo</h1><script>alert("xss");</script>');
console.log(html)// <h1>XSS Demo</h1><script>alert("xss");</script>
这样就在过滤了script标签的同时保留了h1标签。
(4)输出检查
在变量输出到 HTML 页面时,也可以使用上述(3)类似的编码或转义的方式来防御 XSS 攻击。
二、CSRF
Cross Site Request Forgery,跨站请求伪造。是劫持受信任用户向服务器发送非预期请求的攻击方式。例如,这些非预期请求可能在url后加入一些恶意的参数,从而达到攻击者的目的。
通常情况下,CSRF 攻击是攻击者借助受害者的 Cookie 骗取服务器的信任,可以在受害者毫不知情的情况下以受害者名义伪造请求发送给受攻击服务器,从而在并未授权的情况下执行在权限保护之下的操作。
简单来说,CSRF就是利用用户的登录态发起恶意请求。
1. 场景举例:通过 Cookie 进行 CSRF 攻击
假设有一个 bbs 站点:http://www.c.com,当登录后的用户发起如下 GET 请求时,会删除 ID 指定的帖子:
http://www.c.com:8002/content/delete/:id
如发起 http://www.c.com:8002/content/delete/87343 请求时,会删除 id 为 87343 的帖子。当用户登录之后,服务器会设置如下 cookie并发送到浏览器:
res.setHeader('Set-Cookie', ['user=22333; expires=Sat, 21 Jul 2018 00:00:00 GMT;']);
然后CSRF 攻击者准备了一个页面http://www.a.com:
<p>CSRF 攻击者准备的网站:</p>
<img src="http://www.c.com:8002/content/delete/87343">
该页面使用了一个 img 标签,其地址指向了删除用户帖子的链接:http://www.c.com:8002/content/delete/87343
可以看到,当登录用户访问攻击者的网站时,会向 www.c.com 发起一个删除用户帖子的请求。由于用户已经登录,则www.c.com下已经存在了该user=22333的cookie,那么删除请求就会顺利进行。此时若用户在切换到 www.c.com 的帖子页面刷新,会发现ID 为 87343 的帖子已经被删除。
这个攻击过程中,攻击者借助受害者的 Cookie 骗取服务器的信任,但并不能拿到 Cookie,也看不到 Cookie 的内容。而对于服务器返回的结果,由于浏览器同源策略的限制,攻击者也无法进行解析。因此,攻击者无法从返回的结果中得到任何东西,他所能做的就是给服务器发送请求,以执行请求中所描述的命令,在服务器端直接改变数据的值,而非窃取服务器中的数据。
若 CSRF 攻击的目标并不需要使用 Cookie,则也不必顾虑浏览器的 Cookie 策略了。
2. CSRF的防范
防范CSRF可遵循以下几种规则:
- Get 请求不对数据进行修改
- 不让第三方网站访问到用户Cookie
- 阻止第三方网站请求接口
- 请求时附带验证信息,如验证码或Token
(1)验证码
CSRF攻击往往是在用户不知情的情况下发起了网络请求。而验证码会保证用户必须与应用进行交互,才能完成请求。
(2)Referer Check
在HTTP头中有一个字段叫做Referer,它记录了该HTTP请求的来源地址。通过Referer Check,可以检查是否来自合法的"源".
实践
以上例来说,如果是从www.c.com发起的删帖请求,那么Referer值是http://www.c.com, 删帖请求应该被允许;而如果是从CSRF攻击者构造的页面www.a.com发起删帖请求, 那么Referer值是http://www.a.com, 删帖请求应该被阻止。故只需要对每一个删帖请求验证其Referer即可防止CSRF攻击。
服务端验证Referer的代码:
const app = new Koa();
const router = new Router();
router.get('/', async ctx => {
if (ctx.headers.referer !== 'http://www.c.com:8002/') {
ctx.body = 'csrf攻击'
}
});
(3)请求地址添加token验证
可以在 HTTP 请求中以参数的形式加入一个随机产生的 token,并在服务器端建立一个拦截器来验证这个 token,如果请求中没有 token 或者 token 内容不正确,则认为可能是 CSRF 攻击而拒绝该请求。
CSRF 攻击之所以能够成功,是因为攻击者可以完全伪造用户的请求,该请求中所有的用户验证信息都是存在于 Cookie 中,因此攻击者可以在不知道这些验证信息的情况下直接利用用户自己的 Cookie 来通过安全验证。要抵御 CSRF,关键在于在请求中放入攻击者所不能伪造的信息,并且该信息不存在于 Cookie 之中。为请求添加token验证可以很好地做到这一点。
(4) SameSite Cookie
给Cookie设置SameSite属性。这样服务器可以要求某个cookie在跨站请求时不会被发送,从而可以阻止跨站请求伪造攻击(CSRF)。但目前SameSite Cookie还处于实验阶段,并不是所有浏览器都支持。
三、XSS与CSRF的对比总结
- XSS是利用用户对指定网站的信任
- CSRF是利用网站对用户的信任
参考资料
https://developer.mozilla.org/zh-CN/docs/Glossary/CSP
https://developer.mozilla.org/zh-CN/docs/Glossary/Cross-site_scripting
https://developer.mozilla.org/zh-CN/docs/Glossary/CSRF
https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Cookies
XSS与CSRF攻击的更多相关文章
- xss和csrf攻击
xss(cross site scripting)是一种最常用的网站攻击方式. 一.Html的实体编码 举个栗子:用户在评论区输入评论信息,然后再评论区显示.大概是这个样子: <span> ...
- XSS 和 CSRF 攻击
web安全中有很多种攻击手段,除了SQL注入外,比较常见的还有 XSS 和 CSRF等 一.XSS(Cross Site Scripting)跨站脚本 XSS其实就是Html的注入问题,攻击者的输入没 ...
- 前端安全之XSS和csrf攻击
1.Csrf攻击概念: csrf攻击(Cross-site request forgery):跨站请求伪造; 2.Csrf攻击原理: 用户是网站A的注册用户,且登录进去,于是网站A就给用户下发cook ...
- xss 和 csrf攻击详解
在那个年代,大家一般用拼接字符串的方式来构造动态 SQL 语句创建应用,于是 SQL 注入成了很流行的攻击方式.在这个年代, 参数化查询 已经成了普遍用法,我们已经离 SQL 注入很远了.但是,历史同 ...
- XSS攻击 && CSRF攻击 基础理解
一个网站,不管多么的帅气,多么的风骚,如果你不安全,那始终都是一个弟弟啊~ 今天又看了下XSS和CSRF攻击的文章,我也想发点什么普及下大家的安全意识,毕竟作为一名拥有伟大梦想的程序员,基本的安全意识 ...
- 关于XSS(跨站脚本攻击)和CSRF(跨站请求伪造)
我们常说的网络安全其实应该包括以下三方面的安全: 1.机密性,比如用户的隐私被窃取,帐号被盗,常见的方式是木马. 2.完整性,比如数据的完整,举个例子,康熙传位十四子,被当时四阿哥篡改遗诏:传位于四子 ...
- XSS攻击&SQL注入攻击&CSRF攻击?
- XSS(Cross Site Script,跨站脚本攻击)是向网页中注入恶意脚本在用户浏览网页时在用户浏览器中执行恶意脚本的攻击方式.跨站脚本攻击分有两种形式:反射型攻击(诱使用户点击一个嵌入恶意 ...
- yii框架各种防止sql注入,xss攻击,csrf攻击
PHP中常用到的方法有: /* 防sql注入,xss攻击 (1)*/ function actionClean($str) { $str=trim($str); ...
- XSS与CSRF两种跨站攻击比较
XSS:跨站脚本(Cross-site scripting) CSRF:跨站请求伪造(Cross-site request forgery) 在那个年代,大家一般用拼接字符串的方式来构造动态SQL 语 ...
随机推荐
- Qt浅谈之二十六图片滑动效果
一.简介 博客中发现有作者写的仿360的代码,觉得其中图片滑动的效果很有意思,特提取其中的代码.并加上类似mac的画面移动的动画效果. 二.详解 1.代码一:界面滑动(QWidget) (1)slid ...
- .babelrc参数小解
.babelrc是用来设置转码规则和插件的,这种文件在window上无法直接创建,也无法在HBuilder中创建,甚至无法查看,但可以在sublime text中创建.查看并编辑. 当我们使用es6语 ...
- 百度竞价推广URL通配符使用说明
{keywordid} 被替换为触发该创意的关键词ID(全局唯一ID,不是字面ID),当没有对应的keywordid时,替换为0. {creative} 被替换为所点击的创意ID(全局唯一ID). 2 ...
- json数据与Gson工具类的使用
JS中使用JSON JSON对象 --> JSON字符串:JSON.stringify(对象) JSON字符串 --> JSON对象:JSON.parse(JSON字符串) <scr ...
- vijos 1057 盖房子 dp 最大子正方形
P1057盖房子 未递交 标签:[显示标签] 描述 永恒の灵魂最近得到了面积为n*m的一大块土地(高兴ING^_^),他想在这块土地上建造一所房子,这个房子必须是正方形的. 但是,这块土地并非十全十美 ...
- flsk-SQLALchemy
SQLALchemy 一.介绍 SQLALchemy是一个基于Python实现的ORM框架.该框架是建立在DB API之上,使用关系对象映射进行数据库操作 简言之便就是:将类和对象转换 ...
- js装饰者模式
装饰者模式是为已有的功能动态地添加更多功能的一种方式.当系统需要新功能的时候,是向旧的类中添加新的代码.这些新加的代码通常装饰了原有类的核心职责或主要行为,在主类中加入了新的字段,新的方法和新的逻辑, ...
- review38
Java程序中可以存在多个线程,但是在处理多线程问题时,必须注意这样一个问题:当两个或多个线程同时访问同一个变量,并且一些线程需要修改这个变量.这时可能发生混乱. 所谓线程同步就是若干个线程都需要一个 ...
- PHP 5.2、5.3、5.4、5.5、5.6 版本区别对比以及新功能详解
截至目前(2015.1), PHP 的最新稳定版本是 PHP5.5, 但有差不多一半的用户仍在使用已经不在维护 的 PHP5.2, 其余的一半用户在使用 PHP5.3 . 因为 PHP 那“集百家之 ...
- rehash过程
步骤 1) 首先创建一个比现有哈希表更大的新哈希表(expand)2) 然后将旧哈希表的所有元素都迁移到新哈希表去(rehash) dictAdd 对字典添加元素的时候, _dictExpandI ...