PHP+MySQL防止注入式攻击

防止你的网站被注入式攻击的第一步是理解什么是注入式攻击。一个注入式攻击是网站的某个访客在你的网站输入表单中输入了某种内容,试图改变你的MySQL查询本意。例如,某些人可能会在登陆窗口使用这种方法绕开登陆。如果你的查询用户名和密码的形式类似这样子:
[code=’sql’]
SELECT * FROM users WHERE username = {username} AND
password = {password }
[/code]
那么用户可以使用任意的用户名,使用这个密码:
[code=’sql’]’ OR ”=”[/code]
从而使得你的验证用户名密码的MySQL查询变成:
[code=’sql’]
SELECT * FROM users WHERE username = ‘anyuser’ AND
password = ” OR ”=”
[/code]
由于空串总是等于空串,所以查询条件永真。因此可以看到,MySQL注入的风险还是很大的,因为攻击者可以看到那些本来应该通过登陆才能访问的数据。防止你的网站受到注入式攻击是非常重要的。幸运的是,PHP可以帮助我们防止注入式攻击。
MySQL将会返回表中的所有行,根据你的程序逻辑,可能会导致全部用户都登陆了,因为他们都被匹配到了。现在,大部分情况下,人们会打开magic_quotes_gpc选项(也是PHP的默认情况),这样的配置将会自动添加反斜线,转义全部'(单引号),”(双引号),\(反斜线)和空字符。但事情并不是这么简单就能解决,因为并不是所有的会导致风险的字符都被转义了。PHP有一个函数可以转义全部可能带来多余SQL子句的MySQL字符。这个函数就是mysql_real_escape_string()
使用这个函数的时候要小心,因为你可能已经打开了magic_quotes_gpc选项,这时候使用mysql_real_escape_string()会导致第二次转义。下面这个函数避免了这个问题,首先判断
magic_quotes_gpc选项是否打开,然后再决定是否执行mysql_real_escape_string()
[code=’php’]

[/code]
需要注意的是,quote_smart()函数会自动给字符串加引号,因此你不需要自己加。
另外需要注意,因为不同的MySQL版本对于过滤的要求不一样,mysql_real_escape_string()需要一个MySQL连接才能工作,因此必须第二个参数传入一个MySQL连接。在本机安装MySQL的情况,可以省略,但是如果本机没有装MySQL,或者远程连接到MySQL,则这个参数必不可少,否则mysql_real_escape_string()将返回一个空字符串。
如果你有任何疑问,可以在下面评论,我们一起讨论。

发表评论