用户
 找回密码
 入住 CI 中国社区
搜索
查看: 11644|回复: 15
收起左侧

[原创]CodeIgniter 的数据安全过滤全解析,让你的系统坚如坦克

[复制链接]
发表于 2009-9-22 17:32:35 | 显示全部楼层 |阅读模式
原文发在我的博客 http://www.mb120.com/blog/?p=1174
不知道这东东怎么代码高亮。
PS:N早前我被HEX老大请出群了。。

由于对CI的SQL安全这些不放心,今天寡人啃了一下午的代码,算是对其机制比较了解了,为了让各位兄弟姐妹少走弯路,特将战果公布,希望大家喜欢。
1.无论如何在获取参数之时都建设将 xss过滤打开,比如 $this->input->get('username',true); 其中的true就代表打开了 xss
2.不要直接使用$_GET等类似方式获得数据,如果这样获取数据的话将不会被xss过滤
3.CI的数据在入库之前不仅不会增加转义字符,而且还会取消它 比如 Input.php 里面的这么一段
PHP复制代码
        // We strip slashes if magic quotes is on to keep things consistent
        if (get_magic_quotes_gpc())
        {
            $str = stripslashes($str);
        }
复制代码

        
4.如果你使用 $this->db->query('YOUR QUERY HERE'); 直接查询数据库,那么你需要使用 $this->db->escape('fileld_name') 语句进行转义,这样才安全。
    escape函数实际上是调用的escape_str这个函数,只不过escape增加了一层对数据类型的判断,看到了没(注意:它可没判断数值类型的哟,所以说如果传入的数据是数值型的话,你得自己动手判断一下了),下面这两个东东就是进行转义的家伙了。
PHP复制代码
    function escape($str)
    {
        if (is_string($str))
        {
            $str = "'".$this->escape_str($str)."'";
        }
        elseif (is_bool($str))
        {
            $str = ($str === FALSE) ? 0 : 1;
        }
        elseif (is_null($str))
        {
            $str = 'NULL';
        }
 
        return $str;
    }
   
    function escape_str($str, $like = FALSE)    
    {    
        if (is_array($str))
        {
            foreach($str as $key => $val)
               {
                $str[$key] = $this->escape_str($val, $like);
               }
           
               return $str;
           }
 
        if (function_exists('mysql_real_escape_string') AND is_resource($this->conn_id))
        {
            $str = mysql_real_escape_string($str, $this->conn_id);
        }
        elseif (function_exists('mysql_escape_string'))
        {
            $str = mysql_escape_string($str);
        }
        else
        {
            $str = addslashes($str);
        }
       
        // escape LIKE condition wildcards
        if ($like === TRUE)
        {
            $str = str_replace(array('%', '_'), array('\\%', '\\_'), $str);
        }
       
        return $str;
    }
复制代码

   
5.无论如何你都必须要对数值型数据手动判断,这个得你自己做,比如用个 (int)之类的强制转换。
   
6. 对于使用 Active Record 操作的数据你可以偷懒不用 $this->db->escape('fileld_name') 转义了(事实上你如果你使用了反而会被多增加些引号之类的东西),因为它会帮你搞定,但数值型你还是要自己判断。

7. 如果你使用 Active Record 操作的数据,那么其实CI是在数据快要入数据库的时候进行转义的,所以在前面的很多地方你都看不到addslashes之类函数的身影,这样做也是有好处的你看看escape_str函数里对转义函数的判断就知道了。

8.上面我一再强调数值型数据必须得自己搞定,实际上如果你的SQL语句中对数值型加了单引号的话,应该问题不大,不过还是建议处理一下,宁可错杀,不要放过啊!!!兄弟们,姐妹们。

9. 还没想起,差不多了,寡人深信,如果你能做到上面所讲的,那就应该比坦克还保险。

10. 再次感谢 CCTV MTV XXXXXV

评分

参与人数 1威望 +5 收起 理由
Hex + 5 原创内容

查看全部评分

发表于 2009-9-22 18:01:35 | 显示全部楼层
我小白,请问数值型数据为什么要加单引号? 通过数值他怎么黑我?
发表于 2009-9-22 18:02:42 | 显示全部楼层
6. 对于使用 Active Record 操作的数据你可以偷懒不用 $this->db->escape('fileld_name') 转义了(事实上你如果你使用了反而会被多增加些引号之类的东西),因为它会帮你搞定,但数值型你还是要自己判断。
Jack 发表于 2009-9-22 17:32


看来我要把代码重新写一下,我都是用 $this->db->query('YOUR QUERY HERE')直接查的
 楼主| 发表于 2009-9-22 18:13:02 | 显示全部楼层
我小白,请问数值型数据为什么要加单引号? 通过数值他怎么黑我?
testabc111 发表于 2009-9-22 18:01


你去查下sql注入的东东就明白了。
发表于 2009-9-22 19:51:12 | 显示全部楼层
顶,这文章分析的很清楚啊!

PS: 因为什么把楼主请出去的啊?呵呵
 楼主| 发表于 2009-9-22 20:06:42 | 显示全部楼层
可能是时间长了没发言了吧。
发表于 2009-9-22 20:15:35 | 显示全部楼层
可能是时间长了没发言了吧。
Jack 发表于 2009-9-22 20:06

呵呵,原来是这样啊,那还得请楼主多谅解,毕竟群人数有限,并且非常欢迎楼主再次加入群!
 楼主| 发表于 2009-9-23 11:29:19 | 显示全部楼层
群号是多少哟!
发表于 2009-9-23 15:05:30 | 显示全部楼层
我也想加入群。。。。
发表于 2009-9-23 15:31:38 | 显示全部楼层

本版积分规则