首页 > 代码库 > php 防止sql注入

php 防止sql注入

Q:如果把用户输入的没有任何改动的放到SQL的查询语句中,很有可能会导致SQL注入,比如说下面的例子:

$unsafe_variable = $_POST[‘user_input‘]; mysql_query("INSERT INTO `table` (`column`) VALUES (‘$unsafe_variable‘)");

为什么会有注入漏洞呢?因为用户可以输入value‘); DROP TABLE table;-- 然后查询语句就变成了这样

INSERT INTO `table` (`column`) VALUES(‘value‘); DROP TABLE table;--‘)

 

A:通过使用预编译语句(prepared statements)和参数化查询(parameterized queries)。

有两种方式去完成这个:

1. 使用PDO对象(对于任何数据库驱动都好用)$stmt = $pdo->prepare(‘SELECT * FROM employees WHERE name = :name‘);$stmt->execute(array(‘name‘ => $name));
2. 使用MySqli$stmt = $dbConnection->prepare(‘SELECT * FROM employees WHERE name = ?‘);$stmt->bind_param(‘s‘, $name);$stmt->execute(); 

================

通常有一下几种方法:

(1)输入验证和过滤
(2)预处理Sql语句
(3)采用存储过程
(4)输入白名单
(5)一般的简单过滤,直接用php的addslashes函数即可。

全面防注入:

function inject_check($sql_str) { return eregi(‘select|insert|update|delete|\‘|\/\*|\*|\.\.\/|\.\/|union|into|load_file|outfile‘, $sql_str);  // 进行过滤}function verify_id($id=null) { if (!$id) { exit(‘没有提交参数!‘); }  // 是否为空判断 elseif (inject_check($id)) { exit(‘提交的参数非法!‘); }  // 注射判断 elseif (!is_numeric($id)) { exit(‘提交的参数非法!‘); }  // 数字判断 $id = intval($id);  // 整型化 return $id;}

function str_check( $str ) { if (!get_magic_quotes_gpc()) { // 判断magic_quotes_gpc是否打开 $str = addslashes($str); // 进行过滤 } $str = str_replace("_", "\_", $str); // 把 ‘_‘过滤掉 $str = str_replace("%", "\%", $str); // 把 ‘%‘过滤掉 return $str;}

function post_check($post) { if (!get_magic_quotes_gpc()) { // 判断magic_quotes_gpc是否为打开 $post = addslashes($post); // 进行magic_quotes_gpc没有打开的情况对提交数据的过滤 } $post = str_replace("_", "\_", $post); // 把 ‘_‘过滤掉 $post = str_replace("%", "\%", $post); // 把 ‘%‘过滤掉 $post = nl2br($post); // 回车转换 $post = htmlspecialchars($post); // html标记转换 return $post;}

 

    /**     * 转义需要插入或者更新的字段值     *     * 在所有查询和更新的字段变量都需要调用此方法处理数据     *     * @param mixed $str 需要处理的变量     * @return mixed 返回转义后的结果     */    public function escape($str) {        if (is_array($str)) {            foreach ($str as $key => $value) {                $str[$key] = $this->escape($value);            }        } else {            return addslashes($str);        }        return $str;    }

使用实例:

public function _saveWithWhere($tableName, $row, $where, $sync = false) {        // 生成要插入/更新的字段的SQL字符串        $values = ‘‘;        foreach ($row as $searchKey => $val) {            $values .= "`{$searchKey}` = ‘{escape($val)}‘,";        }        $values = trim($values, ",");        // 有itemId的话就UPDATE没有的话就INSERT        if (trim($where)) {            $sql = "UPDATE {$tableName} SET {$values} WHERE {$where} ";        }else {            $sql = "INSERT INTO {$tableName} SET {$values}";        }          $this->saveLog($sql);        // lib_DB->update 只返回  boolean 当 insert 的时候需要获取 last_id 就不行        return $this->_update($sql, $sync);    }

其他重要:

1. http://stackoverflow.com/questions/60174/how-can-i-prevent-sql-injection-in-php

 

php 防止sql注入