http://product.china-pub.com/3021666html
http://product.china-pub.com/3021117?ref=buyand#mlmysql
http://product.china-pub.com/3020484#mlweb
测试用于登陆认证的ESAPI接口的步骤:正则表达式
1.一、建立用户(方法的实现请参考FileBasedAuthenticator .java)算法
1.1.一、Authenticator instance = ESAPI.authenticator(); //实例化sql
1.1.二、User user = instance.createUser(accountName, password, password); //在users.txt 中建立一个新用户,【遗留问题:在createUser()中并未发现是写到users.txt文件】shell
1.1.三、instance.getUser(accountName).enable(); //使能帐户数据库
1.1.四、instance.getUser(accountName).unlock(); //解锁帐户apache
1.二、用户登陆(方法的实现请参考AbstractAuthenticator .java)
/*
1.2.一、必须预先在ESAPI.properties文件中设置UsernameParameterName和PasswordParameterName参数,由于login()会使用这两个参数的值去http请求中获取用户输入的用户名和密码。好比说,若是UsernameParameterName的值为username,那么login()会在http请求中去找username字段并获取其值(用户名)。
1.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.三、用户注销
User user = ESAPI.authenticator().logout;
1.四、关于ESAPI.authenticator().login(HTTPServletRequest, HTTPServletResponse)对每一个请求的处理逻辑。
javax.servlet.http.HttpSession ESAPI.httpUtilities().changeSessionIdentifier(javax.servlet.http.HttpServletRequest request);
接口内部实现说明:将当前session数据拷贝到新session,并使当前session失效,并将新session绑定到当前user对象中,并返回新的session。
2.2.一、为指定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.二、在transferFundsHref的页面里验证request携带的和user的CSRF token是否一致。
ESAPI.httpUtilities().verifyCSRFToken();
if ( !user.getCSRFToken().equals( token ) ) { //验证二者是否一致
throw new IntrusionException("Authentication failed",
3.1.一、接口:ESAPI.accessController().assertAuthorizedForURL(java.lang.String url)
3.1.二、说明:检查当前用户对应的角色是否有权限访问url,权限的定义在esapi\fbac-policies\URLAccessRules.txt文件中。
3.1.三、接口源码分析:
ESAPI.accessController().assertAuthorizedForURL(string url)
this.assertAuthorized("AC 1.0 URL", new Object[] {url});
/*
在esapi\ESAPI-AccessControlPolicy.xml文件中获取name为“AC 1.0 URL”的访问控制信息:
*/
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),请参 考第四、5点的分析。
*/
3.1.四、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.五、boolean isAuthorized ()的源码分析
boolean isAuthorized(Object[] runtimeParameters)
return ((Boolean)delegateMethod.invoke(delegateInstance,
runtimeParameters)).booleanValue();
/*
调用FileBasedACRs类中定义的回调函数,此例实际为isAuthorizedForURL(), runtimeParameters为要检查的内容,好比要访问的URL、service、function和file等, 此列为URL。
*/
3.1.六、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内容以下图所示:
*/
【遗留问题】:
是否是在过滤器中设置ESAPI的ESAPI.authenticator().login()和ESAPI.accessController().assertAuthorizedForURL()就能够解决每个请求的认证和权限验证问题了?
3.2.一、使用随机映射表对象的样例代码:
<%@ 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.二、处理来自用户请求的样例代码:
<%
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.三、服务器处理携带用户资源标签请求的流程图
4.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.二、validation.properties文件的正则表达式定义以下:
4.1.三、样例代码:
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
应用系统容许用户输入自定义的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编码再输出就会改变原意,达不到想要的显示效果:<p>test <b>this</b> <i>right</i> now</p>
术语解释: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后的数据。
如下内容摘自《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 …… |
接口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。
接口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
接口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)
执行结果样例:-十一、55等。
接口4:获取随机文件名:
接口:java.lang.String getRandomFilename(java.lang.String extension)
说明:生成随机字符串做为文件名,并添加extension做为文件扩展名。
样例代码:ESAPI.randomizer().getRandomFilename("exe")
执行结果样例:X4f0cafF0Mkj.exe、CzkmUsLKFx7c.exe等。
接口5:获取随机长整数:
接口:long ESAPI.randomizer().getRandomLong()
说明:获取随机长整数。
样例代码:略
执行结果样例:871291077068472622五、6703356794875845559等。
更多随机函数接口请参考:
http://owasp-esapi-java.googlecode.com/svn/trunk_doc/latest/index.html
org.owasp.esapiàRandomizer
7.1.一、日志接口说明:
ESAPI日志接口定义了6个级别的日志等级:
同时也预约义了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.二、接口:
原型:
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.二、样例代码:
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.三、输出结果:
181681687 [http-8443-2] FATAL SwingSetInteractive:LoggingTutorialModule - [SECURITY FAILURE Anonymous:308755@unknown -> /SwingSetInteractive/LoggingTutorialModule] <script>alert('123')</script> (Encoded)
181681687 [http-8443-2] DEBUG SwingSetInteractive:LoggingTutorialModule - [EVENT SUCCESS Anonymous:308755@unknown -> /SwingSetInteractive/LoggingTutorialModule] <scr<script>ipt>alert('abc')</script> (Encoded)
在与具体业务相结合时,应提供足够的信息做为回溯的依据,应提供的信息以下:
致使事件发生的源对象(好比用户id,用户名等);
对事件的描述;
事件的结果(成功或失败);
事件的严重等级(在具体的业务事件中定义,而后调用ESAPI接口执行);
事件的类型(在具体的业务事件中定义,而后调用ESAPI接口执行);
发生事件的源IP和目标主机IP;
发生事件的时间。
接口:
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.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.二、对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);
接口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值