我一直在使用ColdFusion 9附带的OWASP ESAPI实用程序。ColdFusion's Builtin Enterprise Security API。 encoder
实用程序非常简单,我相信我让它们正常工作。我的问题在于validator
实用程序。
我可以让他们单独工作 。也就是说,如果我用“无效”数据调用validator.getValidInput()
方法,它将抛出一个我可以捕获的错误。但是,当我尝试在 batch 中调用validator
方法时,我得到一个空指针异常。通过 batch 我的意思是尝试执行验证尝试组。这应该通过传递validator.getValidInput()
方法ValidationErrorList
方法来工作,该参数应该告诉它不要抛出错误,而只是将错误添加到错误列表中。我不能让它在这种模式下工作。我最好的尝试是给我一个空指针异常。
以下是具体错误:
java.lang.NullPointerException
使用此堆栈跟踪:
java.lang.NullPointerException at
org.owasp.esapi.reference.DefaultValidator.getValidInput(DefaultValidator.java:238) at
sun.reflect.GeneratedMethodAccessor377.invoke(Unknown Source) at
sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at
java.lang.reflect.Method.invoke(Unknown Source) at
coldfusion.runtime.StructBean.invoke(StructBean.java:536) at
coldfusion.runtime.CfJspPage._invoke(CfJspPage.java:2393) at
cftest2ecfm989071068.runPage(D:\Web\internet\fboc\test.cfm:19) at
coldfusion.runtime.CfJspPage.invoke(CfJspPage.java:231) at
coldfusion.tagext.lang.IncludeTag.doStartTag(IncludeTag.java:416) at
coldfusion.runtime.CfJspPage._emptyTcfTag(CfJspPage.java:2722) at
cfApplication2ecfc1705903666$funcONREQUEST.runFunction(D:\Web\internet\fboc\Application.cfc:70) at
coldfusion.runtime.UDFMethod.invoke(UDFMethod.java:472) at
coldfusion.runtime.UDFMethod$ReturnTypeFilter.invoke(UDFMethod.java:405) at
coldfusion.runtime.UDFMethod$ArgumentCollectionFilter.invoke(UDFMethod.java:368) at
coldfusion.filter.FunctionAccessFilter.invoke(FunctionAccessFilter.java:55) at
coldfusion.runtime.UDFMethod.runFilterChain(UDFMethod.java:321) at
coldfusion.runtime.UDFMethod.invoke(UDFMethod.java:220) at
coldfusion.runtime.TemplateProxy.invoke(TemplateProxy.java:491) at
coldfusion.runtime.TemplateProxy.invoke(TemplateProxy.java:337) at
coldfusion.runtime.AppEventInvoker.invoke(AppEventInvoker.java:88) at
coldfusion.runtime.AppEventInvoker.onRequest(AppEventInvoker.java:280) at
coldfusion.filter.ApplicationFilter.invoke(ApplicationFilter.java:356) at
coldfusion.filter.RequestMonitorFilter.invoke(RequestMonitorFilter.java:48) at
coldfusion.filter.MonitoringFilter.invoke(MonitoringFilter.java:40) at
coldfusion.filter.PathFilter.invoke(PathFilter.java:94) at
coldfusion.filter.ExceptionFilter.invoke(ExceptionFilter.java:70) at
coldfusion.filter.BrowserDebugFilter.invoke(BrowserDebugFilter.java:79) at
coldfusion.filter.ClientScopePersistenceFilter.invoke(ClientScopePersistenceFilter.java:28) at
coldfusion.filter.BrowserFilter.invoke(BrowserFilter.java:38) at
coldfusion.filter.NoCacheFilter.invoke(NoCacheFilter.java:46) at
coldfusion.filter.GlobalsFilter.invoke(GlobalsFilter.java:38) at
coldfusion.filter.DatasourceFilter.invoke(DatasourceFilter.java:22) at
coldfusion.filter.CachingFilter.invoke(CachingFilter.java:62) at
coldfusion.filter.RequestThrottleFilter.invoke(RequestThrottleFilter.java:126) at
coldfusion.CfmServlet.service(CfmServlet.java:201) at
coldfusion.bootstrap.BootstrapServlet.service(BootstrapServlet.java:89) at
jrun.servlet.FilterChain.doFilter(FilterChain.java:86) at
coldfusion.monitor.event.MonitoringServletFilter.doFilter(MonitoringServletFilter.java:42) at
coldfusion.bootstrap.BootstrapFilter.doFilter(BootstrapFilter.java:46) at
jrun.servlet.FilterChain.doFilter(FilterChain.java:94) at
jrun.servlet.FilterChain.service(FilterChain.java:101) at
jrun.servlet.ServletInvoker.invoke(ServletInvoker.java:106) at
jrun.servlet.JRunInvokerChain.invokeNext(JRunInvokerChain.java:42) at
jrun.servlet.JRunRequestDispatcher.invoke(JRunRequestDispatcher.java:286) at
jrun.servlet.ServletEngineService.dispatch(ServletEngineService.java:543) at
jrun.servlet.jrpp.JRunProxyService.invokeRunnable(JRunProxyService.java:203) at
jrunx.scheduler.ThreadPool$ThreadThrottle.invokeRunnable(ThreadPool.java:428) at
jrunx.scheduler.WorkerThread.run(WorkerThread.java:66)
这是一个简单的测试脚本。你会注意到我有一行注释掉了。该行在没有ErrorList
的情况下工作,但会抛出错误(应该如此)。我试图让方法工作而不抛出错误:
<cftry>
<cfsilent>
<cfparam name="form.TestField" default="" type="string" />
<cfset Esapi = CreateObject("java", "org.owasp.esapi.ESAPI") />
<cfset EsapiEncoder = Esapi.encoder() />
<cfset EsapiValidator = Esapi.validator() />
<cfset Clean = StructNew() />
<cfset Clean.Css = EsapiEncoder.encodeForCss(form.TestField) />
<cfset Clean.Html = EsapiEncoder.encodeForHtml(form.TestField) />
<cfset Clean.HtmlAttribute = EsapiEncoder.encodeForHtmlAttribute(form.TestField) />
<cfset Clean.JavaScript = EsapiEncoder.encodeForJavaScript(form.TestField) />
<cfset Clean.Url = EsapiEncoder.encodeForUrl(form.TestField) />
<cfset Clean.Xml = EsapiEncoder.encodeForXml(form.TestField) />
<cfset ErrorList = CreateObject("java", "org.owasp.esapi.ValidationErrorList") />
<cfset Valid = StructNew() />
<cfset Valid.Input = EsapiValidator.getValidInput("Test Field", form.TestField, "SafeString", 128, false, true, ErrorList) />
<!---<cfset Valid.Input = EsapiValidator.getValidInput("Test Field", form.TestField, "SafeString", 128, false, true) />--->
</cfsilent>
<!DOCTYPE HTML>
<head>
<meta charset='UTF-8' />
<title>ESAPI Test</title>
</head>
<body>
<div>
<h3>ESAPI Test</h3>
<cfoutput>
<form name="frmtest" id="frmtest" action="#cgi.script_name#" method="post">
<p>Enter text to test:</p>
<p><input type="text" name="TestField" id="TestField" size="64" maxlength="128" value="#Clean.HtmlAttribute#" /></p>
<p><input type="submit" name="submit" id="submit" value=" Submit " /></p>
</form>
</cfoutput>
<hr />
<cfdump var="#Clean#" label="Clean Structure" />
<hr />
<cfdump var="#Valid#" label="Valid Structure" />
</div>
</body>
</html>
<cfcatch type="any">
<hr />
<div>
<h3>ERROR</h3>
<cfdump var="#cfcatch#" label="Error" />
</div>
</cfcatch>
</cftry>
当我使用“有效”数据运行此脚本时,它可以正常工作(不会抛出任何错误)。如果我输入“无效”字符,那么我会得到空指针异常。
“有效”数据示例:this is a safe string 0123456789
“无效”数据的示例:this is a safe string 0123456789-
(注意结尾处的连字符)
Here is a link to the documentation that shows what I am trying to implement
对于它的价值,验证“规则”在ColdFusion附带的validation.properties
文件中定义。该文件位于{cfusion lib}目录中。以下是我服务器中该文件的内容:
# The ESAPI validator does many security checks on input, such as canonicalization
# and whitelist validation. Note that all of these validation rules are applied *after*
# canonicalization. Double-encoded characters (even with different encodings involved,
# are never allowed.
#
# To use:
#
# First set up a pattern below. You can choose any name you want, prefixed by the word
# "Validation." For example:
# Validation.Email=^[A-Za-z0-9._%-]+@[A-Za-z0-9.-]+\\.[a-zA-Z]{2,4}$
#
# Then you can validate in your code against the pattern like this:
# ESAPI.validator().isValidInput("User Email", input, "Email", maxLength, allowNull);
# Where maxLength and allowNull are set for you needs, respectively.
#
# But note, when you use boolean variants of validation functions, you lose critical
# canonicalization. It is preferable to use the "get" methods (which throw exceptions) and
# and use the returned user input which is in canonical form. Consider the following:
#
# try {
# someObject.setEmail(ESAPI.validator().getValidInput("User Email", input, "Email", maxLength, allowNull));
#
Validator.SafeString=^[.\\p{Alnum}\\p{Space}]{0,1024}$
Validator.Email=^[A-Za-z0-9._%-]+@[A-Za-z0-9.-]+\\.[a-zA-Z]{2,4}$
Validator.IPAddress=^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$
Validator.URL=^(ht|f)tp(s?)\\:\\/\\/[0-9a-zA-Z]([-.\\w]*[0-9a-zA-Z])*(:(0-9)*)*(\\/?)([a-zA-Z0-9\\-\\.\\?\\,\\:\\'\\/\\\\\\+=&%\\$#_]*)?$
Validator.CreditCard=^(\\d{4}[- ]?){3}\\d{4}$
Validator.SSN=^(?!000)([0-6]\\d{2}|7([0-6]\\d|7[012]))([ -]?)(?!00)\\d\\d\\3(?!0000)\\d{4}$
Validator.CFContainerID=^[\\p{Alnum}_\\-\\.:]+$
Validator.GOOGLEMAPAPI=^[\\p{Alnum}_\\+=\\/\\-]+$
Validator.CFFORMSCRIPTSRC=^[^\\*\\?\"'<>|%]*$
我认为我的想法是为您自己的应用程序添加此文件的规则。
是否有人使用validator.getValidInput()
方法在批处理(验证尝试组)中工作?
更新1
我注意到每次得到空指针异常时,都会在服务器上写入cfusion-out.log
。它让我相信它正在起作用,但在尝试分配验证异常时获得空指针:
06/25 16:08:14 [jrpp-3225] WARN [SECURITY FAILURE Anonymous:null@unknown -> /IntrusionDetector] Invalid input: context=Test Field, type(SafeString)=^[.\p{Alnum}\p{Space}]{0,1024}$, input=this is a safe string 0123456789-
org.owasp.esapi.errors.ValidationException: Test Field: Invalid input. Please conform to regex ^[.\p{Alnum}\p{Space}]{0,1024}$ with a maximum length of 128
at org.owasp.esapi.reference.validation.StringValidationRule.checkWhitelist(StringValidationRule.java:144)
at org.owasp.esapi.reference.validation.StringValidationRule.checkWhitelist(StringValidationRule.java:160)
at org.owasp.esapi.reference.validation.StringValidationRule.getValid(StringValidationRule.java:284)
at org.owasp.esapi.reference.DefaultValidator.getValidInput(DefaultValidator.java:199)
at org.owasp.esapi.reference.DefaultValidator.getValidInput(DefaultValidator.java:236)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at coldfusion.runtime.StructBean.invoke(StructBean.java:508)
at coldfusion.runtime.CfJspPage._invoke(CfJspPage.java:2393)
at cftest2ecfm989071068.runPage(D:\Web\internet\fboc\test.cfm:19)
at coldfusion.runtime.CfJspPage.invoke(CfJspPage.java:231)
at coldfusion.tagext.lang.IncludeTag.doStartTag(IncludeTag.java:416)
at coldfusion.runtime.CfJspPage._emptyTcfTag(CfJspPage.java:2722)
at cfApplication2ecfc1705903666$funcONREQUEST.runFunction(D:\Web\internet\fboc\Application.cfc:70)
at coldfusion.runtime.UDFMethod.invoke(UDFMethod.java:472)
at coldfusion.runtime.UDFMethod$ReturnTypeFilter.invoke(UDFMethod.java:405)
at coldfusion.runtime.UDFMethod$ArgumentCollectionFilter.invoke(UDFMethod.java:368)
at coldfusion.filter.FunctionAccessFilter.invoke(FunctionAccessFilter.java:55)
at coldfusion.runtime.UDFMethod.runFilterChain(UDFMethod.java:321)
at coldfusion.runtime.UDFMethod.invoke(UDFMethod.java:220)
at coldfusion.runtime.TemplateProxy.invoke(TemplateProxy.java:491)
at coldfusion.runtime.TemplateProxy.invoke(TemplateProxy.java:337)
at coldfusion.runtime.AppEventInvoker.invoke(AppEventInvoker.java:88)
at coldfusion.runtime.AppEventInvoker.onRequest(AppEventInvoker.java:280)
at coldfusion.filter.ApplicationFilter.invoke(ApplicationFilter.java:356)
at coldfusion.filter.RequestMonitorFilter.invoke(RequestMonitorFilter.java:48)
at coldfusion.filter.MonitoringFilter.invoke(MonitoringFilter.java:40)
at coldfusion.filter.PathFilter.invoke(PathFilter.java:94)
at coldfusion.filter.ExceptionFilter.invoke(ExceptionFilter.java:70)
at coldfusion.filter.BrowserDebugFilter.invoke(BrowserDebugFilter.java:79)
at coldfusion.filter.ClientScopePersistenceFilter.invoke(ClientScopePersistenceFilter.java:28)
at coldfusion.filter.BrowserFilter.invoke(BrowserFilter.java:38)
at coldfusion.filter.NoCacheFilter.invoke(NoCacheFilter.java:46)
at coldfusion.filter.GlobalsFilter.invoke(GlobalsFilter.java:38)
at coldfusion.filter.DatasourceFilter.invoke(DatasourceFilter.java:22)
at coldfusion.filter.CachingFilter.invoke(CachingFilter.java:62)
at coldfusion.filter.RequestThrottleFilter.invoke(RequestThrottleFilter.java:126)
at coldfusion.CfmServlet.service(CfmServlet.java:201)
at coldfusion.bootstrap.BootstrapServlet.service(BootstrapServlet.java:89)
at jrun.servlet.FilterChain.doFilter(FilterChain.java:86)
at coldfusion.monitor.event.MonitoringServletFilter.doFilter(MonitoringServletFilter.java:42)
at coldfusion.bootstrap.BootstrapFilter.doFilter(BootstrapFilter.java:46)
at jrun.servlet.FilterChain.doFilter(FilterChain.java:94)
at jrun.servlet.FilterChain.service(FilterChain.java:101)
at jrun.servlet.ServletInvoker.invoke(ServletInvoker.java:106)
at jrun.servlet.JRunInvokerChain.invokeNext(JRunInvokerChain.java:42)
at jrun.servlet.JRunRequestDispatcher.invoke(JRunRequestDispatcher.java:286)
at jrun.servlet.ServletEngineService.dispatch(ServletEngineService.java:543)
at jrun.servlet.jrpp.JRunProxyService.invokeRunnable(JRunProxyService.java:203)
at jrunx.scheduler.ThreadPool$ThreadThrottle.invokeRunnable(ThreadPool.java:428)
at jrunx.scheduler.WorkerThread.run(WorkerThread.java:66)
更新2
我一直在挖掘ColdFusion的Damon Miller's implementation of the OWASP ESAPI方法。我在他的代码中注意到他没有使用getValidInput()
属性调用ValidationErrorList
方法。相反,他编写代码来捕获生成的错误,然后将错误添加到列表本身。嗯?我以为这个方法应该为你做那个????
顺便说一句,我试图不使用像他这样的库来避免我不需要的额外膨胀。
摘自他的代码:
if(structKeyExists( arguments, "errorList" )) {
try {
return getValidInput( arguments.context, arguments.input, arguments.type, arguments.maxLength, arguments.allowNull );
}
catch(esapi4cf.org.owasp.esapi.errors.ValidationException e) {
arguments.errorList.addError( arguments.context, e );
}
return arguments.input;
}
else {
...
答案 0 :(得分:6)
这看起来是ESAPI的Coldfusion实现中的一个错误 - 我们在ESAPI的单元测试套件中对getValidInput方法进行了全面覆盖测试,证明该方法与广告一样有效。
根据您上面的第二次更新,我猜想在CF实现代码中有一个未初始化的变量被访问(可能在此上下文中未初始化errorList)
我是OWASP ESAPI项目的项目负责人,非常熟悉ESAPI本身的这段代码,但我不是CF开发人员,也没有看到CF9的所有实现代码。
** 修改 **
为了使验证方法使用ColdFusion批量工作,在调用init()
之前,org.owasp.esapi.ValidationErrorList
类需要调用validator
方法。方法。将以下行添加到测试脚本中,它将起作用:
<cfset ErrorList = ErrorList.init() />
在上下文中:
<cfset ErrorList = CreateObject("java", "org.owasp.esapi.ValidationErrorList") />
<cfset ErrorList = ErrorList.init() />
<cfset Valid.TestField = EsapiValidator.getValidInput("Test Field", form.TestField, "SafeString", 128, true, true, ErrorList) />
现在输入无效输入时,错误将被添加到ErrorList
变量而不是抛出错误。