SRCMS·轻响应V1.6正式版

修复外部报告的多个严重安全缺陷
This commit is contained in:
Martin Zhou
2016-01-26 14:09:59 +08:00
parent e650f04553
commit f46a67c7ec
31 changed files with 924 additions and 114 deletions

View File

@@ -1,11 +1,170 @@
<?php
//<2F><><EFBFBD>ı<EFBFBD>XSS<53><53><EFBFBD><EFBFBD>
function waf($arr)
{
$ra=Array('/([\x00-\x08,\x0b-\x0c,\x0e-\x19])/','/<script/i','/javascript:/i','/vbscript:/i','/expression/i','/applet/','/meta/','/xml/','/blink/','/<link/i','/<embed/i','/<object/i','/frame/i','/iframe/i','/layer/','/title/','/bgsound/','/base/','/onload=/i','/onunload=/i','/onchange=/i','/onsubmit=/i','/onreset=/','/onselect=/i','/onblur=/i','/onfocus=/i','/onabort=/i','/onkeydown=/i','/onkeypress=/i','/onkeyup=/i','/onclick=/i','/ondblclick=/i','/onmousedown=/','/onmousemove=/i','/onmouseout=/i','/onmouseover=/i','/onmouseup=/i','/onunload=/i','/alert/i','/<input/i');
$value = preg_replace($ra,'',$arr);
echo $value;
/**
* PHP <20><><EFBFBD>ı<EFBFBD>XSS<53><53><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*
* @package XssHtml
* @version 1.0.0
* @link http://phith0n.github.io/XssHtml
* @since 20140621
* @copyright (c) Phithon All Rights Reserved
*
*/
class XssHtml {
private $m_dom;
private $m_xss;
private $m_ok;
private $m_AllowAttr = array('title', 'src', 'href', 'id', 'class', 'style', 'width', 'height', 'alt', 'target', 'align');
private $m_AllowTag = array('a', 'img', 'br', 'strong', 'b', 'code', 'pre', 'p', 'div', 'em', 'span', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'table', 'ul', 'ol', 'tr', 'th', 'td', 'hr', 'li', 'u');
/**
* <20><><EFBFBD><EFBFBD><ECBAAF>
*
* @param string $html <20><><EFBFBD><EFBFBD><EFBFBD>˵<EFBFBD><CBB5>ı<EFBFBD>
* @param string $charset <20>ı<EFBFBD><C4B1><EFBFBD><EFBFBD>룬Ĭ<EBA3AC><C4AC>utf-8
* @param array $AllowTag <20><><EFBFBD><EFBFBD><EFBFBD>ı<EFBFBD>ǩ<EFBFBD><C7A9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EBB1A3>Ĭ<EFBFBD>ϣ<EFBFBD>Ĭ<EFBFBD><C4AC><EFBFBD>Ѻ<EFBFBD><D1BA>Ǵ󲿷ֹ<F3B2BFB7><D6B9>ܣ<EFBFBD><DCA3><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD>Σ<EFBFBD>ձ<EFBFBD>ǩ
*/
public function __construct($html, $charset = 'utf-8', $AllowTag = array()){
$this->m_AllowTag = empty($AllowTag) ? $this->m_AllowTag : $AllowTag;
$this->m_xss = strip_tags($html, '<' . implode('><', $this->m_AllowTag) . '>');
if (empty($this->m_xss)) {
$this->m_ok = FALSE;
return ;
}
$this->m_xss = "<meta http-equiv=\"Content-Type\" content=\"text/html;charset={$charset}\"><nouse>" . $this->m_xss . "</nouse>";
$this->m_dom = new DOMDocument();
$this->m_dom->strictErrorChecking = FALSE;
$this->m_ok = @$this->m_dom->loadHTML($this->m_xss);
}
/**
* <20><><EFBFBD>ù<EFBFBD><C3B9>˺<EFBFBD><CBBA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
public function getHtml()
{
if (!$this->m_ok) {
return '';
}
$nodeList = $this->m_dom->getElementsByTagName('*');
for ($i = 0; $i < $nodeList->length; $i++){
$node = $nodeList->item($i);
if (in_array($node->nodeName, $this->m_AllowTag)) {
if (method_exists($this, "__node_{$node->nodeName}")) {
call_user_func(array($this, "__node_{$node->nodeName}"), $node);
}else{
call_user_func(array($this, '__node_default'), $node);
}
}
}
$html = strip_tags($this->m_dom->saveHTML(), '<' . implode('><', $this->m_AllowTag) . '>');
$html = preg_replace('/^\n(.*)\n$/s', '$1', $html);
return $html;
}
private function __true_url($url){
if (preg_match('#^https?://.+#is', $url)) {
return $url;
}else{
return 'http://' . $url;
}
}
private function __get_style($node){
if ($node->attributes->getNamedItem('style')) {
$style = $node->attributes->getNamedItem('style')->nodeValue;
$style = str_replace('\\', ' ', $style);
$style = str_replace(array('&#', '/*', '*/'), ' ', $style);
$style = preg_replace('#e.*x.*p.*r.*e.*s.*s.*i.*o.*n#Uis', ' ', $style);
return $style;
}else{
return '';
}
}
private function __get_link($node, $att){
$link = $node->attributes->getNamedItem($att);
if ($link) {
return $this->__true_url($link->nodeValue);
}else{
return '';
}
}
private function __setAttr($dom, $attr, $val){
if (!empty($val)) {
$dom->setAttribute($attr, $val);
}
}
private function __set_default_attr($node, $attr, $default = '')
{
$o = $node->attributes->getNamedItem($attr);
if ($o) {
$this->__setAttr($node, $attr, $o->nodeValue);
}else{
$this->__setAttr($node, $attr, $default);
}
}
private function __common_attr($node)
{
$list = array();
foreach ($node->attributes as $attr) {
if (!in_array($attr->nodeName,
$this->m_AllowAttr)) {
$list[] = $attr->nodeName;
}
}
foreach ($list as $attr) {
$node->removeAttribute($attr);
}
$style = $this->__get_style($node);
$this->__setAttr($node, 'style', $style);
$this->__set_default_attr($node, 'title');
$this->__set_default_attr($node, 'id');
$this->__set_default_attr($node, 'class');
}
private function __node_img($node){
$this->__common_attr($node);
$this->__set_default_attr($node, 'src');
$this->__set_default_attr($node, 'width');
$this->__set_default_attr($node, 'height');
$this->__set_default_attr($node, 'alt');
$this->__set_default_attr($node, 'align');
}
private function __node_a($node){
$this->__common_attr($node);
$href = $this->__get_link($node, 'href');
$this->__setAttr($node, 'href', $href);
$this->__set_default_attr($node, 'target', '_blank');
}
private function __node_embed($node){
$this->__common_attr($node);
$link = $this->__get_link($node, 'src');
$this->__setAttr($node, 'src', $link);
$this->__setAttr($node, 'allowscriptaccess', 'never');
$this->__set_default_attr($node, 'width');
$this->__set_default_attr($node, 'height');
}
private function __node_default($node){
$this->__common_attr($node);
}
}
function waf($data)
{
$xss = new XssHtml($data);
$html = $xss->getHtml();
echo $html;
}
?>

View File

@@ -40,7 +40,7 @@ class GiftController extends BaseController{
$model = D("order");
$model->user_id = 1;
$model->username = 1;
if (!$model->create()) {
if (!$model->field('username,email,password,repassword,gid')->create()) {
// 如果创建失败 表示验证没有通过 输出错误提示信息
$this->error($model->getError());
exit();

View File

@@ -11,6 +11,7 @@ use Think\Controller;
class IndexController extends BaseController {
public function index(){
echo waf('111111');
$id = session('userId');
$tmodel= M('setting');
$title = $tmodel->where('id=1')->select();

View File

@@ -3,10 +3,10 @@ namespace User\Controller;
use Think\Controller;
/**
* @author Zhou Yuyang <1009465756@qq.com> 12:28 2016/1/23
* @author Zhou Yuyang <1009465756@qq.com> 12:21 2016/1/26
* @copyright 2105-2018 SRCMS
* @homepage http://www.src.pw
* @version 1.5
* @version 1.6
*/
class InfoController extends BaseController{
@@ -35,7 +35,7 @@ class InfoController extends BaseController{
$model = D("info");
$model->user_id = 1;
$model->username = 1;
if (!$model->create()) {
if (!$model->field('realname,zipcode,location,tel,alipay')->create()) {
// 如果创建失败 表示验证没有通过 输出错误提示信息
$this->error($model->getError());
exit();
@@ -67,15 +67,15 @@ class InfoController extends BaseController{
$model = D("info");
$model->user_id = 1;
$model->username = 1;
if (!$model->create()) {
if (!$model->field('realname,zipcode,location,tel,alipay')->create()) {
// 如果创建失败 表示验证没有通过 输出错误提示信息
$this->error($model->getError());
exit();
} else {
if ($model->save()) {
$this->success("更新成功", U('info/index'));
$this->success("联系方式更新成功", U('info/index'));
} else {
$this->error("更新失败");
$this->error("联系方式更新失败");
}
}
}

View File

@@ -59,7 +59,7 @@ class LoginController extends Controller {
//验证码
public function verify(){
ob_clean();
ob_clean();
$Verify = new \Think\Verify();
$Verify->codeSet = '123456789abcdefg';
$Verify->fontSize = 16;
@@ -78,4 +78,4 @@ class LoginController extends Controller {
session('username',null);
redirect(U('Login/index'));
}
}
}

View File

@@ -57,7 +57,7 @@ class PostController extends BaseController
$model = D("Post");
$model->time = time();
$model->user_id = 1;
if (!$model->create()) {
if (!$model->field('title,user_id,cate_id,content')->create()) {
// 如果创建失败 表示验证没有通过 输出错误提示信息
$this->error($model->getError());
exit();
@@ -77,8 +77,8 @@ class PostController extends BaseController
public function view(){
$id = session('userId');
$rid = I('get.rid',0,'intval');
$model = M("Post");
$post = $model->where(array('user_id'=>$id,'id'=>$rid))->find();
$model = M("Post");
$post = $model->where(array('user_id'=>$id,'id'=>$rid))->find(); //修复越权漏洞
$tmodel= M('setting');
$title = $tmodel->where('id=1')->select();
$this->assign('title', $title);

View File

@@ -3,10 +3,10 @@ namespace User\Controller;
use Think\Controller;
/**
* @author Zhou Yuyang <1009465756@qq.com> 12:28 2016/1/23
* @author Zhou Yuyang <1009465756@qq.com> 11:28 2016/1/26
* @copyright 2105-2018 SRCMS
* @homepage http://www.src.pw
* @version 1.5
* @version 1.6
*/
@@ -38,15 +38,15 @@ class RegController extends Controller{
if (IS_POST) {
//如果用户提交数据
$model = D("Member");
if (!$model->create()) {
if (!$model->field('username,email,password,repassword')->create()) {
// 如果创建失败 表示验证没有通过 输出错误提示信息
$this->error($model->getError());
exit();
} else {
if ($model->add()) {
$this->success("用户添加成功", U('index/index'));
$this->success("注册成功", U('index/index'));
} else {
$this->error("用户添加失败");
$this->error("注册失败");
}
}
}

View File

@@ -0,0 +1,187 @@
<?php
/**
* PHP 富文本XSS过滤类
*
* @package XssHtml
* @version 1.0.0
* @link http://phith0n.github.io/XssHtml
* @since 20140621
* @copyright (c) Phithon All Rights Reserved
*
*/
#
# Written by Phithon <root@leavesongs.com> in 2014 and placed in
# the public domain.
#
# phithon <root@leavesongs.com> 编写于20140621
# From: XDSEC <www.xdsec.org> & 离别歌 <www.leavesongs.com>
# Usage:
# <?php
# require('xsshtml.class.php');
# $html = '<html code>';
# $xss = new XssHtml($html);
# $html = $xss->getHtml();
# ?\>
#
# 需求:
# PHP Version > 5.0
# 浏览器版本IE7+ 或其他浏览器无法防御IE6及以下版本浏览器中的XSS
# 更多使用选项见 http://phith0n.github.io/XssHtml
class XssHtml {
private $m_dom;
private $m_xss;
private $m_ok;
private $m_AllowAttr = array('title', 'src', 'href', 'id', 'class', 'style', 'width', 'height', 'alt', 'target', 'align');
private $m_AllowTag = array('a', 'img', 'br', 'strong', 'b', 'code', 'pre', 'p', 'div', 'em', 'span', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'table', 'ul', 'ol', 'tr', 'th', 'td', 'hr', 'li', 'u');
/**
* 构造函数
*
* @param string $html 待过滤的文本
* @param string $charset 文本编码默认utf-8
* @param array $AllowTag 允许的标签,如果不清楚请保持默认,默认已涵盖大部分功能,不要增加危险标签
*/
public function __construct($html, $charset = 'utf-8', $AllowTag = array()){
$this->m_AllowTag = empty($AllowTag) ? $this->m_AllowTag : $AllowTag;
$this->m_xss = strip_tags($html, '<' . implode('><', $this->m_AllowTag) . '>');
if (empty($this->m_xss)) {
$this->m_ok = FALSE;
return ;
}
$this->m_xss = "<meta http-equiv=\"Content-Type\" content=\"text/html;charset={$charset}\"><nouse>" . $this->m_xss . "</nouse>";
$this->m_dom = new DOMDocument();
$this->m_dom->strictErrorChecking = FALSE;
$this->m_ok = @$this->m_dom->loadHTML($this->m_xss);
}
/**
* 获得过滤后的内容
*/
public function getHtml()
{
if (!$this->m_ok) {
return '';
}
$nodeList = $this->m_dom->getElementsByTagName('*');
for ($i = 0; $i < $nodeList->length; $i++){
$node = $nodeList->item($i);
if (in_array($node->nodeName, $this->m_AllowTag)) {
if (method_exists($this, "__node_{$node->nodeName}")) {
call_user_func(array($this, "__node_{$node->nodeName}"), $node);
}else{
call_user_func(array($this, '__node_default'), $node);
}
}
}
$html = strip_tags($this->m_dom->saveHTML(), '<' . implode('><', $this->m_AllowTag) . '>');
$html = preg_replace('/^\n(.*)\n$/s', '$1', $html);
return $html;
}
private function __true_url($url){
if (preg_match('#^https?://.+#is', $url)) {
return $url;
}else{
return 'http://' . $url;
}
}
private function __get_style($node){
if ($node->attributes->getNamedItem('style')) {
$style = $node->attributes->getNamedItem('style')->nodeValue;
$style = str_replace('\\', ' ', $style);
$style = str_replace(array('&#', '/*', '*/'), ' ', $style);
$style = preg_replace('#e.*x.*p.*r.*e.*s.*s.*i.*o.*n#Uis', ' ', $style);
return $style;
}else{
return '';
}
}
private function __get_link($node, $att){
$link = $node->attributes->getNamedItem($att);
if ($link) {
return $this->__true_url($link->nodeValue);
}else{
return '';
}
}
private function __setAttr($dom, $attr, $val){
if (!empty($val)) {
$dom->setAttribute($attr, $val);
}
}
private function __set_default_attr($node, $attr, $default = '')
{
$o = $node->attributes->getNamedItem($attr);
if ($o) {
$this->__setAttr($node, $attr, $o->nodeValue);
}else{
$this->__setAttr($node, $attr, $default);
}
}
private function __common_attr($node)
{
$list = array();
foreach ($node->attributes as $attr) {
if (!in_array($attr->nodeName,
$this->m_AllowAttr)) {
$list[] = $attr->nodeName;
}
}
foreach ($list as $attr) {
$node->removeAttribute($attr);
}
$style = $this->__get_style($node);
$this->__setAttr($node, 'style', $style);
$this->__set_default_attr($node, 'title');
$this->__set_default_attr($node, 'id');
$this->__set_default_attr($node, 'class');
}
private function __node_img($node){
$this->__common_attr($node);
$this->__set_default_attr($node, 'src');
$this->__set_default_attr($node, 'width');
$this->__set_default_attr($node, 'height');
$this->__set_default_attr($node, 'alt');
$this->__set_default_attr($node, 'align');
}
private function __node_a($node){
$this->__common_attr($node);
$href = $this->__get_link($node, 'href');
$this->__setAttr($node, 'href', $href);
$this->__set_default_attr($node, 'target', '_blank');
}
private function __node_embed($node){
$this->__common_attr($node);
$link = $this->__get_link($node, 'src');
$this->__setAttr($node, 'src', $link);
$this->__setAttr($node, 'allowscriptaccess', 'never');
$this->__set_default_attr($node, 'width');
$this->__set_default_attr($node, 'height');
}
private function __node_default($node){
$this->__common_attr($node);
}
}
// if(php_sapi_name() == "cli"){
// $html = $argv[1];
// $xss = new XssHtml($html);
// $html = $xss->getHtml();
// echo "'$html'";
// }
?>

View File

@@ -8,8 +8,8 @@ class MemberModel extends Model{
array('email','email','邮箱格式错误!'), //默认情况下用正则进行验证
array('password','require','请填写密码!','','',self::MODEL_INSERT), //默认情况下用正则进行验证
array('repassword','password','确认密码不正确',0,'confirm'), // 验证确认密码是否和密码一致
array('username','','用户名已存在',0,'unique',self::MODEL_BOTH), // 在新增的时候验证name字段是否唯一
array('email','','邮箱已存在',0,'unique',self::MODEL_BOTH), // 在新增的时候验证name字段是否唯一
array('username','','用户名已存在',0,'unique',self::MODEL_BOTH), // 在新增的时候验证name字段是否唯一
array('email','','邮箱已存在',0,'unique',self::MODEL_BOTH), // 在新增的时候验证name字段是否唯一
);
protected $_auto = array(

View File

@@ -3,40 +3,56 @@
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta charset="utf-8">
<title>应急响应中心</title>
<meta name="generator" content="Bootply" />
<title><foreach name="title" item="v">{$v.value}</foreach>安全应急响应中心</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<link href="__PUBLIC__/Home/css/bootstrap.min.css" rel="stylesheet">
<link href="//netdna.bootstrapcdn.com/font-awesome/3.2.1/css/font-awesome.min.css" rel="stylesheet">
<link href="__PUBLIC__/User/font-awesome/css/font-awesome.css" rel="stylesheet">
<link href="__PUBLIC__/Home/index/carousel.css" rel="stylesheet">
<!--[if lt IE 9]>
<script src="//html5shim.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<link href="__PUBLIC__/Home/css/styles.css" rel="stylesheet">
</head>
<body>
<div class="navbar navbar-fixed-top navbar-bold" data-spy="affix" data-offset-top="1000">
<div class="container">
<div class="navbar-header">
<a href="__ROOT__/index.php" class="navbar-brand">应急响应中心</a>
<a class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</a>
</div>
<div class="navbar-collapse collapse" id="navbar">
<ul class="nav navbar-nav">
<li><a href="{:U('index/index')}">个人中心</a></li>
<!--<li><a href="{:U('post/index')}">漏洞列表</a></li>
<li><a href="{:U('post/add')}">报告漏洞</a></li>
<li><a href="__ROOT__/index.php?m=&c=page&a=index">公告</a></li>
<li><a href="__ROOT__/index.php?m=&c=hall&a=index">贡献榜</a></li>
<li><a href="__ROOT__/index.php?m=&c=gift&a=index">礼品库</a></li>-->
</ul>
</div>
</div>
</div>
<body>
<nav class="navbar navbar-default navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
<span class="yahei sr-only">Toggle navigation</span>
<span class="yahei icon-bar"></span>
<span class="yahei icon-bar"></span>
<span class="yaheiicon-bar"></span>
</button>
<a class="yahei navbar-brand" href="__ROOT__"><strong><foreach name="title" item="v">{$v.value}</foreach></strong>
<span class="yahei navbar-brand-subtitle">安全应急响应中心</span>
</a>
</div>
<div id="navbar" class="navbar-collapse collapse">
<ul class="yahei nav navbar-nav">
<li><a href="{:U('index/index')}">个人中心</a></li>
<li><a href="{:U('post/add')}">报告漏洞</a></li>
<li><a href="{:U('post/index')}">漏洞列表</a></li>
<li><a href="{:U('gift/index')}">礼品兑换</a></li>
<li><a href="{:U('info/index')}">联系方式</a></li>
</ul>
<ul class="yahei nav navbar-nav navbar-right">
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"><?php echo session('username')?><span class="caret"></span></a>
<ul class="dropdown-menu">
<!--<li><a href="#">Action</a></li>
<li><a href="#">更改密码</a></li>
<li><a href="#">Something else here</a></li>
<li role="separator" class="divider"></li>
<li class="dropdown-header">Nav header</li>-->
<li><a href="{:U('change/index')}">更改密码</a></li>
<li><a href="{:U('login/logout')}">退出登录</a></li>
</ul>
</li>
</ul>
</div>
</div><!--/.navbar-collapse -->
</div>
</nav>
<div class="gallery">
<div class="row">