很多 web 开发者没有注意到 SQL 查询是可以被篡改的,因而把 SQL 查询当作可信任的命令。殊不知道,SQL 查询可以绕开访问控制,从而绕过身份验证和权限检查。更有甚者,有可能通过 SQL 查询去运行主机操作系统级的命令。
直接 SQL 命令注入就是攻击者常用的一种创建或修改已有 SQL 语句的技术,从而达到取得隐藏数据,或覆盖关键的值,甚至执行数据库主机操作系统命令的目的。这是通过应用程序取得用户输入并与静态参数组合成 SQL 查询来实现的。下面将会给出一些真实的例子。
由于在缺乏对输入的数据进行验证,并且使用了超级用户或其它有权创建新用户的数据库帐号来连接,攻击者可以在数据库中新建一个超级用户。
下面分享一个用于防注入的PHP类:
<?php /** * Params Tools * @author JasonWei * @version v2 */ class Params { public $get = array(); public $post = array(); function __construct() { if (!empty($_GET)) { foreach ($_GET as $key => $val) { if (is_array($val)) { $this->get[$key] = $this->getArray($val); } else { if (is_int($val)) { $this->get[$key] = $this->getInt($val); } else { $this->get[$key] = $this->getStr($val); } } } } if (!empty($_POST)) { foreach ($_POST as $key => $val) { if (is_array($val)) { $this->post[$key] = $this->getArray($val); } else { if (is_int($val)) { $this->post[$key] = $this->getInt($val); } else { $this->post[$key] = $this->getStr($val); } } } } } public function getInt($number) { return intval($number); } public function getStr($string) { if (!get_magic_quotes_gpc()) { $string = addslashes($string); } return $string; } private function getArray($array, $max_layer = 32) { foreach ($array as $key => $val) { if (is_array($val)) { $array[$key] = $this->getArray($val); } else { if (is_numeric($val)) { $array[$key] = $this->getInt($val); } else { $array[$key] = $this->getStr($val); } } } return $array; } /** * checkInject 检测传入的字符串是否含有引起SQL注入的字符 * * @param string $string * @return bool */ public function checkInject($string) { return eregi('select|insert|update|delete|\/\*|\*|\.\.\/|\.\/|union|into|load_file|outfile', $string); } public function verifyId($id = null) { if (!$id || $this->checkInject($id) || !is_numeric($id)) { $id = false; } else { $id = intval($id); } return $id; } } ?>