放牧代码和思想
专注自然语言处理、机器学习算法
    愛しさ 優しさ すべて投げ出してもいい

addslashes_deep防注入补丁

addslashes_deep负责对用户提交的数据进行转义,以防SQL注入,然而分析addslashes_deep函数后我们就可以发现,该函数只处理数组的值,对数组的key是完全不作任何过滤的,这直接导致了漏洞。

一个漏洞示例:

<?php
include_once '../krumo/class.krumo.php';
header("Content-type: text/html; charset=utf-8");
// krumo::backtrace();
 
/**
 * 递归方式的对变量中的特殊字符进行转义
 *
 * @access  public
 * @param   mix     $value
 *
 * @return  mix
 */
function addslashes_deep($value)
{
    if (empty($value))
    {
        return $value;
    }
    else
    {
        return is_array($value) ? array_map('addslashes_deep', $value) : addslashes($value);
    }
}
 
/**
 * 将对象成员变量或者数组的特殊字符进行转义
 *
 * @access   public
 * @param    mix        $obj      对象或者数组
 * 
 *
 * @return   mix                  对象或者数组
 */
function addslashes_deep_obj($obj)
{
    if (is_object($obj) == true)
    {
        foreach ($obj AS $key => $val)
        {
            if ( ($val) == true)
            {
                $obj->$key = addslashes_deep_obj($val);
            }
            else
            {
                $obj->$key = addslashes_deep($val);
            }
        }
    }
    else
    {
        $obj = addslashes_deep($obj);
    }
 
    return $obj;
}
 
/**
 * 递归方式的对变量中的特殊字符去除转义
 *
 * @access  public
 * @param   mix     $value
 *
 * @return  mix
 */
function stripslashes_deep($value)
{
    if (empty($value))
    {
        return $value;
    }
    else
    {
        return is_array($value) ? array_map('stripslashes_deep', $value) : stripslashes($value);
    }
}
 
echo '原来的线性数组:<br>';
$arr = array('I\'m hankcs');
krumo($arr);
echo '转义后:<br>';
krumo(addslashes_deep($arr));
 
echo '假如使用k-v数组:<br>';
$arr = array('I\'m hankcs' => 'but who\'re you?');
krumo($arr);
echo '转义后:<br>';
krumo(addslashes_deep($arr));

结果I'm hankcs中的'根本没有被转义!

一个可用的修正补丁:

<?php
include_once '../krumo/class.krumo.php';
header("Content-type: text/html; charset=utf-8");
// krumo::backtrace();
 
/**
 * 递归方式的对变量中的特殊字符进行转义
 *
 * @access  public
 * @param   mix     $value
 * @author  hankcs
 *
 * @return  mix
 */
function addslashes_deep($value)
{
    if (empty($value))
    {
        return $value;
    }
     
    if(is_array($value))
    {
        foreach((array)$value as $k=>$v)
        {
            unset($value[$k]);
            $k = addslashes($k);
            if(is_array($v))
                $value[$k] = addslashes_deep($v);
            else
                $value[$k] = addslashes($v);
        }
    }
    else
    {
        $value = addslashes($value);
    }
    return $value;
}  
 
/**
 * 将对象成员变量或者数组的特殊字符进行转义
 *
 * @access   public
 * @param    mix        $obj      对象或者数组
 * @author   hankcs
 *
 * @return   mix                  对象或者数组
 */
function addslashes_deep_obj($obj)
{
    if (is_object($obj) == true)
    {
        foreach ($obj AS $key => $val)
        {
            if ( ($val) == true)
            {
                $obj->$key = addslashes_deep_obj($val);
            }
            else
            {
                $obj->$key = addslashes_deep($val);
            }
        }
    }
    else
    {
        $obj = addslashes_deep($obj);
    }
 
    return $obj;
}
 
/**
 * 递归方式的对变量中的特殊字符去除转义
 *
 * @access  public
 * @param   mix     $value
 *
 * @return  mix
 */
function stripslashes_deep($value)
{
    if (empty($value))
    {
        return $value;
    }
     
    if(is_array($value))
    {
        foreach((array)$value as $k=>$v)
        {
            unset($value[$k]);
            $k = stripslashes($k);
            if(is_array($v))
            {
                $value[$k] = stripslashes_deep($v);
            }
            else
            {
                $value[$k] = stripslashes($v);
            }
        }
    }
    else
    {
        $value = stripslashes($value);
    }
    return $value;
}
 
echo '原来的线性数组:<br>';
$arr = array('I\'m hankcs');
krumo($arr);
echo '转义后:<br>';
krumo(addslashes_deep($arr));
 
echo '假如使用k-v数组:<br>';
$arr = array('I\'m hankcs' => 'but who\'re you?');
krumo($arr);
echo '转义后:<br>';
krumo(addslashes_deep($arr));
 
echo '使用obj转义:';
krumo(addslashes_deep_obj($arr));
 
echo '先转义再还原:';
krumo(stripslashes_deep(addslashes_deep($arr)));

结果正常,至于还有没有潜在的问题,就交给屏幕前的你帮忙测试吧。

知识共享许可协议 知识共享署名-非商业性使用-相同方式共享码农场 » addslashes_deep防注入补丁

评论 1

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
  1. #1

    请问大侠用这个函数干什么?

    浴火凤凰9年前 (2015-02-07)回复

我的作品

HanLP自然语言处理包《自然语言处理入门》