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

  

最新文章

  1. 6.Swift协议|扩展|访问权限|异常调试|类型转换|运算函数|ARC|类类型初试化器|值类型初始化器
  2. Json与javaBean之间的转换工具类
  3. 【LintCode】计算两个数的交集(二)
  4. UVa 11889 Benefit(数论)
  5. How to read a scientific paper
  6. Appium+Robotframework实现Android应用的自动化测试-2:Windows中启动Appium和模拟器
  7. python学习笔记:文件操作和集合(转)
  8. Entity Framework 4 数据事务操作
  9. 《驾驭Core Data》 第三章 数据建模
  10. java中的trim()
  11. php中的 == 和 ===
  12. 【HDOJ】5632 Rikka with Array
  13. 自定义android精美聊天界面
  14. PDCA模型的学习
  15. libJPEG-turbo库使用示例代码
  16. 【转】JS中setTimeout和setInterval的最大延时值详解
  17. Coablt strike官方教程中文译版本
  18. 初识数据库、初识MySQL
  19. MySQL 之 MySQL数据库的优化
  20. 04_web基础(八)之车票实现增删改查初级版本

热门文章

  1. EMCAscript6随心所记
  2. C#读取Txt大数据并更新到数据库
  3. vscode保存代码,自动按照eslint规范格式化代码设置
  4. FastStone Capture(FSCapture) 注册码
  5. css3弹性盒子 flex布局
  6. Ribbon实现客户端负载均衡
  7. 【阿里云IoT+YF3300】5. Alink物模型之服务下发
  8. 怎样用QT在windows环境通过编程卸载installShield打包的程序
  9. Java内部类使用注意事项
  10. Js 组合键