很多 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;
}
}
?>