Fortify漏洞修复总结

摘要:
=旧);returnret;}document.location=safe_url;收到的全局变量和setTimeout函数满足问题代码:this。timer=setTimeout;修复:使用匿名函数,包装setTimeout函数();1.3 JSON注入问题代码:$data=file_get_contents;$data=json_解码;修复:使用filter_过滤和修复var函数的示例:$data=file_get_contents;$数据=过滤器_变量;$data=json_解码;1.4 SQL注入的原因:1。数据从不受信任的数据源进入程序。
 

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 = '<span>'+rows[i]+'</span>';
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<url.length; 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.不安全随机数

标准的伪随机数值生成器不能抵挡各种加密攻击。伪随机数生成器 (PRNG) 近似于随机算法,是统计学的 PRNG,该PRNG是可移植和可重复的,攻击者很容易猜到其生成的字符串。 在对安全性要求较高的环境中,使用能够生成可预测值的函数作为随机数据源,会产生 Insecure Randomness 错误。

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<url.length; 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, "");
}

  

 

免责声明:文章转载自《Fortify漏洞修复总结》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇spring自动识别数据库并切换数据源MAC终端中tree命令下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

天龙八部源码描述

天龙八部(武侠世界)的源码很可能是天龙八部代码流出后改写的,因为在看了代码中可以找到一些证据,整个客户端分为:一个是编辑器,一个是客户端,采用OGRE+cegui+自写的简单的物理碰撞检测+FMOD+自写的网络库。 服务器端代码目前没仔细关注 客户端总体的描述如下: UI系统 CEGUI UI基础系统 CEGUI渲染器 Expat XML解析器 CEGUI...

使用zabbix监控oracle数据库

使用zabbix监控oracle数据库  一、概述 zabbix是一款非常强大,同时也是应用最为广泛的开源监控软件,本文将给大家介绍如何利用zabbix+python监控oracle数据库。 二、环境介绍 以下是我安装的环境,实际部署时并不需要跟我的环境一样。 1. 监控机 Redhat Linux 6.5 + Zabbix server 3.4.10...

Bootstrap3入门

Bootstrap3学习第一轮(入门)前言 在上一节中http://www.cnblogs.com/aehyok/p/3381651.html主要是简单的介绍了一下Bootstrap。从http://www.bootcss.com/中文网不难发现现在是针对两个版本进行文档说明,看来两个版本的差别还是蛮大的。 不过从Visual Studio 2013前不...

原生JS实现ajax与ajax的跨域请求

一、原生JS实现ajax 第一步获得XMLHttpRequest对象 第二步:设置状态监听函数 第三步:open一个连接,true是异步请求 第四部:send一个请求,可以发送一个对象和字符串,不需要传递数据发送null 第五步:在监听函数中,判断readyState=4&&status=200表示请求成功 第六步:使用responseTe...

shell 脚本之set 命令(转)

服务器的开发和管理离不开 Bash 脚本,掌握它需要学习大量的细节。 set命令是 Bash 脚本的重要环节,却常常被忽视,导致脚本的安全性和可维护性出问题。本文介绍它的基本用法,让你可以更安心地使用 Bash 脚本。 一、简介 我们知道,Bash 执行脚本的时候,会创建一个新的 Shell。 $ bash script.sh 上面代码中,scrip...

【转】linux 定时执行shell脚本

在oracle 中可以利用dbms_job包定时执行pl/sql、sql过程,在像备份等需要在操作系统级定时任务只能采用crontab来完成 本文讲述crontab具体用法,以供备忘. 在oracle 中可以利用dbms_job包定时执行pl/sql、sql过程,在像备份等需要在操作系统级定时任务只能采用crontab来完成 利用crontab来定时执行任...