阅读 322

web攻防勇者成名录-XSS&CSRF

前言

一切的起因都源于一次他人的试探,在一千二百四十四天前,我用Angular1.x写了一个“树洞”,发布在公众号上。一段时间后,意想不到的是我与一个奇怪评论不期而遇了,没错就是它<sctipt>sendTokenToServer()<script>。在之后一分钟的时间里,默然发觉,web安全威胁是离我们这么的近。如果不是用了angular框架,如果angular没有做相关的防范,后果是未知的,不过我知道的是,这便是后来的故事的开始,无论如何都值得拥有。

知己知彼,先来看看危害性最强的XSS攻击

XSS(跨域脚本攻击)

攻击描述

当访问有XSS漏洞的页面时,能够使攻击代码运行在他人的浏览器中。这就意味着网站前端的掌控权已经在他人手中了,这样的结果就可能就会导致用户身份认证被盗取,用户行为被记录等等情况的出现。XSS攻击看似复杂,但其实原理很简单,一般来自于对输入的拼接。XSS又分为好几种类型。

反射型XSS攻击

攻击代码会植入到url相关的参数中,一般经过伪装与混淆之后,用户很容易中招。

发动条件

  • 页面有与用户相关的交互(例如搜索框)
  • 前后端都没对输入内容过滤或被绕过
  • Js从url位置获取相关参数,并且页面中有相关回显
  • 用户主动点击带有攻击代码的链接

攻击例子

【亲朋好友帮忙砍一刀,点击获得红包】
http://localhost:8080/?name=%3Cimg%20src=1%20onerror=alert(document.cookie)%3E%3C/div%3E 
【发送链接砍一刀即有机会获得笔记本电脑,百分百中奖快来参与!】
复制代码

点击链接之后token就被获取了,omg!

image

有漏洞的代码【示例】

function getParams(key) {
    const reg = new RegExp(`(&|^)${key}=([^&]*)($|&)`);
    const res = window.location.search.substr(1).match(reg);
    if (res != null) {
        return unescape(res[2]);
    }
    return null;
}
document.getElementById('xss').innerHtml=getParams('name')
复制代码

那我不点击可疑链接不就行咯?很可惜,那也是不行的。

储存型XSS攻击

目的是将攻击代码持久化到服务器,这样用户即使不点击可疑链接,只访问相关页面就可以被攻击,更严重的是,储存型的XSS漏洞可被编写成蠕虫脚本,具备社交传播属性。

必要攻击条件

  • 页面有与用户相关交互(富文本,评论框),或一切能持久化的行为
  • 页面有对相关数据进行回显
  • 前后端都没对输入内容过滤或被绕过
  • 用户访问了储存攻击代码的页面链接

攻击例子

http://localhost:8080/article?id=58
复制代码

点击链接之后,token又又被获取了,org。

image

这个链接中的评论功能有一个储存型XSS漏洞,用户一旦点击进入了这个页面,那么存储在评论区中的攻击代码就会执行。只要将攻击载荷换成可发表文章的脚本,那么这段攻击代码就具备传播性了。

有漏洞的代码【示例】

async getCommentById=(id)=>{
    ...
}
getCommentById(123).then(res=>{
    document.getElemtById('comment').innerHtml=res
})
复制代码

Dom型XSS攻击

利用交互回显,破坏正常dom结构,得到开发者预期之外的结果。跟sql注入类似,都是拼接用户输入惹的锅。

必要攻击条件

  • 页面有与用户相关交互(利用dom拼接破坏原本的dom结构)
  • 前后端都没对输入内容过滤或被绕过
  • 用户主动点击带有攻击代码的链接or主动点击储存了攻击代码的页面链接

攻击例子&有漏洞的代码【示例】

如果有漏洞代码存在,那么又可通过某种方式插入以下例子的话,就构成了DOM型XSS攻击了
payload="><sctipt>/*恶意脚本*/getCookie();sendCookie()</sctipt"
...
有漏洞的代码
document.getElementById('demo').innerHtml='<option data='+ getInput() +'>2333hhhh</option>'
复制代码

防御手段

http only

通过设置cookie的httpOnly字段,防止通过脚本获取cookie中的信息。

image

严格控制输入输出

关键字过滤(好消息是像现在流行的前端框架都帮开发者做了这一层过滤)

七个控制输入输出原则

接下来继续来挑战另一种漏洞

CSRF(跨域请求伪造)

攻击描述

跨域请求伪造的原理也很简单,由于网站在发送请求时,会自动地将储存在本地的cookie带上,发送给后台验证。利用这个特性,就可以在不知道用户身份凭证的情况下,模拟用户的正常请求。而且在后台的角度来看,这一切都是正常的,一切都是用户自己在操作。

攻击例子

这是brandf网站正常的发表文章接口,之前特意设置的一个CSRF漏洞,看看就好。
http://www.brandf.cn:8010/articles/csrfdemo

通过iframe伪造一下这个请求,再进行一些小小的伪装。

【亲朋好友帮忙砍一刀,点击获得红包】 http://localhost:8080 
【发送链接砍一刀即有机会获得笔记本电脑,百分百中奖快来参与!】
复制代码

image

用户在网站http://www.brandf.cn登录之后,又点击进入隐藏了攻击代码的网站(http://localhost:8080)。这时,就会在用户不知情的情况下,在用户的账号里发表一篇文章。细思恐极,如果这是一个更加危险的操作呢?比如转账等等。

如果存在漏洞的地方拥有社交属性,例如一个发送消息的接口是可以伪造的,那么这个CSRF漏洞就拥有了传播性,也就是CSRF蠕虫了。

必要攻击条件

  • 用户在已登录的状态下,点击了恶意链接
  • 网站的用户凭证通过cookie传递

防御手段

后台校验referer字段

但请求头中的referer字段能被伪造,存在被绕过的风险。既然CSRF利用了浏览器请求默认带上cookie的机制,那么能不能从源头去杜绝呢?

JWT

JWT即web身份令牌技术,最重要的一点是它将用户凭证放在请求body中,杜绝了浏览器默认行为自动带上cookie所带来的风险。

image

最后

XSS,CSRF这两种可以讲是前端最常见也是危害最大的漏洞,当然有很多时候漏洞是由人为主观造成的,例如弱密码等等。同时在过去的十分钟时间里,很感谢你阅读了这篇文章,如果能对你有帮助,不妨点个赞哈哈,以上的所有例子和方法都是为了大家能更好地去认识到这些漏洞的危害,更好的去做好防范,同时也提高安全意识。例子均在本地实现,有兴趣的朋友可有在本地写写,但别去其他网站乱试。推荐几个web漏洞练习平台,Pikachu漏洞平台DVWA

CSP浏览器安全策略

CSP(Content-Security-Policy)为什么要最后单独拿出来讲呢,因为CSP需要后端的配合,在响应头中加入相关字段合规则。CSP相当于在浏览器中设置一个资源白名单,在白名单中的资源才能加载,能很大程度上提升网站的安全性。这里就不展开了,之后有会一篇详细的使用配置介绍嘿嘿。

关注下面的标签,发现更多相似文章
评论