XSS报警机制(前端防火墙:第二篇)
XSS报警机制(前端防火墙:第二篇)
在第一章结尾的时候我就已经说了,这一章将会更详细的介绍前端防火墙的报警机制及代码。在一章出来后,有人会问为什么不直接防御,而是不防御报警呢。很简单,因为防御的话,攻击者会定位到那一段的JavaScript代码,从而下次攻击的时候绕过代码。如果不防御而报警的话,攻击者会降低警觉,不会在看JavaScript代码(至少我是这样)。回到正题,下面说的代码,是基于thinkphp框架和bootstrap3.3.5框架。如果你的网站没有使用thinkphp3.2.3框架的话,可以参照我的思路重新写一个。这里我强调一下“前端防御XSS是建立在后端忘记做过滤,没有做过滤,疏忽做过滤的基础上的...
0x01 前端要做的事
其实标题应该改成“XSS报警机制”的,因为在这一章里使用了大量的后端代码。但是第一章的标题都出来了,也没法改了。
前端要做的事情在第一章的时候就已经说了,代码如下:
现在我们就是针对第38行进行修改,改成我们后台接受的API URL。就像这样:
对,就这一行。没有其他代码。在实际的线上环境中,也只需要上面5行。可以直接copy到您的线上环境中,记得把倒数第二行的url改成自己的地址就行了。难道就那么简单?不,0x05节还有一部分前端代码。0x01~0x04主要是针对于平台。
0x02 数据库要做的事
一共两个表。fecm_user和fecm_bugdata。
fecm_user的字段信息如下:
name:管理员账户名
md5name:3次name值的md5
password:3次密码的md5
email:管理员邮箱
create_date:管理员创建时间
为了安全起见(其实就是懒)没有写添加管理员的,自行在数据库里添加
fecm_bugdata的字段信息如下:
url:漏洞的url地址
category:漏洞类型
cookies:攻击者的cookies
ua:攻击者的User-Agent
hxff_ip:攻击者的HTTP_X_FORWARDED_FOR
hci_ip:攻击者的HTTP_CLIENT_IP
ra_ip:攻击者的REMOTE_ADDR
time:攻击者攻击的时间
fixes:漏洞是否修复(0为未修复,1为已修复)
0x03 后端要做的事
因为后端代码太多,所以我就说一些核心的后端处理代码。
在0x01节里,有个核心的代码是new Image().src = 'http://fecm.cn/Api/addVul/';
接下来我们来说说这个Api的处理方式(ThinkPHP代码)
public function addVul(){
if(I('get.category','','int') == ""){
$this->ajaxReturn(array(
"typeMsg" => "error",
"msgText" => "漏洞类型错误",
));
}
switch (I('get.category','','int')) {
case '1':
$vul['category'] = "触发alret函数";
break;
case '2':
$vul['category'] = "发现不在白名单里的第三方JavaScript资源";
break;
default:
$this->ajaxReturn(array(
"typeMsg" => "error",
"msgText" => "漏洞类型错误",
));
break;
}
if($_SERVER['HTTP_X_FORWARDED_FOR'] === null){
$vul['hxff_ip'] = "攻击者没有通过代理服务器访问";
}else{
$vul['hxff_ip'] = I('server.HTTP_X_FORWARDED_FOR'); //获取攻击者的HTTP_X_FORWARDED_FOR
}
if($_SERVER['HTTP_CLIENT_IP'] === null){
$vul['hci_ip'] = "攻击者数据包头部没有HTTP_CLIENT_IP";
$vul['hci_ip'] = I('server.HTTP_CLIENT_IP');//获取攻击者的HTTP_CLIENT_IP
}
$vul['ra_ip'] = I('server.REMOTE_ADDR'); //获取攻击者的REMOTE_ADDR
$vulcookie = I('cookie.'); //获取攻击者的cookies
for($i = 0;$icount($vulcookie);$i++){
$vul['cookies'] .= array_keys($vulcookie)[$i].'='.$vulcookie[array_keys($vulcookie)[$i]].'; '; //拼接成方便查看的cookies格式
}
$vul['url'] = I('server.HTTP_REFERER'); //获取攻击者攻击成功的url
$vul['ua'] = I('server.HTTP_USER_AGENT'); //获取攻击者的User-Agent
$vul['time'] = date("Y-m-d"); //获取攻击者攻击的时间
$vul['fixes'] = 0; //默认为漏洞未修复
$bugData = M('bugdata'); //连接fecm_bugdata数据库
$bugData->data($vul)->add(); //添加到数据库中
}
因为这里是接受攻击信息,不能有管理员验证。
后台有一个数据库可视化的表格,这里我使用的Chart.js,下面是后端代码:
public function index(){
$reportForm = M('bugdata'); //连接fecm_bugdata数据库
$dateTimeLabels = [];
$dateTimeTotal = [];
for($i = 0;$i $i++){ //获取近7天的数据
$time = date("Y-m-d",strtotime(-$i." day"));
array_unshift($dateTimeLabels,$time);
$data['time'] = array('like','%'.$time.'%');
array_unshift($dateTimeTotal,$reportForm->where($data)->count());
}
$reportForm = json_encode(["Labels" => $dateTimeLabels,"Total" => $dateTimeTotal]); //转化成json格式
$this->assign('reportForm',$reportForm)->assign('total',total()); //交给前端模块
$this->display(); //前端页面生成
}
前端代码:
var lineChartData = {
labels :eval({$reportForm})['Labels'],
datasets : [
{
fillColor : "rgba(151,187,205,0.5)",
strokeColor : "rgba(151,187,205,1)",
pointColor : "rgba(151,187,205,1)",
pointStrokeColor : "#fff",
data : eval({$reportForm})['Total']
}
]
}
var myLine = new Chart(document.getElementById("Statistics").getContext("2d")).Line(lineChartData);
实际的效果图:
0x04 让我们实际测试一下
代码就用0x01节的代码。我们输入alert(1)。看一下:
我们再去平台看一下:
成功显示了。
0x05 检测第三方js资源是否为xss脚本
这一节需要用到之前长短短分享的代码:
for(var i=0,tags=document.querySelectorAll('iframe[src],frame[src],script[src],link[rel=stylesheet],object[data],embed[src]'),tag;tag=tags[i];i++){
var a = document.createElement('a');
a.href = tag.src||tag.href||tag.data;
上一页
console.warn(location.hostname+' 发现第三方资源['+tag.localName+']:'+a.href);
}
}
但是他这里只是在console里显示,没有进一步的操作,而且他这里同时检测了iframe、frame、script、link、object、embed标签,对我们来说只需要script标签就行了,于是我重写了这段代码,首先我们需要一个白名单列表,用于放置网站允许第三方加载的url地址:
var scriptList = [
location.hostname,
]
这里只是默认的只允许当前域名加载,打击爱可以根据自己的需要添加。
然后就是获取当前网页的所有script标签:
var webScript = document.querySelectorAll('script[src]');
在把当前的地址赋值var webHost = location.hostname;至于为什么不放在for循环里,因为根据js优化规则,for循环里避免多次一样的赋值。
接下来就是for循环里的代码了:
for(var i = 0;i
var a = document.createElement('a'); //建立一个新的a标签,方便取值
a.href = webScript[i].src; //把script里的src赋值给a标签里的href属性
if(a.hostname != webHost){ //对比,是否为第三方资源
for(var j = 0;j
if(a.hostname != scriptList[i]){ //判断当前的第三方资源是否在白名单里
new Image().src = 'http://fecm.cn/Api/addVul/category/2'; //发送给FECM
}
}
}
}
这里我做了一个测试,加载hi.baidu.com的资源:
刷新后,打开FECM平台,看一下:
0x06 结语
因为穷,没有服务器和域名,也没法添加邮件自动提醒功能了。感兴趣的可以自己添加,如果后来我有钱了,我买个服务器,会添加邮件自动提醒的,第一时间会在乌云社区里发布。本来打算采用ED的on事件拦截代码的,但是发现on事件在程序里也会大量使用,索性就没有添加,如果你有思路
下载地址:http://pan.baidu.com/s/1jGVP7Ps
使用时记得在Application\Home\Conf\config.php改下配置(我已经全部加了注释,即使不会thinkphp的也可以搭建)
个人代码写的没有多好,思路可能也比较烂。如果您有什么意见欢迎提出来,我会进一步修改的。
上一页
XSS报警机制(前端防火墙:第二篇)的更多相关文章
- XSS前端防火墙
前一段时间,在EtherDream大神的博客里看到关于XSS防火墙的一系列文章,觉得很有意思.刚好科创要做一个防火墙,就把XSS前端防火墙作为一个创新点,着手去实现了. 在实现过程中,由于各种原因,比 ...
- 前端第二篇---前端基础之CSS
前端第二篇---前端基础之CSS 目录 一.css介绍 二.css语法 三.css的几种引入方式 四.css选择器 五.css属性相关 六.盒子模型 拓展 一.css介绍 CSS(Cascading ...
- XSS 前端防火墙 —— 天衣无缝的防护
上一篇讲解了钩子程序的攻防实战,并实现了一套对框架页的监控方案,将防护作用到所有子页面. 到目前为止,我们防护的深度已经差不多,但广度还有所欠缺. 例如,我们的属性钩子只考虑了 setAttribut ...
- 前端工程师技能之photoshop巧用系列第二篇——测量篇
× 目录 [1]测量信息 [2]实战 [3]注意事项 前面的话 前端工程师使用photoshop进行的大量工作实际上是测量.本文是photoshop巧用系列第二篇——测量篇 测量信息 在网页制作中需要 ...
- XSS 前端防火墙(4):天衣无缝的防护
例如,我们的属性钩子只考虑了 setAttribute,却忽视还有类似的 setAttributeNode.尽管从来不用这方法,但并不意味人家不能使用. 例如,创建元素通常都是 createEleme ...
- [ 高并发]Java高并发编程系列第二篇--线程同步
高并发,听起来高大上的一个词汇,在身处于互联网潮的社会大趋势下,高并发赋予了更多的传奇色彩.首先,我们可以看到很多招聘中,会提到有高并发项目者优先.高并发,意味着,你的前雇主,有很大的业务层面的需求, ...
- 从0开始搭建SQL Server AlwaysOn 第二篇(配置故障转移集群)
从0开始搭建SQL Server AlwaysOn 第二篇(配置故障转移集群) 第一篇http://www.cnblogs.com/lyhabc/p/4678330.html第二篇http://www ...
- (转)从0开始搭建SQL Server AlwaysOn 第二篇(配置故障转移集群)
原文地址: http://www.cnblogs.com/lyhabc/p/4682028.html 这一篇是从0开始搭建SQL Server AlwaysOn 的第二篇,主要讲述如何搭建故障转移集 ...
- 深入理解this机制系列第三篇——箭头函数
× 目录 [1]痛点 [2]解决 [3]基本用法[4]回调函数[5]注意事项 前面的话 this机制与函数调用有关,而作用域则与函数定义有关.有没有什么是可以将this机制和作用域联系起来的呢?本文将 ...
随机推荐
- screen.height && screen.width
screen.height && screen.width how to get window max width in js screen.height; screen.width; ...
- javascript中boolean类型和其他类型的转换
在javascript中,if语句括号中的表达式返回值可以是任何类型,即:if(a)中的a可以是boolean.number.string.object.function.undefined中的任何类 ...
- [BZOJ2095][Poi2010]Bridges 最大流(混合图欧拉回路)
2095: [Poi2010]Bridges Time Limit: 10 Sec Memory Limit: 259 MB Description YYD为了减肥,他来到了瘦海,这是一个巨大的海, ...
- nginx支持.htaccess文件实现伪静态的方法
方法如下: 1. 在需要使用.htaccess文件的目录下新建一个.htaccess文件, vim /var/www/html/.htaccess 2. 在里面输入规则,我这里输入Discuz的伪静态 ...
- 分享关于js解析URL中的参数的方法
function GetQueryString(name) { var reg = new RegExp("(^|&)" + name + "=([^&] ...
- 【poj1390】 Blocks
http://poj.org/problem?id=1390 (题目链接) 题意 给出一排方块,每次可以把颜色相同的消掉,获得长度的平方的分数,问最大得分. Solution 蜜汁dp.. 我们把颜色 ...
- 【bzoj3926】【Zjoi2015】诸神眷顾的幻想乡
题解: 如果树上某个路径串的端点不是叶子,那么一定是另一个串的子串: 这样只对叶子$dfs$把$20*20$个串插入广义$SAM$就是统计本质不同的串的个数的模板了: 我不太会分析广义$SAM$的空间 ...
- (转)Tomcat version 7.0 only supports J2EE 1.2, 1.3, 1.4, and Java EE 5 and 6 Web mod
背景:在sts中导入web项目,却不能通过sts中的tomcat来加载该服务,并报出如下错误. “Tomcat version 7.0 only supports J2EE 1.2, 1.3, 1.4 ...
- salt源码安装
salt是什么? 一种全新的基础设施管理方式,部署轻松,在几分钟内可运行起来,扩展性好,很容易管理上万台服务器,速度够快,服务器之间秒级通讯. salt底层采用动态的连接总线, 使其可以用于编配, 远 ...
- ribbion的负载均衡之端口的切换
可以说在这里被坑了很久,终于今天在大神的指导下,成功实现了负载均衡,切换不同的端口,这里来记录下,首先来看下效果图吧: 到底是怎么实现的呢?到底是如何切换的呢? 具体来讲: 几个步骤,启动服务注册中心 ...