防SQL注入N法.
9 W/ g+ s8 b" q; H" d6 H+ f+ K网站要做足安全, 特别是对防SQL注入, 因为大多数程序员都会很粗心大意而导致网站被黑
6 i& A5 g3 K. L/ H& Hphp脚本:
! t6 @) x3 V0 i3 B/ c t基本上php本身就带有类似功能的函数了, 比如mysql_real_escape_string, addslashes等.
& A& n8 M% S3 Q9 s/ M+ Z8 D大多数虚拟主机商比如耐思尼克(
www.nicenic.com/?s=jiangyanfei)都会开启了magic_quotes_gpc这个选项, 那提交数据时, 会自动执行了addslashes这个函数, 这样就可以杜绝大多数的注入了
, ]# L/ S: G. m: ]
另外因为mysql是不分数字还是文本,都可以用''来括住, 所以建议在写sql的时候, 参数都用''来括起来
2 e% r; w! X( A# E, r2 A1 X
使用方法如下:
! K4 r- _5 ]6 b2 {1 Y* Y
$query = mysql_real_escape_string("SELECT * FROM products WHERE name='$productname'");
2 A, |! ~4 i% {; O
asp脚本:
7 v: ~5 x" D; n5 ^# @" T0 E$ ]' v' xFUNCTION CHECKSTR(ISTR)
) p" d9 I0 T9 O# c1 R/ B
DIM ISTR_FORM,SQL_KILL,SQL_KILL_1,SQL_KILL_2,ISTR_KILL
( }* {+ Q8 I" ~- O/ `, x) f
IF ISTR="" THEN EXIT FUNCTION
; E7 a( n& `& E }- c
ISTR=LCase(ISTR)
" P& p1 q2 D% z" _
ISTR_FORM=ISTR
# [! @( R) K3 s, a% t# ESQL_KILL="'|and|exec|insert
; I, |7 |% w; O; w
|select|delete|update|count|*|%|chr|mid|master|truncate|char|declare|set|;|from|="
* F/ l8 L5 G* E2 W, t$ J' WSQL_KILL_1=SPLIT(SQL_KILL,"|")
( k$ A6 d/ H: Q! lFOR EACH SQL_KILL_2 IN SQL_KILL_1
p+ r. H; A! y; q" l% k
ISTR=REPLACE(ISTR,SQL_KILL_2,"")
' X0 } {! e+ u. k/ m+ L% `, T. n5 N
NEXT
' p+ `( j, q7 c/ F! r3 f$ {
CHECKSTR=ISTR
( q- d! Q8 t ?* f" h8 O! j
ISTR_KILL=REPLACE(ISTR_FORM,ISTR,"")
5 E! I( G( e& ~+ m( QIF ISTR<>ISTR_FORM THEN
2 Q6 ^& j/ U( {* ^& n! X" mRESPONSE.WRITE "<script>alert('警告: 您提交的数据["&ISTR_FORM&"]中含有非法字符 ["&ISTR_KILL&"]');history.back();</Script>"
" j2 b' u3 f' v0 t' FRESPONSE.END
/ Z, ` @) Y& v/ e( ]END IF
5 J i _' R! q/ \; i Z1 z" I- K, qEND FUNCTION
6 l: e% r# B4 X# _) |2 X0 g
C#脚本:
& Z7 E6 O5 o2 k( \ w( N7 X9 M+ v# Fbool CheckParams(params object[] args)
, w, I6 O( g0 z1 N9 d, l* I
{
7 M% R+ H* H7 [1 F0 ~
string[] Lawlesses={"=","'"};
4 k, a& C* Z8 J2 o8 x7 `) t$ p/ u
if(Lawlesses==null||Lawlesses.Length<=0)return true;
7 A# e7 S. ^4 o! _$ H
//构造正则表达式,例:Lawlesses是=号和'号,则正则表达式为 .*[=}'].* (正则表达式相关内容请见MSDN)
) m% ^$ P, ^, t' R2 V% C; r
//另外,由于我是想做通用而且容易修改的
8 S( U/ m: o6 K8 h* q
函数,所以多了一步由字符数组到正则表达式,实际使用中,直接写正则表达式亦可;
3 Y2 X/ M& l6 w, U string str_Regex=".*[";
1 r3 U6 z6 f" C
for(int i=0;i< Lawlesses.Length-1;i++)
7 }( v7 f7 n; b% t5 F
str_Regex+=Lawlesses
+"|";9 V, z4 p% }& G/ ^
str_Regex+=Lawlesses[Lawlesses.Length-1]+"].*";
+ ?% K# S/ `: D& K3 z3 L5 w //
* Q! n7 g; c E; `4 w# _/ | foreach(object arg in args)
8 c N* W* @5 A {& ~$ |( t% k, F- ]# B& \% Z# D
if(arg is string)//如果是字符串,直接检查- M$ T e5 p# `2 {% T6 h
{0 ~0 Y3 }4 E* z! n# g2 e
if(Regex.Matches(arg.ToString(),str_Regex).Count>0)
5 I& f& y V" L- X- m3 b return false;
2 N5 z& _# m2 L4 I+ r9 _ }$ @' Y! O' q( H
else if(arg is ICollection)//如果是一个集合,则检查集合内元素是否字符串,是字符串,就进行检查) i$ e, P% O! u$ p
{
6 A, g5 m, Z% u, y foreach(object obj in (ICollection)arg): T5 n; T. O' m: v0 i, E. P
{, K- J$ w. x( c
if(obj is string)
' U3 z9 ]% p5 ~% L {
0 y) @$ {& ]+ S V if(Regex.Matches" {1 p& p- L+ I) ~
(obj.ToString(),str_Regex).Count>0)1 p, m+ b9 U1 M x7 C$ J
return false;
/ o) p3 `/ f" `& z }+ k4 p. m/ a: r: j0 A' K
}
, d1 v! M" e7 K( G* j5 Y }
. N( s' C [/ {6 Y, {+ ? }
# ]% r u: S$ |8 e3 `# l! g" e3 U return true;
! u5 M* ~/ _3 N' f1 ]}
# Q2 C$ f1 D1 h
4 t5 T3 @: f T' y- z[
本帖最后由 nicenic 于 2008-4-14 10:27 编辑 ]