php ssrf漏洞修复代码
这个存在漏洞的url是http://bbs.demo.com//forum.php?mod=ajax&action=downremoteimg&message=
攻击者把非法文件传入到参数进行SSRF攻击:
http://bbs.demo.com//forum.php?mod=ajax&action=downremoteimg&message=[img]http://tv.phpinfo.me/exp.php?s=ftp%26ip=127.0.0.1%26port=6379%26data=helo.jpg[/img]
这里message参数传的是用户在论坛发布的图片地址,正常情况下是图片格式后缀,虽然程序有对后缀进行了判断,但是判断不严格,只需要通过在url加图片后缀就可以蒙混过去。
解决办法是修改对url的合法性判断,后缀即使合法,也可能通过url rewrite方式伪造,所以进一步通过curl获取文件头信息,根据返回的报文Content-Type参数判断文件格式是否合法。
于是,在文件/source/module/forum/forum_ajax.php文件新增以下几个函数:
PHP
//获取上传图片url列表
function getImageList($temp)
{
$urlList = array();
foreach ($temp as $item) {
$urlList[] = $item[1];
}
return $urlList;
}
/**
* 检查content-type是否合法
* @param $imageList array 图片url列表
* @return bool true合法 false非法
*/
function checkContentType($imageList)
{
$allowExtensions = array('jpg', 'jpeg', 'png', 'gif', 'bmp');
$allowTypes = array('image/png', 'image/x-png', 'image/gif', 'image/jpeg', 'image/pjpeg');
foreach ($imageList as $url) {
$extension = getUrlExtension($url);
if(!in_array(strtolower($extension), $allowExtensions)){
return false;
}
$contentType = getContentType($url);
if (!in_array($contentType, $allowTypes)) {
return false;
}
}
return true;
}
//获取content-type
function getContentType($url)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_NOBODY, 1);
curl_exec($ch);
$contentType = curl_getinfo($ch, CURLINFO_CONTENT_TYPE);
return $contentType;
}
//获取url后缀
function getUrlExtension($url)
{
$parseurl = parse_url($url);
$extension = pathinfo($parseurl['path'], PATHINFO_EXTENSION);
return $extension;
}
在具体接口处理的地方新增:
//检测图片是否合法 Added by tanteng<tanteng@xunlei.com> 2016.07.07
if(is_array($temp) && !empty($temp)){
$imageList = getImageList($temp);
$check = checkContentType($imageList);
if ($check === false) {
die('file upload error!');
}
}
首先判断文件后缀是否合法,再通过curl请求判断header的Content-Type是否合法,因为后者不容易伪造。其中curl判断文件Content-Type方法:
PHP
//获取content-type
function getContentType($url)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_NOBODY, 1);
curl_exec($ch);
$contentType = curl_getinfo($ch, CURLINFO_CONTENT_TYPE);
return $contentType;
}
再通过乌云公开的漏洞地址,url传入非法格式的文件,程序不再继续执行。
不过,这样做有一个问题,有的图片地址并不是真实的静态文件,如:http://image.demo.com/avatar/100/150*150,这个路径就是一个图片,尽管不是图片格式的静态路径,那么这样判断就会误判,不过这种情况是很少数,暂且不管。
双引号在php使用中我们通常把它定义为字符串了,但你知道双引号在使用过程中会有一些小问题呢,那么有什么问题我们来看看PHP很多语法特性会让攻击者有机可乘,例如PHP会检测双引号中的变量。
执行如下代码:
function test()
{
echo "abc";
}
echo "${@test()}";
//或者
echo "${@phpinfo()}";
原理如下:
$a = 'b';
$b = 'a';
echo $$a; //a
以上就利用了PHP可变变量,双引号{}可解析双引号内的变量内容特性制造出来的小麻烦。
Laravel 5本身没有这个能力来防止xss跨站攻击了,但是这它可以使用Purifier 扩展包集成 HTMLPurifier 防止 XSS 跨站攻击了,我们一起来看一篇整合的例子。1、安装
HTMLPurifier 是基于 PHP 编写的富文本 HTML 过滤器,通常我们可以使用它来防止 XSS 跨站攻击,更多关于 HTMLPurifier的详情请参考其官网:http://htmlpurifier.org/。Purifier 是在 Laravel 5 中集成 HTMLPurifier 的扩展包,我们可以通过 Composer 来安装这个扩展包:
composer require mews/purifier
安装完成后,在配置文件config/app.php的providers中注册HTMLPurifier服务提供者:
'providers' => [
// ...
Mews\Purifier\PurifierServiceProvider::class,
]
然后在aliases中注册Purifier门面:
'aliases' => [
// ...
'Purifier' => Mews\Purifier\Facades\Purifier::class,
]
2、配置
要使用自定义的配置,发布配置文件到config目录:
php artisan vendor:publish
这样会在config目录下生成一个purifier.php文件:
return [
'encoding' => 'UTF-8',
'finalize' => true,
'preload' => false,
'cachePath' => null,
'settings' => [
'default' => [
'HTML.Doctype' => 'XHTML 1.0 Strict',
'HTML.Allowed' => 'div,b,strong,i,em,a[href|title],ul,ol,li,p[style],br,span[style],img[width|height|alt|src]',
'CSS.AllowedProperties' => 'font,font-size,font-weight,font-style,font-family,text-decoration,padding-left,color,background-color,text-align',
'AutoFormat.AutoParagraph' => true,
'AutoFormat.RemoveEmpty' => true
],
'test' => [
'Attr.EnableID' => true
],
"youtube" => [
"HTML.SafeIframe" => 'true',
"URI.SafeIframeRegexp" => "%^(http://|https://|//)(www.youtube.com/embed/|player.vimeo.com/video/)%",
],
],
];
3、使用示例
可以使用辅助函数clean:
clean(Input::get('inputname'));
或者使用Purifier门面提供的clean方法:
Purifier::clean(Input::get('inputname'));
还可以在应用中进行动态配置:
clean('This is my H1 title', 'titles');
clean('This is my H1 title', array('Attr.EnableID' => true));
或者你也可以使用Purifier门面提供的方法:
Purifier::clean('This is my H1 title', 'titles');
Purifier::clean('This is my H1 title', array('Attr.EnableID' => true));
php防止xss攻击
<?PHP
function clean_xss(&$string, $low = False)
{
if (! is_array ( $string ))
{
$string = trim ( $string );
$string = strip_tags ( $string );
$string = htmlspecialchars ( $string );
if ($low)
{
return True;
}
$string = str_replace ( array ('"', "\\", "'", "/", "..", "../", "./", "//" ), '', $string );
$no = '/%0[0-8bcef]/';
$string = preg_replace ( $no, '', $string );
$no = '/%1[0-9a-f]/';
$string = preg_replace ( $no, '', $string );
$no = '/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]+/S';
$string = preg_replace ( $no, '', $string );
return True;
}
$keys = array_keys ( $string );
foreach ( $keys as $key )
{
clean_xss ( $string [$key] );
}
}
//just a test
$str = '111cn.net<meta http-equiv="refresh" content="0;">';
clean_xss($str); //如果你把这个注释掉,你就知道xss攻击的厉害了
echo $str;
?>
相信很多人要么是md5()直接存入库或者存储md5()和salt两个字段。但第一种不安全。第二种麻烦。好在php提供了更简单的解决方案。
注:以下的前提条件是在php5.5版本中的
在php5.5以后,可以换一种存法了。简单方便。
<?php
$pwd = "123456";
$hash = password_hash($pwd, PASSWORD_BCRYPT);
echo $hash;
// mysql中就只需要存储这个hash值就行了。建议把数据库该字段值设置为255
if (password_verify($pwd, '数据库中的hash值')) {
echo "密码正确";
} else {
echo "密码错误";
}
看到这时,可能有些人说tm以前我存密码只是单独存了一个md5的password,也没有用salt,现在我想改成你这种,可怎么办好呢。
参考stackoverflow中的这个文章,也许对你有帮助。
http://stackoverflow.com/questions/18906660/converting-md5-password-hashes-to-php-5-5-password-hash
$password = $_POST["password"];
// TODO 这里要判断一下这个密码是否是正确密码
// 然后再决定更新
if (substr($pwInDatabase, 0, 1) == "$")
{
// Password already converted, verify using password_verify
}
else
{
// User still using the old MD5, update it!
if (md5($password) == $pwInDatabase)
{
$db->storePw(password_hash($password));
}
}
不推荐图中这种做法,因为double hash不会增加安全性。
相关文章
- 有一种方法,可以不打开网站而直接查看到这个网站的源代码.. 这样可以有效地防止误入恶意网站... 在浏览器地址栏输入: view-source:http://...2016-09-20
- <?php require('path.inc.php'); header('content-Type: text/html; charset=utf-8'); $borough_id = intval($_GET['id']); if(!$borough_id){ echo ' ...2016-11-25
- Multipart/form-data是文件上传或数据提交时会用到了,在php中Multipart/form-data是有安全bug的,下面我们来看看如何修复Multipart/form-data的bug吧. 今天在乌云...2016-11-25
- 本文实例讲述了JS基于Mootools实现的个性菜单效果代码。分享给大家供大家参考,具体如下:这里演示基于Mootools做的带动画的垂直型菜单,是一个初学者写的,用来学习Mootools的使用有帮助,下载时请注意要将外部引用的mootools...2015-10-23
- 本文实例讲述了JS+CSS实现分类动态选择及移动功能效果代码。分享给大家供大家参考,具体如下:这是一个类似选项卡功能的选择插件,与普通的TAb区别是加入了动画效果,多用于商品类网站,用作商品分类功能,不过其它网站也可以用,...2015-10-21
- 本文实例讲述了JS实现自定义简单网页软键盘效果。分享给大家供大家参考,具体如下:这是一款自定义的简单点的网页软键盘,没有使用任何控件,仅是为了练习JavaScript编写水平,安全性方面没有过多考虑,有顾虑的可以不用,目的是学...2015-11-08
- php 取除连续空格与换行代码,这些我们都用到str_replace与正则函数 第一种: $content=str_replace("n","",$content); echo $content; 第二种: $content=preg_replac...2016-11-25
- php简单用户登陆程序代码 这些教程很对初学者来讲是很有用的哦,这款就下面这一点点代码了哦。 <center> <p> </p> <p> </p> <form name="form1...2016-11-25
- 公司一些wordpress网站由于下载的插件存在恶意代码,导致整个服务器所有网站PHP文件都存在恶意代码,就写了个简单的脚本清除。恶意代码示例...2015-10-23
- 其实挺简单的就是if(navigator.userAgent.indexOf('UCBrowser') > -1) {alert("uc浏览器");}else{//不是uc浏览器执行的操作}如果想测试某个浏览器的特征可以通过如下方法获取JS获取浏览器信息 浏览器代码名称:navigator...2015-11-08
- 本文实例讲述了JS实现双击屏幕滚动效果代码。分享给大家供大家参考,具体如下:这里演示双击滚屏效果代码的实现方法,不知道有觉得有用处的没,现在网上还有很多还在用这个特效的呢,代码分享给大家吧。运行效果截图如下:在线演...2015-10-30
- 一、日期减去天数等于第二个日期function cc(dd,dadd){//可以加上错误处理var a = new Date(dd)a = a.valueOf()a = a - dadd * 24 * 60 * 60 * 1000a = new Date(a)alert(a.getFullYear() + "年" + (a.getMonth() +...2015-11-08
- 微信支付,即便交了保证金,你还是处理测试阶段,不能正式发布。必须到你通过程序测试提交订单、发货通知等数据到微信的系统中,才能申请发布。然后,因为在微信中是通过JS方式调用API,必须在微信后台设置支付授权目录,而且要到...2014-05-31
- 本文实例讲述了PHP常用的小程序代码段。分享给大家供大家参考,具体如下:1.计算两个时间的相差几天$startdate=strtotime("2009-12-09");$enddate=strtotime("2009-12-05");上面的php时间日期函数strtotime已经把字符串...2015-11-24
- 小编分享了一段简单的php中文转拼音的实现代码,代码简单易懂,适合初学php的同学参考学习。 代码如下 复制代码 <?phpfunction Pinyin($_String...2017-07-06
php导出csv格式数据并将数字转换成文本的思路以及代码分享
php导出csv格式数据实现:先定义一个字符串 存储内容,例如 $exportdata = '规则111,规则222,审222,规222,服2222,规则1,规则2,规则3,匹配字符,设置时间,有效期'."/n";然后对需要保存csv的数组进行foreach循环,例如复制代...2014-06-07- ecshop商品无限级分类代码 function cat_options($spec_cat_id, $arr) { static $cat_options = array(); if (isset($cat_options[$spec_cat_id]))...2016-11-25
- 本文介绍了如何延迟javascript代码的加载,加快网页的访问速度。 当一个网站有很多js代码要加载,js代码放置的位置在一定程度上将会影像网页的加载速度,为了让我们的网页加载速度更快,本文总结了一下几个注意点...2013-10-13
- 这篇文章主要介绍了vue项目,代码提交至码云,iconfont的用法说明,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-07-30
- 这篇文章主要介绍了IDEA插件之快速删除Java代码中的注释,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-02-18