SQL中的安全问题
1.SQL注入
demo1:
SELECT * FROM user WHERE username = ? AND password = ? ;
http://127.0.0.1/injection/user.do?username=angel' or '1=1
http://127.0.0.1/injection/user.do?username=angel'/*
http://127.0.0.1/injection/user.do?username=angel'#
其中 or 1=1 保证sql为真;而 /* 以及 # 会将后面的SQL注释掉,使得SQL也为真,导致SQL没有起到需要密码的目的,将数据返回.
2.开发时,防止SQL注入
a.使用Java , JSP进行开发时,应采用PrepareStatement + Bind-variable方式防止SQL注入.
尽量不要使用拼接SQL的方式.
demo :
...
String sql = "SELECT * FROM users u where u.id = ? and u.password = ?";
PrepareStatement ps = connection.prepareStatement(sql);
ps.setInt(1,id);
ps.setString(2.pwd);
ResultSet rs = ps.executeQuery();
...
b,使用应用程序提供的转换函数
略,这里没有提到 java 相关的api .
c.自定义函数 进行校验
输入验证的途径可以分为以下几种:
整理数据使之变得有效;
拒绝已知的非法输入;
只接受已知的合法输入;
目前最好的办法就是对用户提交或者可能改变的数据进行简单分类,分别应用正则表达式来对用户提供的输入数据进行严格的检测和验证.
已知非法的字符有 :
' ,
; ,
= ,
( ,
) ,
/* ,
*/ ,
% ,
+ ,
空字符串 ,
> , < , -
- , [ ,
]
同时要过滤它们的十六进制表示"%XX",由此可以构造如下正则表达式:
(|\'|(\%27)|\;|(\%3b)|\=|(\%3d)|\(|(\%28)|\)|(\%29)|(\/*)|(\%2f%2a)|(\*/)|(\%2a%2f)|\+|(\%2b)|\<|(\%3c)|\>|(\%3e)|\(--))|\[|\%5b|\]|\%5d)