如何在ColdFusion中使用验证尝试组实现OWASP ESAPI验证器?

Mig*_*l-F 3 coldfusion coldfusion-9 esapi cfml

我一直在使用ColdFusion 9附带的OWASP ESAPI实用程序.ColdFusion的Builtin Enterprise Security API.该encoder工具是非常直接的,我相信我有他们工作的罚款.我的问题在于validator公用事业.

我可以让他们单独上班.也就是说,如果我validator.getValidInput()用"无效"数据调用该方法,它将抛出一个我可以捕获的错误.但是,当我尝试批量调用该validator方法时,我得到一个空指针异常.通过批量我的意思是试图执行验证尝试的群体.这应该通过传递方法一个参数来工作,该参数应该告诉它不要抛出错误,而只是将错误添加到错误列表中.我不能让它在这种模式下工作.我最好的尝试是给我一个空指针异常.validator.getValidInput()ValidationErrorList

这是具体的错误:

java.lang.NullPointerException
Run Code Online (Sandbox Code Playgroud)

使用此堆栈跟踪:

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)
Run Code Online (Sandbox Code Playgroud)

这是一个简单的测试脚本.你会注意到我有一行注释掉了.该行无效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>
Run Code Online (Sandbox Code Playgroud)

当我用"有效"数据运行此脚本时,它工作正常(没有抛出错误).如果我输入"无效"字符,那么我得到空指针异常.

"有效"数据this is a safe string 0123456789
示例:"无效"数据示例:( this is a safe string 0123456789-注意结尾处的连字符)

这是我试图实现的validator.getValidInput方法的文档的链接.

这是一个文档的链接,显示了我想要实现的内容.

对于它的价值,验证"规则"在validation.propertiesColdFusion附带的文件中定义.该文件位于{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\\-\\.\\?\\,\\:\\'\\/\\\\\\+=&amp;%\\$#_]*)?$
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=^[^\\*\\?\"'<>|%]*$
Run Code Online (Sandbox Code Playgroud)

我认为这个想法是为你自己的应用程序添加规则到这个文件.

有没有人让这种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)
Run Code Online (Sandbox Code Playgroud)


更新2

我一直在挖掘Damon Miller对ColdFusion 的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 {
    ...
Run Code Online (Sandbox Code Playgroud)

小智 6

这看起来是ESAPI的Coldfusion实现中的一个错误 - 我们在ESAPI的单元测试套件中对getValidInput方法进行了全面覆盖测试,证明该方法与广告一样有效.

根据您上面的第二次更新,我猜想在CF实现代码中有一个未初始化的变量被访问(可能在此上下文中未初始化errorList)

我是OWASP ESAPI项目的项目负责人,非常熟悉ESAPI本身的这些代码,但我不是CF开发人员,也没有看到CF9的所有实现代码.

**编辑**

为了使验证方法使用ColdFusion批量工作,调用方法之前,init()需要对该org.owasp.esapi.ValidationErrorList类调用该方法.将以下行添加到测试脚本中它将起作用:validator

<cfset ErrorList = ErrorList.init() />
Run Code Online (Sandbox Code Playgroud)

在上下文中:

<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) />
Run Code Online (Sandbox Code Playgroud)

现在输入无效输入时,错误将被添加到ErrorList变量而不是抛出错误.