这是我参与更文挑战的第29天,活动详情查看: 更文挑战
什么是XSS?
中文名称跨站点脚本攻击,英文全称 Cross Site Script,本来缩写是CSS,但是为了和层叠样式css有所区别,所以改成了XSS。XSS攻击,通常指黑客通过”HTML注入”篡改了网页,插入了任意脚本,从而在用户浏览网页时,控制用户浏览器的一种攻击。在一开始,这种攻击的演示案例是跨域的,所以叫“跨站脚本”,但是由于js的强大功能以及网站应用的复杂化,是否跨域已经不在重要,但是由于历史原因,XSS这个名字却一直保留下来。
XSS长期以来被列为客户端Web安全中的头号大敌。因为XSS破坏力强大,且产生的场景复杂,难以一次性解决。下面举个栗子说明下什么才是XSS。
假设一个页面把用户输入的参数直接输出到页面上,正常情况下,get请求,用户提交的数据会展示到链接上,但是如果提交的是html代码(XXX.php?params=),并且从服务器不做处理正常返回参数,会发现alert在当前页面执行了,会查看到源代码sparams已经在html代码当中,这肯定不是开发者所希望看到的,上面这个栗子,就是XSS的第一种类型,反射型XSS。
XSS根据效果可以分成不同类型:
1. 反射型XSS
这种只是简单的把用户输入的数据反射给浏览器。也就是说黑客往往需要诱导用户点击一个链接,才能成功,也叫做非持久型XSS。
2. 存储型XSS
存储型SXX会把用户输入的数据“存储”在服务端。这种XSS具有很强的稳定性。比较常见的一个场景:黑客写下一片包含恶意的js代码的博客文章,文章发表后,所有访问该博文的用户,都会在他们的浏览器中执行这段恶意的js代码,黑客把恶意脚本保存到服务端,所以这种XSS攻击就叫做存储型XSS。也叫持久型XSS。
3. DOM Based XSS
实际上,这种类型的XSS并非按照“数据是否存在服务端”来划分,这种从效果上来说也是反射型XSS,单独划分出来,是因为形成原因比较特别,发现它的安全专家专门提出了这种类型的XSS。也就是通过修改页面DOM节点形成的XSS,所以叫做DOM Based XSS。
XSS Payload
XSS攻击成功后,攻击者能否对用户当前浏览的页面植入恶意脚本,通过恶意脚本,控制用户的浏览器,这些用以完成各种具体功能的恶意脚本,被叫做 ‘XSS Payload’。实际上就是js脚本,所以任何js脚本能实现的功能,XSS Payload 都能做到。一个最常见的XSS payload,就是通过读取浏览器的Cookie对象,从而发起Cookie劫持攻击。Cookie中一般加密保存了当前用户的登陆凭证。Cookie如果修饰,往往意味着用户的登陆凭证丢失。换句话说,攻击者可以不通过密码,而直接登录进用户的账户。
Cookie一般都是用户登陆的凭证,可浏览器发起的所有请求都会自动带上Cookie,如果Cookie没有绑定客户端信息,当攻击者窃取了Cookie后,就可以不用密码登录进用户的账户。Cookie的HttpOnly标识可以防止“cookie劫持”。
cookie劫持并非所有的时候都有效,有的网站可能在Set-cookie时给关键的cookie植入HttpOnly标识,有的网站则可能会把Cookie与客户端IP绑定,从而使得XSS窃取的Cookie毫无意义。
这里举个例子,如果说我们想通过XSS删除某个文章,怎么做?
对于攻击来说,只需要知道文章的id就能够通过某个请求删除这篇文章了,攻击者可以通过插入一张图片来发起一个get请求,攻击者只需要让文章的作者 执行这段图片代码,就会把文章删除。当然也可以通过post请求方式来执行类似的操作。
所以XSS攻击后,攻击者除了可以实施Cookie劫持外,还能够通过模拟Get,Post请求操作用户的浏览器。这在某些隔离环境中会非常有用,比如Cookie劫持失效时,或者目标用户的网络不能访问互联网等情况。
XSS 钓鱼
XSS并非万能的,之前所讲的都是通过js脚本进行的,缺少了用户交互过程。比如现在有个用户修改密码的功能,需要修改老密码,这样是不是就能限制住XSS攻击了?显然是不行的,对于验证码而言,XSS Payload可以通过读取页面内容,将验证码的图片URL发送到远程服务器上实施–攻击者可以在远程的XSS后台接受当前验证码,并将验证码的值返回给当前的XSS Payload,从而绕过验证码。修改密码问题稍微复杂了点,为了窃取密码,攻击者可以将XSS与“钓鱼”相结合。
实现思路很简单:利用js在当前页面上做出一个伪造的登录框,当用户登陆框中输入用户名密码后,其密码将发送到黑客服务器上。
XSS的构造技巧
- 利用字符编码,比如我们常见用户名、密码字符校验;
- 绕过长度限制,比如密码长度;
- 使用标签,它的作用是定义页面上所有使用的“相对路径”标签的hosting地址;
- window.name的使用,这个对象是个比较奇怪的东西,对当前窗口的window.name对象赋值,没有特殊字符的限制。因为window对象是浏览器的窗体,而并非document对象,因此很多时候window对象不受同源策略的显示,攻击者利用这个对象可以实现跨域、跨页面传递数据。
XSS防御
1. HttpOnly
httponly最早是由微软提出,并在IE6上实现,已经成为了一个标准,浏览器将禁止页面js访问还有Httponly属性的Cookie。但是并非玩万能的,添加HttpOnly不等于解决了XSS问题,XSS攻击带来的不光是Cookie劫持问题,还有窃取用户信息、模拟用户身份执行操作等诸多严重后果。攻击者利用Ajax构造HTTP请求,以用户身份完成的操作,就是在不知道用户Cookie的情况下进行的。使用Httponly有主语环节XSS攻击,但仍然需要其他能够解决XSS漏洞的方案。
2. 输入检查
输入检查逻辑,必须放在服务器端代码中实现,如果只是在客户端使用js进行输入检查,是很容易被攻击者绕过的。客户端js的输入检查,可以阻挡大部分误操作的正常用户,从而节约服务器资源。
3. 输出检查
一般来说,除了富文本的输出外,在变量输出到HTML页面时,可以使用编码或转义的方式来预防XSS攻击。处理富文本应该使用白名单,避免使用黑名单,比如,只允许a,img,div等比较安全的标签存在,处理css时尽可能地禁止用户自定义CSS和style。
总结
一般来说,存储型XSS的风险会大于反射型XSS。因为存储型XSS会保存在服务器上,有可能会跨也可面存在。它不改变页面URL的原有结构,因此有时候还能逃过一些IDS的检测。
从攻击过程来说,反射型XSS,一般要求攻击者诱使用户点击包含一个XSS代码的url链接;而非存储型XSS,则只需要让用户查看一个正常的url。
从风险角度看,用户自己有互动的页面,是可能发起XSS蠕虫攻击的地方,而根据不同页面的pageView的高低,也可以分析出那些页面受XSS攻击后的影响会更大。
各位大佬,又献丑了!!