SQL - Injection(注入)

SQL - Injection(注入) 首页 / SQL入门教程 / SQL - Injection(注入)

如果您通过网页输入用户输入并将其插入到SQL数据库中,则可能会遇到因 SQL注入而引起的安全问题。本章将教您如何防止这种情况的发生,并帮助您保护服务器端脚本(如PERL脚本)中的脚本和SQL语句。

在下面的示例中,名称限于字母数字字符加下划线,并且长度介于8到20个字符之间(根据需要修改这些规则)。

if (preg_match("/^\w{8,20}$/", $_GET['username'], $matches)) {
   $result=mysql_query("SELECT * FROM CUSTOMERS 
      WHERE name=$matches[0]");
} else {
   echo "user name not accepted";
}

为了演示问题,请考虑以下摘录-

//supposed input
$name="Qadir'; DELETE FROM CUSTOMERS;";
mysql_query("SELECT * FROM CUSTOMSRS WHERE name='{$name}'");

该函数调用应该从CUSTOMERS表中检索一条记录,其中name列与用户指定的名称匹配。在正常情况下, $name 仅包含字母数字字符,可能还包含空格,如字符串ilia。但是在这里,通过在$name后面附加一个全新的查询,对数据库的调用变成了灾难,注入的DELETE查询将从CUSTOMERS表中删除所有记录。

幸运的是,如果使用MySQL,则 mysql_query()函数不允许查询堆栈或在单个函数调用中执行多个SQL查询,如果您尝试堆叠查询,则调用将失败。

但是,其他PHP数据库扩展(如 SQLite 和 PostgreSQL )执行了堆栈查询,执行了一个字符串中提供的所有查询,并造成了严重的安全问题。

防止SQL注入

您可以使用PERL和PHP等脚本语言来巧妙地处理所有转义字符,PHP的MySQL扩展提供了 mysql_real_escape_string()函数,以转义MySQL特有的输入字符。

if (get_magic_quotes_gpc()) {
   $name=stripslashes($name);
}
$name=mysql_real_escape_string($name);
mysql_query("SELECT * FROM CUSTOMERS WHERE name='{$name}'");

LIKE 语句

为了解决LIKE难题,自定义转义机制必须将用户提供的'%'和'_'字符转换为文字。使用 addcslashes(),该函数可让您指定要转义的字符范围。

$sub=addcslashes(mysql_real_escape_string("%str"), "%_");
//$sub ==\%str\_
mysql_query("SELECT * FROM messages 
   WHERE subject LIKE '{$sub}%'");

祝学习愉快!(内容编辑有误?请选中要编辑内容 -> 右键 -> 修改 -> 提交!)

技术教程推荐

数据结构与算法之美 -〔王争〕

代码精进之路 -〔范学雷〕

算法面试通关40讲 -〔覃超〕

Go语言从入门到实战 -〔蔡超〕

趣谈Linux操作系统 -〔刘超〕

手把手教你玩音乐 -〔邓柯〕

恋爱必修课 -〔李一帆〕

业务开发算法50讲 -〔黄清昊〕

超级访谈:对话道哥 -〔吴翰清(道哥)〕

好记忆不如烂笔头。留下您的足迹吧 :)