跨站脚本攻击(Cross-site scripting,通常简称为XSS)发生在客户端,可被用于进行窃取隐私、钓鱼欺骗、偷取密码、传播恶意代码等攻击行为。
恶意的攻击者将对客户端有危害的代码放到服务器上作为一个网页内容, 使得其他网站用户在观看此网页时,这些代码注入到了用户的浏览器中执行,使用户受到攻击。
一般而言,利用跨站脚本攻击,攻击者可窃会话COOKIE从而窃取网站用户的隐私,包括密码。
XSS攻击使用到的技术主要为HTML和Javascript,也包括VBScript和ActionScript等。XSS攻击对WEB服务器虽无直接危害,但是它借助网站进行传播,使网站的使用用户受到攻击,导致网站用户帐号被窃取,从而对网站也产生了较严重的危害。
跨站脚本漏洞原理
攻击者通过网站的输入点嵌入非法的HTML标签与JavaScript脚本并执行以达到在客户端攻击的目的。 攻击者注入的标签与脚本最终都要在客户端执行,攻击的过程实际上都 在客户端的浏览器上发生的。 能在客户端进行跨站的不仅仅是HTML标签与JavaScript脚本,还包含一些其它的客户端应用,比如Flash里的ActionScript脚本也能辅助发起XSS攻击
跨站脚本漏洞发生在哪里
Cross-Site Scripting (XSS) 漏洞在以下情况下发生:
- 数据通过一个不可信赖的数据源进入 Web 应用程序。 对于 Reflected XSS,不可信赖的源通常为 Web 请求,而对于 Persisted(也称为 Stored)XSS,该源通常为数据库或其他后端数据存储
- 在未检验包含数据的动态内容是否存在恶意代码的情况下,便将其传送给了 Web 用户
跨站脚本漏洞实例
例 1
类型1:CSS跨站
[HTML_REMOVED]//style属性值用户可控或者用户可以直接编辑模板
恶意用户可以提交“xss:expr/*XSS*/ession(alert('XSS'))”作为STYLE标签的属性值,或者在编辑模板的地方,
恶意用户可以将JS代码写入CSS文件,导致跨站漏洞
类型2:HTML标签跨站
[HTML_REMOVED]">
由于程序没有对标签进行转义,恶意用户可以提交
http://www.test.com/search.php? evil_content =">[HTML_REMOVED]alert(/XSS/)[HTML_REMOVED]<
执行任意JS代码,导致跨站漏洞
类型3:Javascript跨站
[HTML_REMOVED]
var UID ='0';
var isLogin =false;
var KEY ='';//KEY变量用户可控
var FROMTAG =1;
[HTML_REMOVED]
用户可以提交:
http://www.test.com/news/tag.jsp?key=%27;alert%281%29;//
变量key包含在JavaScript代码段中。原始代码被修改为:
[HTML_REMOVED]
var UID ='0';
var isLogin =false;
var KEY ='';alert(1);//恶意用户修改了页面输出代码';
例 2
下面的 ASP.NET 代码片段会在一个 HTTP 请求中读取一个雇员 ID,并显示给用户。
protectedSystem.Web.UI.WebControls.TextBoxLogin;
protectedSystem.Web.UI.WebControls.LabelEmployeeID;
...
EmployeeID.Text=Login.Text;
如果 Login 只包含标准的字母或数字文本,这个例子中的代码就能正确运行。 如果 Login 有一个包含元字符或源代码的值,那么 Web 浏览器就会像显示 HTTP 响应那样执行代码。
起初,这个例子似乎是不会轻易遭受攻击的。 毕竟,有谁会输入导致恶意代码的 URL,并且还在自己的电脑上运行呢? 真正的危险在于,攻击者会创建恶意的 URL,然后使用电子邮件或者其他诡计诱使受害者点击这个链接。 当受害者点击这个链接时,就会不知不觉地通过易受攻击的 Web 应用程序,使自己的电脑蒙受恶意内容带来的风险。 这种对易受攻击的 Web 应用程序进行盗取的机制通常被称为反射式 XSS。
例 3
下面的 ASP.NET 代码片段会根据一个给定的雇员 ID 来查询数据库,并显示出该雇员的相应姓名。
protectedSystem.Web.UI.WebControls.LabelEmployeeName;
...
string query ="select * from emp where id="+ eid;
sda =newSqlDataAdapter(query, conn);
sda.Fill(dt);
string name = dt.Rows[0]["Name"];
...
EmployeeName.Text= name;
如同例 2,如果对 name 的值处理得当,该代码就能正常地执行各种功能;如若处理不当,就会对代码的盗取行为无能为力。 同样,这段代码暴露出的危险较小,因为 name 的值是从数据库中读取的,而且显然这些内容是由应用程序管理的。 然而,如果 name 的值是由用户提供的数据产生,数据库就会成为恶意内容沟通的通道。
如果不对储存于数据库中的所有数据进行恰当的输入确认,那么攻击者便能在用户的 Web 浏览器中执行恶意命令。
这种类型的 Persistent(称作 Stored XSS)盗取极其阴险狡猾,由于数据存储的间接性,使得辨别威胁的难度增大,而且还提高了一个攻击影响多个用户的可能性。 XSS 盗取会从访问提供留言簿 (guestbook) 的网站开始。
攻击者会在这些留言簿的条目中嵌入 JavaScript,接下来所有访问该留言簿的用户都会执行这些恶意代码
跨站脚本漏洞危害
- 钓鱼欺骗:最典型的就是利用目标网站的反射型跨站脚本漏洞将目标网站重定向到钓鱼网站,或者注入钓鱼JavaScript以监控目标网站的表单输入,甚至发起基于DHTML更高级的钓鱼攻击方式。
- 网站挂马:跨站时利用IFrame嵌入隐藏的恶意网站或者将被攻击者定向到恶意网站上,或者弹出恶意网站窗口等方式都可以进行挂马攻击。
- 身份盗用:Cookie是用户对于特定网站的身份验证标志,XSS可以盗取到用户的Cookie,从而利用该Cookie盗取用户对该网站的操作权限。如果一个网站管理员用户Cookie被窃取,将会对网站引发巨大的危害。
- 盗取网站用户信息:当能够窃取到用户Cookie从而获取到用户身份使,攻击者可以获取到用户对网站的操作权限,从而查看用户隐私信息。
- 垃圾信息发送:比如在SNS社区中,利用XSS漏洞借用被攻击者的身份发送大量的垃圾信息给特定的目标群。
- 劫持用户Web行为:一些高级的XSS攻击甚至可以劫持用户的Web行为,监视用户的浏览历史,发送与接收的数据等等。
- XSS蠕虫:XSS 蠕虫可以用来打广告、刷流量、挂马、恶作剧、破坏网上数据、实施DDoS攻击等。
跨站脚本漏洞解决方案
- 检查变量是否正确初始化并明确变量类型
- 不仅要验证数据的类型,还要验证其格式、长度、范围和内容。
- 不要仅仅在客户端对数据做HTML标签转义以及过滤单引号,双引号等危险字符,关键的过滤步骤也应该在服务端进行。
- 对输出到页面的数据也要做安全检查,数据库里的值有可能会在一个大网站的多处都有输出,即使在输入做了编码等操作,在各处的输出点时也要进行安全检查。
- 在发布应用程序之前测试所有已知的威胁。