PHP mysql_query SQL 注入预防措施

文章目录

    目前维护的一套 ecshop 系统,由于使用的是 PHP 5.2 加之历史遗留代码安全意识淡薄,所以存在诸多 SQL 注入的隐患(大量拼接 SQL 字符串的行为)。而我入门 PHP 是通过 Laravel 官方教程开始的,没有写过原生 PHP SQL 查询,对如何规避 SQL 注入一无所知。

    首先看一下 PHP 官方文档

    mysql_query — Send a MySQL query

    This extension was deprecated in PHP 5.5.0, and it was removed in PHP 7.0.0. Instead, the MySQLi or PDO_MySQL extension should be used. See also MySQL: choosing an API guide and related FAQ for more information. Alternatives to this function include: mysqli_query() PDO::query()

    原来 mysql_query 已经被 PHP 7 所抛弃,甚至 PHP 5.6 都不支持。但是在将 ecshop 改造支持 PHP 7 之前,还是有必要了解一下 PHP 5.2 下如何规避 SQL 注入。

    使用 sprintf 规避拼接 SQL 字符串

    $query = sprintf("SELECT * FROM users WHERE user='%s' AND password='%s'",
                mysql_real_escape_string($user),
                mysql_real_escape_string($password));
    

    sprintf - Returns a string produced according to the formatting string format.

    同时使用 mysql_real_escape_string 将单引号转义。

    规避 SQL LIKE 引起的注入

    mysql_real_escape_string() does not escape % and _. These are wildcards in MySQL if combined with LIKE, GRANT, or REVOKE.

    使用 mysql_real_escape_string 无法转义 %, 所以在 LIKE 操作时,依然会留有安全隐患。正确的做法是

    $search = mysql_real_escape_string($search);
    $search = addcslashes($search, "%_");
    

    函数说明

    string addcslashes ( string $str , string $charlist ) - Returns a string with backslashes before characters that are listed in charlist parameter.

    封装,让使用更简单

    把这两种情况封装成了一个函数

    function sql_escape($param, $is_like_param = false) {
    	$param = mysql_real_escape_string($param);
    	if ($is_like_param) {
    		$param = addcslashes($param, "%_");
    	}
    
    	return $param;
    }
    

    参考

    • http://php.net/manual/en/function.mysql-real-escape-string.php
    • http://stackoverflow.com/questions/3683746/escaping-mysql-wild-cards
    • http://www.webappsec.org/projects/articles/091007.txt
    • http://stackoverflow.com/questions/2190737/what-is-the-difference-between-mysql-mysqli-and-pdo
    • PDO 教程
    • 淺談 PHP-MySQL, PHP-MySQLi, PDO 的差異

    关于作者 🌱

    我是来自山东烟台的一名开发者,有感兴趣的话题,或者软件开发需求,欢迎加微信 zhongwei 聊聊,或者关注我的个人公众号“大象工具”, 查看更多联系方式