php ceil 漏洞,Fortify漏洞修复总结

1.代码注入

1.1 命令注入

问题代码:

$dir = $_POST['dir']

exec("cmd.exe /c dir" + $dir);

修复方案:

(1)程序对非受信的用户输入数据进行净化,删除不安全的字符。

(2)限定输入类型, 创建一份安全字符串列表,限制用户只能输入该列表中的数据。 修复例子:

//方式1

if (!preg_match('/^[\w\.:\-]+$/', $dir) ){

// Handle error

}

$cmd = filter_var($cmd, FILTER_VALIDATE_REGEXP,

array("options" => array("regexp" => getCommandFilterReg())));

...

$msg = escapeshellarg($msg);

//方式2

function cmd_arg($cmd, $filter='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.')

{

$filter_chars = str_split($filter);

$filter_chars = array_combine($filter_chars, $filter_chars);

$cmd_chars = str_split($cmd);

$ret = '';

foreach ($cmd_chars as $v)

{

$ret .= isset($filter_chars[$v]) ? $filter_chars[$v] : '';

}

return $ret;

}

$cmd = cmd_arg($cmd);

1.2 js动态代码注入

(1)主要是前端使用了eval函数来解析服务端的响应

evalResponse: function() {

try {

return eval((this.transport.responseText ));

} catch (e) {

this.dispatchException(e);

}

修复方案: a.不要使用eval函数,使用自定义函数替换

function _dhtmlxEvalData( code )

{

var script;

if ( code ) {

var data_key = '_process_json_data_'+parseInt( rand(0,1000000000000));

code = 'window["'+data_key+'"]=('+code+');'

// If the code includes a valid, prologue position

// strict mode pragma, execute code by injecting a

// script tag into the document.

script = document.createElement("script");

script.text = code;

document.head.appendChild( script ).parentNode.removeChild( script );

return window[data_key];

}

return null;

}

return _dhtmlxEvalData(this.transport.responseText );

(2)document.write(html)中写入的html和document.location = url 中的url没有过滤处理

var html = ''+rows[i]+'';

document.write(html)

....

document.location = url

修复方案: a.避免使用document.write 参考地址

b.使用白名单

//document.write() 换成如下写法

_var sNew = document.createElement("script");

sNew.async = true;

sNew.src = "https://example.com/script.min.js";

var s0 = document.getElementsByTagName('script')[0];

s0.parentNode.insertBefore(sNew, s0);

//document.location = url的处理

function safe_url (url, whiteChars)

{

whiteChars = ''+(whiteChars||'0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz.-_~+#,%&=*;:@[]');

var ret = '';

for(var i=0; i

{

ret += whiteChars[whiteChars.indexOf(url[i])] || '';

}

do

{

var old = ret;

ret = ret.replace(/javascript:/gi,'');

}while(ret != old);

return ret;

}

document.location = safe_url(url);

(3) 接收的全局变量和setTimeout函数相遇

问题代码:

this.timer = setTimeout(this.onTimerEvent.bind(this),

this.decay * this.frequency * 1000);

...

(u = setTimeout(function() {

x.abort("timeout")

},

c.timeout));

修复方案: 使用匿名函数,包裹setTimeout函数

(function(){

this.timer = setTimeout(this.onTimerEvent.bind(this),

this.decay * this.frequency * 1000);

})();

...

(u = (function()

{

var u = setTimeout(function() {

x.abort("timeout")

}, c.timeout);

return u;

})()

);

1.3 JSON 注入

问题代码:

$data = file_get_contents("php://input");

$data = json_decode($data, true);

修复方案: 使用filter_var函数进行过滤 修复例子:

$data = file_get_contents("php://input");

$data = filter_var($data, FILTER_SANITIZE_STRING, FILTER_FLAG_NO_ENCODE_QUOTES);

$data = json_decode($data, true);

1.4 SQL注入

SQL injection 发生原因:

1、数据从一个不可信赖的数据源进入程序。

2、数据用于动态地构造一个 SQL 查询。

问题代码:

$sql = "SELECT value FROM config WHERE ip=".$ip." AND owner=".$_SESSION["user"];

$stm->execute();

$stm->fetchAll(PDO::FETCH_ASSOC);

修复方案:

a、确保sql语句不通过拼接的方式构造;

b、然后采用一些对sql语句进行预编译的执行方法;

c、最后再以参数绑定的方式设置sql语句需要的条件的值。

修复例子:

$sql = "SELECT value FROM config WHERE ip=? AND owner=?";

$stm = $db->prepare($sql);

$stm->execute(array($ip, $_SESSION["user"]));

$rows = $stm->fetchAll(PDO::FETCH_ASSOC);

2.不安全随机数

2.1 php例子

代码中使用了rand() 和mt_rand() 函数,相关了解

mt_srand(time());

$token = mt_rand();

...

$randnum = rand(1,10000);

$str = md5($token.$randnum.time());

...

修复方案: 1.php7 添加了更好的随机数random_int()用来代替php5的mt_rand()

2.使用openssl_random_pseudo_bytes函数重新自定义随机函数,注意运行环境需要支持该函数

修复例子:f

unction dynamicNumber($min,$max) {

$range = $max - $min + 1;

if ($range == 0) return $min;

$length = (int) (log($range,2)/8) + 1;

$max = pow(2, 8 * $length);

$num = $max + 1;

while ($num > $max) {

$num = hexdec(bin2hex(openssl_random_pseudo_bytes($length,$s)));

}

return ($num % $range) + $min;

}

function getDynamicInt($min = 0, $max = null)

{

if ($max === null) {

$max = getrandmax();

}

return dynamicNumber($min,$max);

}

function getDynamicMtInt($min = 0, $max = null)

{

if ($max === null) {

$max = mt_getrandmax();

}

return dynamicNumber($min,$max);

}

$token = getDynamicMtInt();

...

$randnum = getDynamicInt(1,10000);

2.2 js例子

代码中使用了Math.random()

...

var rnd = Math.random();

...

修复方案: 不使用Math.random(),原理参考 自定义随机函数 修复例子:

var rand = (function(){

var seed = (new Date()).getTime()

function r(){

seed = (seed*9301+49297)%233280

return seed/(233280.0)

}

return function(number){

return Math.ceil(r()*number)

}

})()

console.log(rand(5));

function randnum() {

var seed = (new Date()).getTime();

seed = (seed*9301+49297)%233280;

return seed/(233280.0);

}

3.硬编码密码

if (password == null) {

password = "123456";

}

fortify可能会误报,比如一些带关键词的变量:password、passwd、pass、password_xxx、xxx_passwd等

修复方式: 程序中所需密码应从配置文件中获取经过加密的密码值。对于误报的变量,只有修改变量名。

4.其他

1.空密码问题

其实只是变量设置为空,但是fortify要报错

$passwd = "";

//解决方式用函数转为空

$passwd = strval(null);

2.变量覆盖

extract($params)

//改为

extract($params,EXTR_SKIP);

3.base64_pri_decrypt() 方法执行不带 OAEP 填充模式的公钥 RSA 加密,因此加密机制比较脆弱。

openssl_public_encrypt($input, $output, $key, OPENSSL_NO_PADDING);

=》

openssl_private_decrypt($password_base64_decode, $password_decode, $pi_key,OPENSSL_PKCS1_OAEP_PADDING);//私钥解密

4.js中的setTimeout 报动态代码注入

this.timer = setTimeout(this.onTimerEvent.bind(this), this.decay * this.frequency * 1000);

用匿名函数将其包裹

(function(){ this.timer = setTimeout(this.onTimerEvent.bind(this), this.decay * this.frequency * 1000);

})();

例2:

(u = setTimeout(function() { x.abort("timeout") }, c.timeout)); 改为

(u = (function() { var u = setTimeout(function() { x.abort("timeout") }, c.timeout); return u; })() );

5.Cookie Security: Overly Broad Path path 不传“/”

6..xss,css Dom

safe_url: function (url, whiteChars) {

whiteChars = ''+(whiteChars||'0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz.-_~+#,%&=*;:@[]');

var ret = '';

for(var i=0; i

{

ret += whiteChars[whiteChars.indexOf(url[i])] || '';

}

do

{

var old = ret;

ret = ret.replace(/javascript:/gi,'');

}while(ret != old);

return ret;

},

7.jsonencode的输出 filter_var_array()

function stripHtml(value) {

// remove html tags and space chars

return value.replace(/<.>]*?>/g, " ").replace(/ | /gi, " ")

// remove punctuation

.replace(/[.(),;:!?%#$'\"_+=\/\-“”’]*/g, "");

}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值