关于CI xss进攻和sql注入的防范问题
XSS过滤
输入类可以自动的对输入数据进行过滤,来阻止跨站脚本攻击。如果你希望在每次遇到 POST 或 COOKIE 数据时自动运行过滤,你可以在 application/config/config.php 配置文件中设置如下参数:
$config['global_xss_filtering'] = TRUE;
或者自动设置get和post方法的第二个参数为true,则对输入的参数进行XSS过滤,注意只是XSS过滤,并不会对SQL注入进行有效的防范。
$this->input->post("userName",TRUE);
防SQL注入
防SQL注入的原理主要是过滤判断条件(WHERE或LIKE)中字段的特殊字符(',\,%,_.....等),在特殊字段前加上转义字符等操作,使数据库能正常执行SQL,不会发生DatabaseError的问题
1、数字类型数组可以通过判断是否是数字和位数进行筛选,避免执行到数据库那里遇到问题
2、如果是纯字符串不需要特殊字符插库的话,可以判断如果有特殊字符的话就不继续执行,避免执行到数据库那里遇到问题
3、如果执行到数据库这里,需要对判断条件的字段进行过滤转义
这里说一下CI框架中转义的方式:
1、直接使用CI的AR(Active Record)的数据库CURD方式去处理
(1)、插入:$this->db->insert("tableName",$insertArray);
(2)、删除:$this->db->where("id",$id)->delete("tableName");
(3)、更新:$this->db->where("id",$id)->update("tableName",$updateArray);
(4)、查询:$this->db->where("id",$id)->select("id,name,age")->get("tableName");
*这里有个细节需要get一下,where里面写sql自定义字符串时(下面的第4种方式),如where("id = '{$id}'"),where这一块并不算是AR类的操作,换言之也就是不会自动进行过滤转义的
*下面的4方式,自定义字符串方式虽然不是AR类写法,不支持自动过滤转义,但是可以支持where中写or的写法,相对灵活,如果遇到有or的情况,需要在那之前把判断的字段先转义过来,不管是用CI自己的方式(详见最下方的转义查询),还是自己封好的demo函数都可以
-
简单的 key/value 方式:
$this->db->where('name', $name); // Produces: WHERE name = 'Joe'
注意自动为你加上了等号。
如果你多次调用该方法,那么多个 WHERE 条件将会使用 AND 连接起来:
$this->db->where('name', $name); $this->db->where('title', $title); $this->db->where('status', $status); // WHERE name = 'Joe' AND title = 'boss' AND status = 'active'
-
自定义 key/value 方式:
为了控制比较,你可以在第一个参数中包含一个比较运算符:
$this->db->where('name !=', $name); $this->db->where('id <', $id); // Produces: WHERE name != 'Joe' AND id < 45
-
关联数组方式:
$array = array('name' => $name, 'title' => $title, 'status' => $status); $this->db->where($array); // Produces: WHERE name = 'Joe' AND title = 'boss' AND status = 'active'
你也可以在这个方法里包含你自己的比较运算符:
$array = array('name !=' => $name, 'id <' => $id, 'date >' => $date); $this->db->where($array);
-
自定义字符串:
你可以完全手工编写 WHERE 子句:
$where = "name='Joe' AND status='boss' OR status='active'"; $this->db->where($where);
转义查询
在提交数据到你的数据库之前,确保先对其进行转义是个非常不错的做法。 CodeIgniter 有三个方法来帮你做到这一点:
-
$this->db->escape() 这个函数会检测数据类型,仅转义字符串类型的数据。 它会自动用单引号将你的数据括起来,你不用手动添加:
$sql = "INSERT INTO table (title) VALUES(".$this->db->escape($title).")";
-
$this->db->escape_str() 这个函数忽略数据类型,对传入的数据进行转义, 这个方法并不常用,一般情况都是使用上面的那个方法。方法的使用代码如下:
$sql = "INSERT INTO table (title) VALUES('".$this->db->escape_str($title)."')";
- $this->db->escape_like_str() 这个函数用于处理 LIKE 语句中的字符串,
-
这样,LIKE 通配符('%', '_')可以被正确的转义。
$search = '20% raise';
$sql = "SELECT id FROM table WHERE column LIKE '%" .
$this->db->escape_like_str($search)."%' ESCAPE '!'";
*转义这里有一点需要get下,$this->db->escape()在使用这个函数之后,变量会自动在两侧加上单引号'',同时也会在里面进行自动的过滤
*比如会把abc变成'abc' , 也会把a'bc变成'a\'bc'的,所以在写进where的sql自定义字符串中时,就不要再加单引号了,那样就会有两个单引号在变量外边(''abc'')
*$this->db->escape_str()在使用这个函数之后,变量不会自动在两侧加上单引号'',只会在里面进行自动的过滤
*比如会把abc还是abc , 也会把a'bc变成a\'bc的,所以在写进where的sql自定义字符串中时,和以前用法是一样的