跨站脚本攻击(XSS)详解

您所在的位置:网站首页 跨站脚本三种类型 跨站脚本攻击(XSS)详解

跨站脚本攻击(XSS)详解

2024-04-02 08:27| 来源: 网络整理| 查看: 265

XSS简介

XSS(Cross Site Script)攻击,通常指黑客通过"HTML注入"篡改了网页,插入了恶意的脚本,从而在用户浏览网页时,控制用户浏览器的一种攻击。

一开始,这种攻击的演示案例是跨域的,所以叫做"跨站脚本"。现在是否跨域已经不再重要,但是名字一直沿用下来。

XSS长期以来被列为客户端Web安全中的头号大敌。因为XSS破坏力强大,且产生的场景复杂,难以一次性解决。

下面举个XSS的例子

假如用户把页面输入的参数直接输出到页面上:

如果用户提交了一段HTML代码

http://www.test.com/test.php?param=alert(/xss/)

alert(/xss/)就会在页面中执行,弹出框显示/xss/。

这个例子就是XSS的一种:反射型XSS。

根据效果的不同,XSS可以分为三类

反射型XSS

反射型XSS只是简单地把用户输入的数据”反射“给浏览器。也就是说黑客往往需要诱使用户”点击“一个恶意链接,才能攻击成功。反射型XSS也叫”非持久型XSS”。

存储型XSS

存储型XSS会把用户输入的数据“存储”在服务器端。这种XSS具有很强的稳定性。

比较常见的,黑客写下一篇包含恶意JavaScript代码的博客文章,文章发表后,所有访问该博客文章的用户,都会在他们的浏览器中执行这段恶意的JavaScript代码。黑客把恶意脚本保存在了服务端,这种XSS攻击就叫做“存储型XSS”。存储型XSS也叫做“持久型XSS”。

DOM Based XSS

DOM Based XSS从效果上来说也是反射型XSS,单独划分出来是因为它的形成原因比较特殊,发现它的安全专家提出了这种类型的XSS。出于历史原因把它单独作为一个分类了。

通过修改页面的DOM节点形成的XSS,称之为DOM Based XSS。

下面举个例子

Document function test() { var str = document.getElementById('text').value; document.getElementById('t').innerHTML = "testLink"; }

输入框构造如下数据:

' onclick=alert(/xss/) //

它先用一个单引号闭合掉href的第一个单引号,然后插入一个onclick事件,最后再用注释符“//”注释掉第二个引号。 输入后,页面代码变成了:

' / -> /

Javascript的编码方式可以使用JavaScriptEncode

它使用""对特殊字符进行转义。在对抗XSS时还要求输出的变量必须在引号内部,以避免造成安全问题。

比较两种写法

var x = escapeJavaScript($evil); var y = '"'+escapeJavaScript($evil)+'"';

如果只是转义了几个危险字符,如’、”、、\、&、#等,那么可能会输出

var x = 1;alert(2); var y = "1;alert(2);";

攻击者即使想要逃脱出引号的范围,也会遇到困难。

var y = "\";alert(1);\/\/";

但是开发者没有这个习惯怎么办?

那就只能使用一个更加严格的JavaScriptEncode函数来保证安全了——除了数字、字母外的所有字符,都使用十六进制“\xHH”的方式进行编码

var x = 1;alert(2);

变成了

var x = 1\x3balert\x282\x29;

此外还有其他编码函数,如XMLEncode、JSONEncode等

只需要一种编码吗

XSS主要发生在MVC架构中的View层。大部分的XSS漏洞可以在模板系统中解决。

如Python的开发框架Django自带的模板系统"Django Templates",可以使用escape进行HtmlEncode,并且在Django1.0中得到了加强——默认所有的变量都会被escape。

但这样还是不能完全避免XSS问题,需要“在正确的地方使用正确的编码方式”

例如

test

如果用户输入

$var = htmlencode("');alert('2");

对于浏览去器来说,htmlparser会优先于JavaScript Parser执行

经过解析后,结果为

test

xss被注入。

xss发出的原因是,没有分清楚输出变量的语境,并非在模板引擎中使用了auto-escape就万事大吉了。

正确防御XSS

XSS的本质是一种“HTML注入”,想要根治XSS问题,可以列出所有XSS可能发生的场景,再一一解决。

在HTML标签中输出 $var $var

防御的方法是对变量使用HtmlEncode

在HTML属性中输出

防御的方法是对变量也是使用HtmlEncode

在script标签中输出

首先应该确保输出的变量在引号中:

var x = "$var";

防御时使用JavaScriptEncode

在事件中输出 test

防御方式和在script标签中输出类似

在CSS中输出

比如@import、url等直接加载XSS、expression(alert('xss'))等

一方面需尽可能避免用户可控制的变量在css中输出,如果必须有这样的需求,那么使用encodeForCSS

在地址栏输出

一般来说使用URLEncode即可,但是如果整个URL被用户完全控制,Protocal和Host是不能使用URLEncode的,否则会改变URL的语义。

[Protocal][Host][Path][Search][Hash]

例如www.evil.com/a/b/c/test?…

对于如下的输出方式:

test

攻击者可能会构造伪协议实施攻击

test

此外,“vbscript”、“dataURI”等伪协议也可以导致脚本执行。

一般来说,对于用户控制整个URL,应该先检查是否以“http”开头,如果不是则自动添加,以保证不会出现伪协议类的XSS攻击,然后再对变量进行URLEncode。

处理富文本

网站允许用户提交一些自定义的HTML代码,称之为富文本。

在处理富文本时,还是要回到“输入检查”的思路上来。“输入检查”的主要问题是检查时还不知道变量的输出语境。但富文本数据,其语义是完整的HTML,在输出时也不会拼凑到某个标签的属性中。因此,可以特殊对待。

通过htmlparser可以解析出HTML代码的标签、标签属性和事件。

在过滤富文本时,事件应该被严格禁止、而一些危险的标签,比如iframe、script、base、form等也是应该严格禁止的。在标签选择上,应该使用白名单。比如,只允许a、img、div等比较安全的标签。“白名单”同样应该用于属性和事件的选择。

在富文本过滤中,处理CSS也是一件麻烦的事,因此应该禁止用户自定义CSS和style。如果不能禁止,那就需要一个CSS Parser对样式进行智能分析,检查其中是否包含危险代码。

防御DOM Based XSS

DOM Based XSS前文提到的几种防御方法都不太适用。

DOM Based XSS是从JavaScript中输出数据到HTML页面里,而前文都是针对从服务器应用直接输出到HTML页面的XSS漏洞。

服务器执行了javascriptEscape,输出的数据又重新渲染到了页面中,对变量进行了解码,仍然会产生XSS。

正确的防御方法是,在$var输出到script时,执行一次javaScriptEncode,其次在输出到HTML页面时,如果输出到事件或者脚本,则要再做一次javaScriptEncode;如果输出到HTML内容或者属性,则再做一次HtmlEncode。

触发DOM Based XSS的地方有很多,以下几个地方是JavaScript输出到HTML页面的必经之路。

document.write()

document.writeln()

xxx.innerHTML=

xxx.outerHTML=

innerHTML.replace

document.attachEvent()

window.attachEvent()

document.location.replace()

document.location.assign()

...

需要重点关注这几个地方的参数是否可以被用户控制

除了服务器端直接输出变量到JavaScript外,还有以下几个地方可能成为DOM Based XSS的输出点,也需要重点关注。

inputs框

window.location(href、hash等)

window.name

document.referrer

document.cookie

localstorage

XMLHttpRequest返回的数据

...

换个角度看XSS的风险

前面都是从漏洞的形成原理上看的,如果从业务风险角度看则有不同的观点

一般来说,存储型XSSS的风险高于反射型。因为它保存在服务器上,有可能会跨页面存在。它不会改变页面URL的原有结构,因此有时候还能逃过一些IDS的检测。

从攻击过程来说,反射型XSS,一般要求攻击者诱使用户点击一个包含XSS代码的URL链接;而存储型XSS,则只需要让用户查看一个正常的URL链接。

从风险角度看,用户之间有互动的页面,是可能发起XSS Worm攻击的地方。而根据不同页面的PageView高低,也可以分析出哪些页面受XSS攻击后的影响更大。

在修补漏洞时遇到的最大挑战之一是漏洞数量太多,开发者不太来得及立刻修复所有漏洞。从业务风险角度来重新定位每个XSS漏洞,就具有了重要意义。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3