Web应用安全威胁与防治--基于OWASP TOP 10 与ESAPI

OWASP ESAPI 预防XSS跨站脚本攻击 2、引入esapi的配置文件。 阅读详情

     ESAPI是owasp提供的一套API级别的web应用解决方案,本人通过对ESAPI和其提供的demo源码学习发现,关键的不是对其所提供的API的使用,而是其web应用安全防御体系的构建的思想。比如,您不一定要使用ESAPI去实现日志系统,而是应该明白,一套好的日志系统应该是怎么样子的,应具备什么样的特性等。

此外,在引入使用时可能会遇到不少麻烦,所以读者应根据自身的业务特性和需求进行整合,而不是一味的去粘贴和拼接。

1、Authentication

测试用于登录认证的ESAPI接口的步骤:

1.1、创建用户(方法的实现请参考FileBasedAuthenticator .java)

         1.1.1、Authenticator instance = ESAPI.authenticator(); //实例化

         1.1.2、User user = instance.createUser(accountName, password, password);  //在users.txt         中创建一个新用户,【遗留问题:在createUser()中并未发现是写到users.txt文件】

         1.1.3、instance.getUser(accountName).enable(); //使能账户

         1.1.4、instance.getUser(accountName).unlock(); //解锁账户

1.2、用户登录(方法的实现请参考AbstractAuthenticator .java)

/*

         1.2.1、必须预先在ESAPI.properties文件中设置UsernameParameterName和PasswordParameterName参数,因为login()会使用这两个参数的值去http请求中获取用户输入的用户名和密码。比如说,如果UsernameParameterName的值为username,那么login()会在http请求中去找username字段并获取其值(用户名)。

         1.2.2、该函数用来检查发送该请求的用户是否已登录,如果没有就重定向让其登录,内部实现的具体步骤如下:

         1) 检查用户是否已登录并存在会话中

             a. 如果是,确认会话最长时间和闲置操作时间是否到达

             b. 如果步骤1满足条件则步骤可跳过

    2) 如果不满足步骤1,则需要对用户的凭证(用户名和密码)进行有效验证

             a.建议使用ESAPI接口

                       loginWithUsernameAndPassword(HttpServletRequest, HttpServletResponse)

                            接口来验证用户凭证

    3) 记录用户本次登录的主机IP

    4) 验证本次请求的方式是否是安全的(比如POST+SSL)

    5) 验证用户账户是否允许登录

             a. 验证用户没有被禁用、过期和锁定等

    6) 将用户分配到会话变量中 

*/

【遗留问题:同一个用户重复登录时,是否只创建一个user对象再绑定多个session?】

User user = ESAPI.authenticator().login(HTTPServletRequest, HTTPServletResponse);

         DefaultUser user = (DefaultUser) getUserFromSession();//检查用户是否已登录

                   HttpSession session = ESAPI.httpUtilities().getCurrentRequest().getSession(false);

        if (session == null) return null;

        return ESAPI.httpUtilities().getSessionAttribute(USER);

         user = getUserFromRememberToken();//【遗留问题:选”记住我”才会用到,未理解】

         user = (DefaultUser) loginWithUsernameAndPassword(request);//如果没登录则要求用户进行认证(hash[username+id]值和users.txt对比),并返回user对象

         user.setLastHostAddress(request.getRemoteHost());//记录用户最后一次成功登录的主机IP

         ESAPI.httpUtilities().assertSecureRequest(ESAPI.currentRequest());//验证请求是否使用POST+SSL方式传输

         if (user.isAnonymous()||!user.isEnabled()||user.isLocked()||user.isExpired()||user.isSessionTimeout()||user.isSessionAbsoluteTimeout())//各种用户状态条件判断

                   user.logout();//强制用户注销

         user.setLocale(request.getLocale());//【遗留问题:未理解】

         /* 为用户创建会话 */

    HttpSession session = request.getSession();//如果当前请求不存在有效session则创建一个,如果存在就返回当前的

    user.addSession(session);//将会话绑定到user对象中,一个用户可能有多个session?

    session.setAttribute(USER, user);//user对象存储到USER

setCurrentUser(user);//将用户设置为当前登录用户

 

1.3、用户注销

User user = ESAPI.authenticator().logout;

1.4、关于ESAPI.authenticator().login(HTTPServletRequest, HTTPServletResponse)对每个请求的处理逻辑。

clip_image001

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


2、Session Management

2.1、用户登录后更新session id的接口(防止会话定置攻击):

javax.servlet.http.HttpSession ESAPI.httpUtilities().changeSessionIdentifier(javax.servlet.http.HttpServletRequest request);

接口内部实现说明:将当前session数据拷贝到新session,并使当前session失效,并将新session绑定到当前user对象中,并返回新的session。

2.2、为URL增加CSRF token

2.2.1、为指定URL增加CSRF TOKEN

String transferFundsHref = "/SwingSet/main?function=TransferFunds&lab";

<a href='<%=ESAPI.httpUtilities().addCSRFToken(transferFundsHref)%>' >Transfer Funds</a>

说明:在url末尾添加的csrftoken值等于user.getCSRFToken()

2.2.2、在transferFundsHref的页面里验证request携带的和user的CSRF token是否一致。

ESAPI.httpUtilities().verifyCSRFToken();

         if ( !user.getCSRFToken().equals( token ) ) {   //验证两者是否一致

                            throw new IntrusionException("Authentication failed",

3、AccessControl

3.1、角色权限验证:

3.1.1、接口:ESAPI.accessController().assertAuthorizedForURL(java.lang.String url)

3.1.2、说明:检查当前用户对应的角色是否有权限访问url,权限的定义在esapi\fbac-policies\URLAccessRules.txt文件中。

3.1.3、接口源码分析:

ESAPI.accessController().assertAuthorizedForURL(string url)

         this.assertAuthorized("AC 1.0 URL", new Object[] {url});

/*

         在esapi\ESAPI-AccessControlPolicy.xml文件中获取name为“AC 1.0 URL”的访问控制信息:

clip_image003

*/

                   AccessControlRule rule = (AccessControlRule)ruleMap.get(key);

/*

    将key对应的(此例key等于"AC 1.0 URL")对应的访问控制信息(如上图)作为     AccessControlRule接口的构造函数的入参(参考   AccessControlRule.java),   即顺序调用了以下3个函数:

    void setPolicyParameters(P policyParameter);//P为访问控制信息

    P getPolicyParameters();//该函数未重写,默认为空,故不执行

    boolean isAuthorized(R runtimeParameter);//此处R为空,故在下面调用

*/

       isAuthorized = rule.isAuthorized(runtimeParameter);

/*

    此处runtimeParameter等于string url,经过setPolicyParameters()的设置,此  处调用isAuthorized()实际上等于调用FileBaseACRs.java中定义的   isAuthorizedForURL(),即实际效果等于:isAuthorizedForURL(string url),请参   考第4、5点的分析。

*/

 

3.1.4、void setPolicyParameters()的分析(源码在DelegatingACR.java):

void setPolicyParameters(DynaBeanACRParameter policyParameter)

    delegateClassName =

       policyParameter.getString("delegateClass", "").trim();

    methodName =

       policyParameter.getString("delegateMethod", "").trim();

    parameterClassNames =

       policyParameter.getStringArray("parameterClasses");

/*

    由以上截图可知,此例的delegateClassName为:

    org.owasp.esapi.reference.accesscontrol.FileBasedACRs;

    methodName为:isAuthorizedForURL;

    parameterClassNames为:java.lang.String

*/

    Class delegateClass = getClass(delegateClassName, "delegate");

    Class parameterClasses[] = getParameters(parameterClassNames);

/*

    通过getClass获取FileBasedACRs类,【疑问:parameterClasses[]是什么呢?】

*/

         this.delegateMethod = delegateClass.getMethod(methodName, parameterClasses);

/*

    根据方法名来从FileBasedACRs类中获取方法,此例实际为isAuthorizedForURL()

*/

 

3.1.5、boolean isAuthorized ()的源码分析

boolean isAuthorized(Object[] runtimeParameters)

         return ((Boolean)delegateMethod.invoke(delegateInstance,

                                               runtimeParameters)).booleanValue();

/*

    调用FileBasedACRs类中定义的回调函数,此例实际为isAuthorizedForURL(),   runtimeParameters为要检查的内容,比如要访问的URL、service、function和file等, 此列为URL。

*/

 

3.1.6、boolean isAuthorizedForURL()的源码分析

    urlMap = loadRules("URLAccessRules.txt");

/*

    故实际定义URL访问控制权限的文件是URLAccessRules.txt,其它类似的还有 FunctionAccessRules.txt和DataAccessRules.txt等等,由以上的分析可知,实 

    际上最终会对哪个权限控制文件做检查是由void assertAuthorized(Object key,  

    Object runtimeParameter)的key决定的,key的值都在ESAPI-AccessControlPolicy.xml 文件中定义了,目前可能的值为"AC 1.0 Data"、"AC 1.0 File"、"AC 1.0 Function"、"AC 1.0  Service"、"AC 1.0 URL"。

    补充说明: ESAPI提供的顶层接口(比如assertAuthorizedForURL()等)已经帮我们定义  好了要调用的key值了(如本例),因此实际上只需要修改权限控制文件 (URLAccessRules.txt、FunctionAccessRules.txt等)就可以了。

*/

                   return matchRule(urlMap, url);

/*

         在URLAccessRules.txt检查当前用户的角色以及该角色是否有访问url的权限,

    URLAccessRules.txt内容如下图所示:

    clip_image005

*/    

【遗留问题】:

         是不是在过滤器中设置ESAPI的ESAPI.authenticator().login()和ESAPI.accessController().assertAuthorizedForURL()就可以解决每一个请求的认证和权限验证问题了?

3.2、直接对象引用:

3.2.1、使用随机映射表对象的样例代码:

<%@ page import="org.owasp.esapi.reference.RandomAccessReferenceMap"%>

<%

         Set fileSet = new HashSet();

         ArrayList list = new ArrayList();

         list.add(msgID0);     //将需要映射的资源的直接引用名(此处为message id)添加到list

         list.add(msgID1);

         ……

         fileSet.addAll(list);

         RandomAccessReferenceMap MsgIDMap = new RandomAccessReferenceMap(fileSet);

         /*调用ESAPI接口生成随机映射表对象*/

         HttpSession sess =          ESAPI.httpUtilities().getCurrentRequest().getSession(false);

    sess.setAttribute("MsgIDMap ", MsgIDMap);

         /*

                   此时应将映射表对象存放到安全的地方,比如:session

         */

         String indirect = instance.getIndirectReference(msgID0));

         /*

                   获取要被访问的资源的间接引用值,该值由ESAPI接口随机生成,并且每次进行映        射时值都会动态产生变化,因此,如果用户每次登录时进行重映射,那么用户在浏                   览器端看到的间接引用值也会每次都不一样,也大大增加了防御CSRF攻击的能力。

         */

         String href = "http://www.test.com?messageid=";

%>

        

         <a href="<%=href + indirect %>">点击读取消息;

         /*

                   将提供给用户读取消息的链接返回给用户,用户最终看到的链接将带上间接引用值。

                   例如:http://www.test.com?messageid=DfDsQK

         */

【说明】:当要映射的资源较多时,使用资源映射表可能会消耗较多的内存。

【遗留问题】:同一个用户重复登录都要重新映射?不同类型的资源(比如消息id、用户id和设备id等等)应当映射到不同的表中还是可以全部映射到一个表中?

 

3.2.2、处理来自用户请求的样例代码:

<%

         HttpSession sess =          ESAPI.httpUtilities().getCurrentRequest().getSession(false);

    RandomAccessReferenceMap MsgIDMap =

    (RandomAccessReferenceMap) sess.getAttribute("MsgIDMap ");

         /*

                   从当前登录用户的session中还原出资源的随机映射表对象。

         */

         String indMsgID = request.getParameter( " messageid " );

        String directMsgID = (String) MsgIDMap.getDirectReference(indMsgID);

         /*

                   获取客户端传过来的间接索引值,再通过间接索引值得到直接引用对象的值,如果                   该值为空,表示用户传过来了一个非法的间接索引值,此时getDirectReference会                         抛出一个AccessControlException异常,应用系统应在异常中做适当处理,比如将                            该异常行为记录到日志中。

         */

%>

3.2.3、服务器处理携带用户资源标签请求的流程图

 

clip_image006

 

 


4、Input Validation

4.1、使用自定义的正则表达式规则验证用户的输入数据。

4.1.1、接口说明:

接口1:

java.lang.String getValidInput(java.lang.String context, java.lang.String input, java.lang.String type, int maxLength, boolean allowNull)

功能说明:使用esapi/validation.properties文件中定义的正则表达式去验证用户的输入数据。

参数说明:

context:任意定义的字符串,主要用于日志打印信息。

Input:需要验证的输入字符。

Type:选择需要使用的一种正则表达式(见4.1.2)。

MaxLenth:允许输入字符的最大长度。

AllowNull:是否允许输入空字符(true为允许,false为不允许)。

返回:经过规范化和验证过滤后的字符串【遗留问题:实际验证时好像未返回字符串】

 

接口2:

isValidInput(java.lang.String context, java.lang.String input, java.lang.String type, int maxLength, boolean allowNull)

功能与getValidInput()一样,但不返回字符串,仅验证通过时返回true,否则返回false。

4.1.2、validation.properties文件的正则表达式定义如下:

clip_image008

4.1.3、样例代码:

String input = request.getParameter("input");

type = "SafeString"; //使用validation.properties文件定义的SafeString正则表达式规则

         try {

                   ESAPI.validator().getValidInput(

                                     "Swingset Validation Secure Exercise", input, type,

                                     200, false);

         } catch (ValidationException e) {

                   /*当检测到输入字符串不匹配正则表达式时产生该异常,应进行适当处理*/

                   input = "Validation attack detected";

                   request.setAttribute("userMessage", e.getUserMessage());

                   request.setAttribute("logMessage", e.getLogMessage());

         } catch (Exception e) {

                   input = "exception thrown";

                   request.setAttribute("logMessage", e.getMessage());

         }

 

接口3:void assertValidFileUpload(java.lang.String context,

java.lang.String filepath, java.lang.String filename, java.io.File parent, byte[] content, int maxBytes, java.util.List<java.lang.String> allowedExtensions, boolean allowNull)

功能说明:对上传文件的路径、文件名、扩展名和文件大小进行检查。

参数说明:略。

函数分析:

void assertValidFileUpload(String context, String directorypath, String filename, File parent, byte[] content, int maxBytes, List<String> allowedExtensions, boolean allowNull)

                  getValidFileName( context, filename, allowedExtensions, allowNull );

                            getValidInput( context, input, "FileName", 255, true );

                   getValidDirectoryPath( context, directorypath, parent, allowNull );

                            fileValidator.getValidInput( context, canonicalPath, "DirectoryName", 255, false);

                   getValidFileContent( context, content, maxBytes, allowNull );

                            esapiMaxBytes = ESAPI.securityConfiguration().getAllowedFileUploadSize();

                   /* FileName和DirectoryName 正则表达式都在ESAPI.properties全局文件中定义*/

 

注意事项:如果没有canonicalize参数,表示该API默认对输入数据进行canonicalize,否则需要使用canonicalize参数去指定是否需要对输入数据进行canonicalize,一般情况下,我们都默认使用不带canonicalize参数的API,表示默认对输入数据进行canonicalize。

更多owasp数据验证API请参考在线官方文档:

URL:http://owasp-esapi-java.googlecode.com/svn/trunk_doc/latest/index.html

接口路径:org.owasp.esapi->Validator->Method Summary

4.2、在富文本应用系统中防御XSS攻击。

应用系统允许用户输入自定义的html代码,我们称之为“富文本”,此类系统容许类似<,>之类的危险标签的存在(即输出时原样携带<,>这样的标签),此场景下我们需要以下API:

java.lang.String getValidSafeHTML(java.lang.String context, java.lang.String input, int maxLength, boolean allowNull)

功能说明:对用户输入的富文本数据进行有效过滤,防止XSS。

参数说明:

context:任意定义的字符串,主要用于日志打印信息。

Input:需要验证的富文本输入数据。

maxLenth:允许输入字符的最大长度。

AllowNull:是否允许输入空字符(true为允许,false为不允许)。

返回:经过规范化和验证的安全的html内容,该内容中的body、attributes、CSS、URLs等都不会包含恶意的脚步代码。

样例:

输入:<p>test <b>this</b> <script>alert(document.cookie)</script><i>right</i> now</p>

输出:<p>test <b>this</b> alert(document.cookie)<i>right</i> now</p>

如果此时对<,>标签进行html编码再输出就会改变原意,达不到想要的显示效果:&lt;p&gt;test &lt;b&gt;this&lt;&#x2f;b&gt; &lt;i&gt;right&lt;&#x2f;i&gt; now&lt;&#x2f;p&gt;

5、Output Encoding/Escaping

5.1、Canonicalize

术语解释:canonicalize是指将数据转换或解码成一个常见字符集的过程。这里的数据可以是经过多重混合编码的。比如:%3cscript%3ealert(%22xss%22)%3c%2fscript%3e还原成<script>alert("xss")</script>。在对输入数据进行过滤之前应进行规范化!

接口1:java.lang.String

canonicalize(java.lang.String input, boolean strict)

功能说明:将编码过的数据还原为其最简化的形式。

参数说明:

Input:输入数据。

strict:指定是否对输入数据进行多重和混合编码的检测,true时将触发IntrusionException,但不返回数据,而false将直接返回canonicalize后的数据。

返回:canonicalize后的数据。

 

5.2、对输出到浏览器的数据进行编码/转义

以下内容摘自《web安全开发规范v1.1》à反射型、存储型XSS安全规则:

将用户数据输出到html body某处时,必须经过html转义,比如:

<body>...【用户数据】...</body>

<div>...【用户数据】...</div>

以及其它普通的html标签,比如p, b, td等等。

ESAPI sample:

String safe =

ESAPI.encoder().encodeForHTML( request.getParameter( "input" ) );

将用户数据输出到html 标签的属性时,必须经过标签属性的转义。

注意:不包含href, src, style和事件处理函数属性(比如onmouseover)。

<div attr=...【用户数据】...>content</div>    //数据不在引号内

<div attr='... 【用户数据】...'>content</div>  //数据在单引号内

<div attr="...【用户数据】...">content</div>  //数据在双引号内

ESAPI sample:

String safe =

ESAPI.encoder().encodeForHTMLAttribute( request.getParameter( "input" ) );

将用户数据输出到JavaScript数据域时,必须经过JavaScript转义。

注意:用户数据必须在引号内,否则转义后数据仍然是不安全的。

<script>alert('... 【用户数据】...')</script>   //数据在带引号的字符串内

<script>x='... 【用户数据】...'</script>  //数据在带引号的表达式内

<div onmouseover="x='... 【用户数据】...'"</div>

ESAPI sample:

String safe =

ESAPI.encoder().encodeForJavaScript( request.getParameter( "input" ) );

将用户数据输出到URL的参数时,必须经过URL转义。

<a href="http://www.somesite.com/x/y/z?test=...【用户数据】...">link</a >

ESAPI sample:

String safe =

ESAPI.encoder().encodeForURL( request.getParameter( "input" ) );

注意:所有基于URL的标签属性(比如href,src等),如果其整个或相对的URL被用户数据控制,比如:

<a href=” ...【用户数据】...”>link</a>

则应先验证URL的有效性,再进行html标签属性的转义:

String userURL = request.getParameter( "userURL" )

 boolean isValidURL = ESAPI.validator().isValidInput("URLContext", userURL, "URL", 255, false);

 if (isValidURL) { 

     <a href="<%=encoder.encodeForHTMLAttribute(userURL)%>">link</a>

 }

除了以上4条规则定义的安全上下文以外,其它上下文都是无法安全地转义的,应避免出现,比如:

<script>...【用户数据】...</script>  //直接输出到js标签内

<!--...【用户数据】...-->           //直接输出到注释内

<div ... 【用户数据】...=test />     //直接输出到标签属性名

<..【用户数据】... href="/test" />   //作为标签名使用

<style>...【用户数据】...</style>    //直接输出到CSS

……

5.3、对输出到解析器的数据进行编码/转义:

接口1:java.lang.String encodeForSQL(Codec codec, java.lang.String input)

功能说明:对SQL查询语句中用户控制的输入数据进行编码/转义。

参数说明:

codec:编码器,编码器的种类请参考在线接口文档àorg.owasp.esapi.codecs,针对数据查询的编码器有MySQLCodec和OracleCodec,故目前只支持mysql和oracle数据库。

input:SQL查询输入数据。

返回:编码/转义后的数据。

样例代码:

以下内容摘自《web安全开发规范v1.1》

Codec MYSQL_CODEC = new MySQLCodec ();//实例化编码器()

String query = "SELECT user_id FROM user_data WHERE user_name = '" +

ESAPI.encoder().encodeForSQL(MYSQL_CODEC,req.getParameter("userID"))+"'and user_password = '"+ ESAPI.encoder().encodeForSQL(MYSQL_CODEC, req.getParameter("pwd")) +"'";

编码结果样例:

         输入:foo" and 1 = 2

         输出:foo\" and 1 \= 2

 

接口2:java.lang.String encodeForOS(Codec codec, java.lang.String input)

功能说明:对传递给OS shell的输入数据进行编码/转义。

参数说明:

codec:编码器,编码器的种类请参考在线接口文档àorg.owasp.esapi.codecs,针对OS command shell的编码器有WindowsCodec和UnixCodec,故目前只支持mysql和oracle数据库。

input:要传递给OS shell的输入数据。

返回:编码/转义后的数据。

样例代码:需要开发人员提供。

 

接口3:java.lang.String encodeForLDAP(java.lang.String input)

功能说明:对LDAP查询数据的编码/转义。

参数说明:LDAP查询输入数据

 

更多API请参考在线接口文档:org.owasp.esapiàEncoder。

6、Cryptography

6.1、加、解密

接口1:CipherText encrypt(PlainText plaintext)

功能说明:对plaintext数据进行加密,加密的算法/模式/填充方式和加密密钥在ESAPI.properties文件中定义(默认AES128/CBC/PKCS5Padding)。

参数说明:

plaintext:需要加密的明文数据。

返回:加密后的数据。

样例代码:

String decryptedStr = request.getParameter("decrypted");

encrypted = ESAPI.encryptor().encrypt(decryptedStr);

注意事项:该接口在对需要加密的明文添加当前时间信息,因此每次加密出来的密文都不相同,在解密时将时间信息删除即可得到原始明文。【遗留问题:添加时间信息能增强安全性?】

 

接口2:PlainText decrypt(CipherText ciphertext)

功能说明:对ciphertext数据进行解密。

参数说明:

ciphertext:需要解密的密文。

返回:解密后的明文数据。

样例代码:

String encryptedStr = request.getParameter("encrypted");

decrypted = ESAPI.encryptor().decrypt(encryptedStr);

 

接口3:java.lang.String hash(java.lang.String plaintext,java.lang.String salt,int iterations)

功能说明:对数据进行哈希。

参数说明:

plaintext:需要hash的数据。

Salt:用于hash的salt。

Iterations:要迭代的次数【遗留问题:迭代是指重复哈希?如果是,每次都需要加salt吗?】。

返回:hash值。

样例代码:

String hashStr = request.getParameter("hash");

hashVal = ESAPI.encryptor().hash(hashStr,”ABCDEFG”,3);

 

更多加密解密API请参考在线官方文档:org.owasp.esapiàEncryptor

6.2、随机数

接口1:获取随机字符串:

以下参考《web安全开发指南v1.1》

接口:java.lang.String  ESAPI.randomizer().getRandomString(int length,char[] characterSet)

说明:从固定字符数组characterset中获取长度为length的随机字符串,本接口可用于生成各种自定义长度和复杂度的随机token,比如CSRF同步token等。

样例代码:

    char[] CHAR_DIGITS = { '0', '1', '2', '3', '4', '5', '6', '7', '8'};

    char[] CHAR_LETTERS = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'};

    char[] CHAR_ALPHANUMERICS = StringUtilities.union(CHAR_LETTERS,           CHAR_DIGITS);

         ESAPI.randomizer().getRandomString(6,CHAR_ALPHANUMERICS);

执行结果样例:0edec6,cjefic等6位随机字符串。

 

接口2:获取随机GUID:

接口:java.lang.String ESAPI.randomizer().getRandomGUID()

说明:产生32位的GUID格式的随机字符串。

样例代码:略

执行结果样例:53110e13-804a-4041-a547-09399c2791ea等

 

接口3:获取随机整数:

接口:int ESAPI.randomizer().getRandomInteger(int min,int max)

说明:获取min到max范围的随机整数。

样例代码:ESAPI.randomizer().getRandomInteger(-100,100)

执行结果样例:-11、55等。

 

接口4:获取随机文件名:

接口:java.lang.String  getRandomFilename(java.lang.String extension)

说明:生成随机字符串作为文件名,并添加extension作为文件扩展名。

样例代码:ESAPI.randomizer().getRandomFilename("exe")

执行结果样例:X4f0cafF0Mkj.exe、CzkmUsLKFx7c.exe等。

 

接口5:获取随机长整数:

接口:long ESAPI.randomizer().getRandomLong()

说明:获取随机长整数。

样例代码:略

执行结果样例:8712910770684726225、6703356794875845559等。

 

更多随机函数接口请参考:

http://owasp-esapi-java.googlecode.com/svn/trunk_doc/latest/index.html

org.owasp.esapiàRandomizer

7、Error Handling and Logging

7.1、日志记录

7.1.1、日志接口说明:        

ESAPI日志接口定义了6个级别的日志等级:

  • fatal (highest value)
  • error
  • warning
  • info
  • debug
  • trace (lowest value)

同时也预定义了4类日志事件:SECURITY_SUCCESS, SECURITY_FAILURE, EVENT_SUCCESS, EVENT_FAILURE,用于区分安全相关的事件和普通事件。

和日志相关的配置参数在ESAPI.properties设置,可配置参数:

Logger.ApplicationName:应用程序名,表示日志是哪个应用程序产生的。

Logger.LogEncodingRequired:true表示当日志包含特殊字符时自动进行转义后再记录。

Logger.LogApplicationName:true表示在日志中记录应用程序吗。

Logger.LogServerIP:true表示在日志中记录服务器的IP。

Logger.LogFileName:日志的名称(必须预先在存在)。

Logger.MaxLogFileSize:单个日志文件的最大容量,超过时自动切到另外一个日志文件。

7.1.2、接口:

原型:

         Logger  getLogger(java.lang.String moduleName)

参数说明:

         moduleName:logger使用来标记该日志是应用程序的哪个模块产生的。

原型:

         Void fatal(Logger.EventType type, java.lang.String message)

参数说明:

Type:事件类型。

Message:要记录的日志信息。

与logger相关的方法和参数请参考ESAPI在线帮忙文档:

org.owasp.esapiàlogger

7.1.2、样例代码:

         WriterAppender appender = new WriterAppender(new SimpleLayout(), out);

         org.apache.log4j.Logger.getRootLogger().addAppender(appender);

 

         Logger logger = ESAPI.getLogger("LoggingTutorialModule");

         logger.fatal(Logger.SECURITY_FAILURE, " <script>alert('123')</script>");

         logger.debug(Logger.EVENT_SUCCESS, " <scr<script>ipt>alert('abc')</script> ");

 

         org.apache.log4j.Logger.getRootLogger().removeAppender(appender);

 

7.1.3、输出结果:

181681687 [http-8443-2] FATAL SwingSetInteractive:LoggingTutorialModule  - [SECURITY FAILURE Anonymous:308755@unknown -> /SwingSetInteractive/LoggingTutorialModule] &lt;script&gt;alert&#x28;&#x27;123&#x27;&#x29;&lt;&#x2f;script&gt; (Encoded)

 

181681687 [http-8443-2] DEBUG SwingSetInteractive:LoggingTutorialModule  - [EVENT SUCCESS Anonymous:308755@unknown -> /SwingSetInteractive/LoggingTutorialModule] &lt;scr&lt;script&gt;ipt&gt;alert&#x28;&#x27;abc&#x27;&#x29;&lt;&#x2f;script&gt;  (Encoded)

 

在与具体业务相结合时,应提供足够的信息作为回溯的依据,应提供的信息如下:

导致事件发生的源对象(比如用户id,用户名等);

         对事件的描述;

         事件的结果(成功或失败);

         事件的严重等级(在具体的业务事件中定义,然后调用ESAPI接口执行);

         事件的类型(在具体的业务事件中定义,然后调用ESAPI接口执行);

         发生事件的源IP和目标主机IP;

         发生事件的时间。

7.2、错误处理

8、Data Protection

8.1、数据缓存

接口:

void setNoCacheHeaders(javax.servlet.http.HttpServletResponse response)

功能说明:为指定的response设置Cache-Control和Expires header。

参数说明:

response:指定的http response,当该参数为空时表示当前request的对应的response。

返回:无

样例代码:

<%

         ESAPI.httpUtilities().setNoCacheHeaders();

%>

返回的http response中包含的缓存控制header如下:

Cache-Control: no-store, no-cache, must-revalidate

Pragma: no-cache

Expires: Wed, 31 Dec 1969 23:59:59 GMT

更多和数据安全相关的接口请参考:

org.owasp.esapià HTTPUtilities

 

9、Http Security

9.1、URL重定向

9.1.1、接口:

void sendRedirect(javax.servlet.http.HttpServletResponse response,java.lang.String location)

功能说明:对需要重定向的参数进行判断,如果重定向的URL不符合"Redirect"正则表达式的要求,则触发异常,并重定向回主页。

参数说明:

response:指定的http response,当该参数为空时表示当前request的对应的response。

location:重定向的URL。

样例代码:

<%

         String redirect = request.getParameter("redirect");

         if (redirect != null){

                 //response.sendRedirect(redirect);

                 ESAPI.httpUtilities().sendRedirect(redirect);

         }

%>

9.1.2、对sendRedirect的源代码分析:

void sendRedirect(javax.servlet.http.HttpServletResponse response,java.lang.String location)

         ESAPI.validator().isValidRedirectLocation("Redirect", location, false)

                   ESAPI.validator().isValidInput( context, input, "Redirect", 512, allowNull);

                            /*通过ESAPI.properties文件中的Redirect正则表达式进行过滤判断:

                            Validator.Redirect=^/SwingSet/.+,此处使用的是相对路径,表示ESAPI只允许                                重定向到当前站点的URL*/

    response.sendRedirect(location);

 

10、Interface HTTPUtilities

接口1:

void addCookie(javax.servlet.http.Cookie cookie)

功能描述:添加新的cookie,并为新cookie设置http only和secure属性。

 

接口2:void addHeader(java.lang.String name,java.lang.String value)

功能描述:为当前response添加新的header。

 

接口3:void assertSecureRequest() throws AccessControlException

功能描述:检查当前request是否是安全的(ssl+post),如果不是则产生异常,服务器应调用该接口对所有包含敏感数据的request做检查,保证敏感数据不会被嗅探、记录到日志。

 

接口4:void assertSecureChannel() throws AccessControlException

功能描述:检查当前request是否是通过SSL传输,如果不是则产生异常,服务器应调用该接口对所有包含敏感数据的request做检查,保证敏感数据不会被嗅探。

 

接口5:java.lang.String getCookie(java.lang.String name)

功能描述:根据cookie name来获取cookie的值。

 

接口6:java.lang.String getHeader(java.lang.String name)

功能描述:根据header name获取当前request的header值

米桃安全漏洞讲堂系列第2期:XSS跨站脚本攻击漏洞 本文结合实际使用案例,简要讲述了跨站脚本攻击XSS漏洞的原理、分类、危害、测试方法及防御措施。适合研发人员、测试人员、在校学生及信息安全爱好者。 阅读详情

相关推荐

OWASP ESAPI项目

OWASP ESAPI项目 ,项目文档

ESAPI学习笔记

ESAPI学习笔记      ESAPI是owasp提供的一套API级别的web应用解决方案,本人通过对ESAPI和其提供的demo源码学习发现,关键的不是对其所提供的API的使用,而是其web应用安全防御体系的构建的思想。比如,您不一定要使用ESAPI去实现日志系统,而是应该明白,一套好的日志系统应该是怎么样子的,应具备什么样的特性等。 此外,在引入使用时可能会遇到不少麻烦,

peterxiaoq的专栏 1万+

系统-等保三级-CentOS Linux 7合规基线检查 shell脚本

系统-等保三级-CentOS Linux 7合规基线检查 shell脚本

swindy博客 2407

WEB安全-ESAPI

ESAPI是owasp提供的一套API级别的web应用解决方案。简单的说,ESAPI就是为了编写出更加安全的代码而设计出来的一些API,方便使用者调用,从而方便的编写安全的代码 其官方网站为:https://www.owasp.org/,其有很多针对不同语言的版本,其J2ee的版本需要jre1.5及以上支持 安装篇 第一步:引入Jar Maven &lt;dependency...

frog4的专栏 2万+

从‘最速控制’到代码:深入拆解韩京清ADRC中TD跟踪器的fhan函数(含Matlab/Simulink实例)

本文深入解析韩京清ADRC中的fhan函数,从理论到代码实现,详细拆解其在Matlab/Simulink中的应用。通过分析最速控制问题和非线性TD的连续形式,揭示fhan函数在信号处理和噪声抑制中的独特优势,并提供工程实践中的参数整定和优化技巧。

weixin_42659194的博客 246

微信小程序返回按钮的隐藏玩法:用onShow实现数据自动刷新(附完整代码)

本文深入探讨了微信小程序中用户点击返回按钮后,如何利用onShow生命周期函数实现页面数据的自动刷新。文章对比了onLoad与onShow的差异,提供了从基础的本地存储标记到进阶的EventChannel事件通信,再到状态管理库的多种解决方案,并附有完整的代码示例,帮助开发者构建流畅的用户体验。

agile9scrum的博客 925

Web应用安全威胁与防治:基于OWASP Top 10与ESAPI

为什么80%的码农都做不了架构师?>>> ...

weixin_34194359的博客 139

SDR实战(五)-AD9361多芯片同步技术详解

本文详细解析了AD9361多芯片同步技术在SDR系统中的实现方法,涵盖硬件连接方案、软件配置流程及同步验证技巧。通过等长时钟走线、低抖动时钟分配和精确的SYNC信号控制,解决MIMO系统中多AD9361芯片的时钟同步难题,提升系统性能与稳定性。

weixin_30952535的博客 761

Web应用安全威胁与防治——基于OWASP Top 10与ESAPI

http://product.china-pub.com/3021666 http://web2hack.org/book/   http://product.china-pub.com/3021117?ref=buyand#ml http://product.china-pub.com/3020484#ml

cnbird's blog 2972

西门子1200,与V90和步科MD60第三方伺服PN通讯

需要注意的是回零方式的选择,因为V90是绝对值编码器,这里回零模式选择模式7,系统自动根据编码器反馈以及组态的机械参数,计算出轴的位置,并且掉电保持。在线访问中,找到对应的网卡,以及下面扫描到的设备,可以在线修改ip地址和profinet名称,注意一定要和组态中的完全一致。以上硬件组态上完成,主要是gsd文件导入后,添加硬件,建立连接,修改ip和profinet名称,添加报文。1- 博图V18内,设备组态,网络视图中,拖入V90以及MD60伺服,并与PLC创建连接。向厂家索要GSD文件,PN的描述文件。

weixin_37596954的博客 2461

【零基础入门unity游戏开发——2D篇】大大简化了地形创建流程,减少Rule Tile的使用 —— AutoTile自动平铺瓦片的使用介绍

Unity 2D游戏开发中的AutoTile技术详解 摘要:本文详细介绍了Unity 2D游戏开发中的AutoTile技术,这是一种智能瓦片系统,能够自动处理地形和场景拼接。文章首先讲解了AutoTile的基本概念和优势,然后分步骤指导读者如何安装2D Tilemap Extras包、创建AutoTile、设置参数和绘制遮罩。通过实际案例演示了AutoTile的使用方法,并比较了AutoTile与Rule Tile的适用场景。最后指出AutoTile虽然使用方便,但对素材要求较高,开发者应根据项目需求选择合

向宇的博客,专注php/web全栈 unity游戏开发,欢迎大家评论纠错 727

试读《Web应用安全威胁与防治——基于OWASP_Top_10与ESAPI》

       试读了《Web应用安全威胁与防治——基于OWASP_Top_10与ESAPI》,感觉这本书写得很好将一些复杂的应用安全理论通过浅显的故事讲述出来,非常方便大家的理解。         读了试读样章后我收获颇丰的一点就是在身份认证中的双因子身份认证。随着互联网应用日渐普及,应用安全的需求也逐步提高。其中身份认证是网络信息安全的基石,如果无法确定用户的身份则不可能进行合理的授权,任...

王浩的技术博客 313

第23章:代码迁移——用AI将Vue2迁移到Vue3、将JS迁移到TS

> - 用AI自动将Vue2 Options API转为Vue3 Composition API的完整流程 > - 将JavaScript项目批量迁移到TypeScript,自动添加类型推导 > - 处理依赖冲突、破坏性变更和迁移后的验证方法 > - 一个完整的Vue2到Vue3迁移案例(含路由、状态管理) > - 我如何用AI将公司一个10万行代码的老项目从JS升级到TS

sfishfly的博客 206

ESAPI之会话安全

ESAPI是开源组织owasp,开放的安全开发框架,但百度、google搜索相关的技术文章很少,今天小尝试了一下,分享一下心得。 会话攻击,简单理解就是盗用窃取用户的cookie,伪装成用户,向服务器端发送请求,窃取用户私密信息。 具体如何防止会话攻击,很简单,参照《Web应用安全威胁与防治--基于OWASP TOP 10 与ESAPI》书中介绍的方法,一旦用户登录成功后,马上validate

boloyz的专栏 4916

Coze 上 OpenClaw 完整使用攻略(零代码 + 24 小时在线 + 飞书 / 微信接入)

Coze(扣子)是目前国内零门槛部署 OpenClaw 最友好的平台,无需服务器、不用命令行,5 分钟即可拥有可执行本地 / 云端任务的 AI 助手,还能一键发布到飞书、微信、钉钉等 IM。

hy行者勇哥的博客 2919

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

新手上路——WEB开发注意“安全”事项

WEB开发注意“安全”事项在互联网时代,数据安全与个人隐私受到了前所未有的挑战,各种新奇的攻击技术层出不穷。这里我不讲hacker领域的攻防技术,毕竟咱也是门外汉,连皮毛...

东南草堂 173

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

Web安全工程师需要读取的技术书目

一. Web入门基础知识 Web是基础中的基础,通俗易懂的讲解了Web的本质和Web开发的基础知识。对于Web小白,建议从头开始抓紧学习;对于已经有一定Web基础知识的同学,建议快速的过一遍,夯实基础。 1《(前端安全)[Web前端黑客技术揭秘].钟晨鸣等.扫描版》 2《[精通正则表达式(第3版)]中文版.(美)Jeffrey.E.F.Friedl》 3《[数据结构(C语言版)].严蔚敏吴伟民.扫描版有目录》 4《[网络分析技术揭秘:原理、实践与WinPcap深入解析].吕雪峰等.扫描版》 5《[网络扫描技

企业实战系列集 ●●● https://ximenjianxue.blog.youkuaiyun.com 545

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

谁动了我的琴弦——会话劫持

谁动了我的琴弦——会话劫持 让我们看一个最常见的例子——会话劫持,如图10-2所示。 图10-2 会话劫持说明 如图10-2所示,受害者Alice正常的登录网站为www.buybook.com,此时她的Session ID是1234567,攻击者Bob通过网络嗅探获得了Alice的Session ID和Cookie中的用户登录信息,这样他就可以模仿Alice进行登录和操作了,而此

博文视点(北京)官方博客 2043

【web前端】前端工程师成长必备好书!

1 引言 乱七八糟的书看了很多,有一本讲JavaScript的印象特别深开篇说的是"JavaScript是Java的脚本语言",但还是看完了,最后忘了书名。 下面列的这些都是看过后至少记得起书名的,也有部分是经常看的书,一起列出来,推荐给爱学习的同学。 2 前端技术 2.1 综合 ·《现代前端技术解析》 ·《Web前端开发最佳实践》 ·《Web前端工程师修炼之道》 ·《编写高质量代码-Web前端开发修炼之道》 ·《响应式Web设计 HTML5和CSS3实战》 第二版 ·《响...

Sixstar_yanxin的博客 347

新年送好礼!ITeye1月技术图书有奖试读活动已结束!

[align=center][img]http://dl.iteye.com/upload/attachment/0079/2441/cafad8b2-019e-3f42-bb4a-bbc2f2cea919.png[/img][/align] 为了继续营造IT分享学习、共同进步的技术氛围,在2013年新年伊始之际,ITeye携手电子工业出版社博文视点共同举办2013年1月技术图书试读活动。 ...

ITeye黑板报 254

电子信息本科四年怎么规划?嵌入式与芯片方向路线详解

大学阶段的技术学习常让人陷入课程多但目标散的困惑。嵌入式是连接软件与硬件的工程领域,核心在于用程序驱动微控制器或应用处理器实现产品功能;芯片方向则聚焦芯片本身的逻辑设计、验证、后端与测试,两者共享C语言、数据结构和数字电路等底层知识。从点灯到嵌入式Linux驱动,再到UVM验证与FPGA原型验证,工程能力的建立依赖真实项目与工具链的熟练使用。智能硬件、物联网、边缘计算与汽车电子等场景对这两类人才需求旺盛,但门槛与成长路径差异明显。电子信息本科的四年规划,正是要在打好基础的前提下,结合目标岗位合理分配时间。

weixin_34221773的博客 250
上一篇: Spring框架解析二【注解】
下一篇: 大数据之路
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值