文章教程

习题

9/17/2020 9:37:07 PM 人评论 次浏览

9.4 SQL注入

至此用户注册系统的所有功能代码开发完毕,但该系统存在一个bug。当配置文件php.ini中的 magic_quotes_gpc 选项设置为关闭时(magic_quotes_gpc = Off),使用用户名“'or''='”和密码“'or''='”登录系统时,系统永远可以登录成功(如图9-18所示),单击“登录”按钮后,login_process.php程序的运行结果如图9-19所示。

产生bug的原因是,SQL语句中出现特殊字符(例如“"”和“'”等特殊字符)时,没有对这些特殊字符进行适当的转义。当浏览器用户在用户名表单控件处输入“'or''='”,在密码表单控件处输入“'or''='”时,单击登录按钮后,login_process.php程序产生的SQL语句为“select * from users where userName=''or''='' and password=''or''=''”。该SQL语句的where子句永远为TRUE,这是由于“userName=''”的值为FALSE,而“'='”的值为TRUE,“userName=''or''=''”的值为TRUE;“password=''”的值为FALSE,而“'='”的值为TRUE,“password=''or''=''”的值为TRUE。这样一些非法用户就可以乘虚而入,成功登录系统,这就是SQL 注入(SQL Injection)。SQL 注入产生的原因是由于某些特殊字符打乱了SQL语句本身的逻辑,使数据库服务器引擎错误地执行了某些SQL语句。

figure_0203_0273
图9-18 SQL注入
figure_0203_0274
图9-19 SQL注入

MySQL数据库引擎不会自动过滤特殊字符,因此防止SQL注入发生的方法是在PHP程序中过滤特殊字符。以用户注册系统为例,有以下两种解决方案。

方案 1 当配置文件 php.ini 中的 magic_quotes_gpc 选项设置为关闭时(magic_quotes_gpc =Off),使用addslashes()函数将GET或POST提交方式提交的特殊字符转义。

方案2 将配置文件php.ini中的magic_quotes_gpc选项设置为开启(magic_quotes_gpc = On), PHP预处理器会自动将GET或POST提交方式提交的特殊字符转义。

若采用第1种方案,需将login_process.php程序修改为如下代码(粗体字部分为代码的改动部分,其他代码不变)。

<?php

include_once("functions/database.php");

//收集表单提交数据

$userName = addslashes($_POST['userName']);

$password = addslashes($_POST['password']);

//连接数据库服务器

getConnection();

//判断用户名和密码是否输入正确

……

closeConnection();

?>

说明:addslashes()函数的具体用法请参考“字符串处理”章节的内容。

若采用第2种方案,login_process.php程序则无须修改。

教程类别