SQL注入漏洞
SQL注入漏洞产生原因及危害在sql查询中很多程序员会将变量拼接入sql语句后再进行查询,这样如果黑客在参数中插入其他sql语句就可能导致我们网站的密码被被黑客查询出来或者被拖取大量数据,如果在开发中使用了字符串拼接进SQL语句就必须进行严格的过滤,任何用户输入的内容都不可信任,以下列举几种防御方法。数字型查询注入防护
查询例子如下
id=_GET[id];
sql=SELECT*FROMtableWHEREid=id;
conn-query(sql);
如果是这样的数字型注入我们可以强制将传入参数转换为整数,以剔除黑客拼接的SQL语句。修改如下
id=intval(_GET[id]);
sql=SELECT*FROMtableWHEREid=id;
conn-query(sql);
这是这个网页正常查询的返回的结果。
这是一个典型的数字型注入,我们输入注入语句可见注入成功
我们强制转换类型到代码中:
我们再执行注入可以看到恢复正常查询,注入失败。
非数字型注入防护-通用防护
如果查询参数不是数字,那么我们该如何防护呢,那么这里可以使用通用型防护,对数字型和非数字型同样适用,我们知道web中获取参数的方式主要有三种分别是get、post、cookie。那么我们防护的主要方面也是这三个方面,我们可以对网站的所有流量进行黑名单过滤。当然这个也可以拦截xss漏洞。具体流程如下:
具体实现代码:
?php
classWAF{
publicfilter;
publicfunction__construct(){
this-filter=\\.+javascript:window\\[.{1}\\\\x
.*=(#\\d+?;?)+?
.*(data
src)=data:text\\/html.*
\\b(alert\\(
confirm\\(
expression\\(
prompt\\(
benchmark\s*?\(.*\)
sleep\s*?\(.*\)
\\b(group_)?concat[\\s\\/\\*]*?\\([^\\)]+?\\)
\bcase[\s\/\*]*?when[\s\/\*]*?\([^\)]+?\)
load_file\s*?\\()
[a-z]+?\\b[^]*?\\bon([a-z]{4,})\s*?=
^\\+\\/v(8
9)
\\b(and
or)\\b\\s*?([\\(\\)\\\d]+?=[\\(\\)\\\d]+?
[\\(\\)\a-zA-Z]+?=[\\(\\)\a-zA-Z]+?
\s+?[\\w]+?\\s+?\\bin\\b\\s*?\(
\\blike\\b\\s+?[\])
\\/\\*.*\\*\\/
\\s*script\\b
\\bEXEC\\b
UNION.+?SELECT\s*(\(.+\)\s*{1,2}.+?\s*
\s+?.+?
(`
\).*?(`
\)\s*)
UPDATE\s*(\(.+\)\s*{1,2}.+?\s*
\s+?.+?
(`
\).*?(`
\)\s*)SET
INSERT\\s+INTO.+?VALUES
(SELECT
DELETE)
{0,2}(\\(.+\\)\\s+?.+?\\s+?
(`
\).*?(`
\))FROM(\\(.+\\)
\\s+?.+?
(`
\).*?(`
\))
(CREATE
ALTER
DROP
TRUNCATE)\\s+(TABLE
DATABASE)
.*(iframe
frame
style
embed
object
frameset
meta
xml
a
img)
hacker;
}
publicfunctionCheckInject(Value){
if(is_array(Value)){
Value=implode(Value);
}
if(preg_match(/.this-filter./is,Value)==1){
die(非法操作!);
}
}
}
checkhack=newWAF();
foreach(_GETaskey=value){
checkhack-CheckInject(value);
}
foreach(_POSTaskey=value){
checkhack-CheckInject(value);
}
foreach(_COOKIEaskey=value){
checkhack-CheckInject(value);
}
?
测试
同样我们在原先的网站上将我们的waf.php文件包含进去,在执行注入操作,可见我们已经将非法操作拦截。
使用预处理对注入进行防护
PHP预处理查询的例子
//预处理语句,?为绑定的参数
mysql=conn-prepare(INSERTINTOMyGuests(firstname,lastname,email)VALUES(?,?,?));
//绑定参数第一个参数为参数列处理其余参数的数据类型。如下firstname,lastname,email三个变量都为字符串类型所以,第一个参数为sss
mysql-bind_param(sss,firstname,lastname,email);
/*参数1有以下四种类型:
i-integer(整型)
d-double(双精度浮点型)
s-string(字符串)
b-BLOB(布尔值)*/
//下面设置参数并执行
firstname=John;
lastname=Doe;
email=john
example.