1、在书写SQL语句时不要省略单引号,即使是整型字段也应该加上单引号。
首先,从技术上讲,引号对于数字值来说是不需要使用的。但是,假如你不使用引号把例如书籍数量这样的一个值括起来,并且假如你的用户把一个空值输入到你的表单中,那么,你将会看到一个类似下面的查询:
SELECT * FROM books WHERE num =
当然,这个查询从语法上讲是无效的;但是,下面的语法却是有效的:
SELECT * FROM books WHERE num = ''
第二个查询虽然也不会返回任何结果,但是至少它不会返回一个错误消息。
其次,单引号可以增加注入者的难度,第二句由于把变量放在一对单引号中,这样使得我们所提交的变量都变成了字符串,即使包含了正确的SQL语句,也不会正常执行,而第一句不同,由于没有把变量放进单引号中,那我们所提交的一切,只要包含空格,那空格后的变量都会作为SQL语句执行,因此,我们要养成给SQL语句中变量加引号的习惯。
2、检查用户提交的值的类型,对接收到的整型参数使用intval()强制转换成整形。
我们知道SQL注入的主要来源往往出在一个意料之外的表单提交或URL参数中,所以当你接受一个由用户提交的参数时,你应该有相当的权利来确定你想取得什么样的输入内容。在以前的学习中我们已经讨论过很多这样或那样的校验问题。因此我们只要简单的总结当时我们讨论的要点即可比较轻易的检查用户提交数据的有效性。假如你期望得到的是一个数值,那么你可以使用下面这些技术之一来确保你得到的参数的安全性。
使用is_int()函数(或is_integer()或is_long())。
使用gettype()函数。
使用intval()函数。
使用settype()函数。
我们通常把传送过来的整型参数使用intval()函数强制转换成整形,因为假如不这样做,接收到的查询子句很可能会附带着其它一些我们并不愿看到的语句,比如原本应该是“nid=17”可能会成为“nid=17 or 1=1”,这会使我们预计的SQL语句变成这样:
SELECT * FROM news WHERE nid=17 or 1=1
这对于一个新闻表中的信息可能不会造成什么大的危害,但假如是在显示某个用户的信息时呢?
此外,为了检查用户输入内容的长度,你可以使用strlen()函数。为了检查一个期望的时间或日期是否有效,你可以使用strtotime()函数。它似乎一定能够确保一位用户的提交参数中没有包含分号字符(除非标点符号可以被合法地包括在内)。你可以借助于strpos()函数轻易地实现这一点,如下所示:
if( strpos( $variety, ';' ) ) exit ( "$variety is an invalid value for variety!" );
正如我们在前面所提到的,只要你仔细分析你的用户输入期望,那么,你应该能够很轻易地检查出其中存在的许多问题。