一 xss的攻击方式
1,反射型
发出请求时,xss代码出现在URL中,作为输入提交到服务器端,服务器端解析后响应,xss代码随响应内容一起传回给浏览器,最后浏览器解析执行xss代码。这个过程像一次反射,故叫做反射型xss。
2,存储型
存储型xss和反射型xss的区别仅在于,提交的代码会存储在服务器端,下次请求目标页面时不用再提交xss代码。
破坏页面结构,插入恶意内容
盗用cookie
实现ddos攻击效果:利用合理的客户端请求占用资源,从而使用户无法正常访问。
实现server limit 攻击效果:当http request header过长,则会产生400,导致一些用户久无法正常访问。
二,构建node应用,演示反射型xss攻击
1 创建express应用:
mkdir mydir
cd mydir/
mkdir xss
cd xss
express -e ./ //-e
npm -install
在index.js中
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/', function(req, res, next) {
res.set('X-XSS-Protection',0);//关闭xss拦截
res.render('index', { title: 'Express',xss:req.query.xss });//解析xss,query用来获取search字段
});
module.exports = router;
在index.ejs中
!DOCTYPE html>
<html>
<head>
<title><%= title %></title>
<link rel='stylesheet' href='/stylesheets/style.css' />
</head>
<body>
<h1><%= title %></h1>
<p>Welcome to <%= title %></p>
<div class="">
<%- xss %>//加入该代码
</div>
</body>
</html>
反射型的xss攻击生效。
攻击脚本的类型
1,自动出发
2,引诱出发
3,嵌入广告
localhost:3000/?xss=< iframe%20src=“//baidu.com/t.html”/></iframe>
三,掌握xss的防御措施
1, 编码
避免对用户的操作保持原样,对用户输入的数据进行 html_entity编码。
2,过滤
解码时,把输入的不合法的东西进行过滤,如移除用户上传的dom属性 ,如onerror等,对于事件相关属性一般都过滤掉;移除用户上传的style节点(控制页面显示与否),script节点(可引入js,获得对页面的百分百权限),iframe节点(通过xss注入,引诱用户触发csrf攻击)
3,校正
避免破坏了正常的dom页面结构。如避免直接对html_entity解码,使用 dom parse 转换,校正不配对的dom标签。
四,实战
通过构建node服务和建立一个评论功能,实例演示xss的攻击预防。
在index.js中
ar express = require('express');
var router = express.Router();
var comments={};
function html_encode(str){
var s='';
if(str.length==0)return ""
s=str.replace(/&/g,">");
s=s.replace(/</g,"<");
s=s.replace(/>/g,">");
s=s.replace(/\s/g," ");
s=s.replace(/\'/g,"'");
s=s.replace(/\"/g,""");
s=s.replace(/\n/g,"<br>");
return s
};
/* GET home page. */
router.get('/', function(req, res, next) {
res.render('index');
});
router.get('/comment',function(req,res,next){
comments.v=html_encode(req.query.comment);
});
//获取评论的接口
router.get('/getComment',function(req,res,next){
res.json({
comment:comments.v
})
});
module.exports = router;
在index.ejs中
<body>
<h1><%= title %></h1>
<p>Welcome to <%= title %></p>
<textarea name="name" rows="8" cols="80" id="txt">
<p>sks<img src="null" alt="" onerror="alert(1)"></p>
</textarea>>
<button type="button" name="button" id="btn">评论</button>
<button type="button" name="button" id="get">获取评论</button>
<script type="text/javascript">
var btn=document.getElementById('btn');
var get=document.getElementById('get');
var txt=document.getElementById('txt');
btn.addEventListener('click',function(){
var xhr=new XMLHttpRequest();
var url='/comment?comment='+txt.value;
xhr.open('GET',url,true);
xhr.onreadystatechange=function(){
if(xhr.readyState==4){
if(xhr.status==200){
console.log(xhr);
}else{
console.log('error');
}
}
}
xhr.send();
});
get.addEventListener('click',function(){
var xhr=new XMLHttpRequest();
var url='/getComment';
xhr.open('GET',url,true);
xhr.onreadystatechange=function(){
if(xhr.readyState==4){
if(xhr.status==200){
// 解码的过程,配对校验的过程
var com=parse(JSON.parse(xhr.response).comment);
var txt=document.createElement('span');
txt.innerHTML=com;//文本不被转译
document.body.appendChild(txt);
}else{
console.log('error');
}
}
}
xhr.send();
});
</script>
<script type="text/javascript" src="encode.js"></script>
<script type="text/javascript" src="domParse.js"></script>
<script>
var parse=function(str){
var results=" ";
try{
// 反转译,解码的过程,之后再dom parse,拼接标签
HTMLParse(he.unescape(str,{strict:true}),{
start:function(tag,attrs,unary){
//过滤掉不安全的标签
if(tag=='script'||tag=='style'||tag=='link'||tag=='iframe'||tag=='frame') return;
results+='<'+tag;
// for (var i = 0; len=attrs,length;i<len;i++) {
// results+=" "+attrs[i].name+'="'+attrs[i].escaped+'"';
// }
results+=(unary?"/":"")+">"
},
end:function(tag){
results+="</"+tag+">"
},
chars:function(text){
results+=text;
},
comment:function(text){
}
});
return results
} catch(e){
}finally{
}
}
</script>