如何在 ColdFusion 中通过多组验证尝试来实现 OWASP ESAPI 验证器?

2024-04-14

我一直在研究 ColdFusion 9 中包含的 OWASP ESAPI 实用程序。ColdFusion 的内置企业安全 API http://www.petefreitag.com/item/788.cfm. The encoder实用程序非常简单,我相信我让它们工作得很好。我的问题是validator公用事业。

我可以让他们工作singly。也就是说,如果我调用validator.getValidInput()具有“无效”数据的方法会抛出一个我可以捕获的错误。但是,当我尝试致电validator中的方法batch我得到一个空指针异常。经过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-(注意末尾的连字符)

这是我尝试实现的 validator.getValidInput 方法的文档链接 http://owasp-esapi-java.googlecode.com/svn/trunk_doc/latest/org/owasp/esapi/reference/DefaultValidator.html#getValidInput%28java.lang.String,%20java.lang.String,%20java.lang.String,%20int,%20boolean,%20org.owasp.esapi.ValidationErrorList%29.

这是文档的链接,显示了我正在尝试实现的内容 http://owasp-esapi-java.googlecode.com/svn/trunk_doc/latest/org/owasp/esapi/ValidationErrorList.html.

对于它的价值,验证“规则”是在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=^[^\\*\\?\"'<>|%]*$

我认为这个想法是为您自己的应用程序向该文件添加规则。

有没有人得到过validator.getValidInput()工作方法batch(验证尝试组)?


Update 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)


Update 2

我一直在挖掘Damon Miller 的 OWASP ESAPI 实现 https://github.com/damonmiller/esapi4cf/blob/master/esapi4cf/org/owasp/esapi/reference/DefaultValidator.cfcColdFusion 的方法。我注意到在他的代码中他没有调用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 {
    ...

这看起来是 ESAPI 的 Coldfusion 实现中的一个错误 - 我们对 ESAPI 的单元测试套件中的 getValidInput 方法进行了全面覆盖测试,证明该方法按照宣传的方式工作。

根据上面的第二次更新,我猜测在 CF 实现代码中存在一个正在访问的未初始化变量(也许 errorList 在这种情况下未初始化)

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

** Edit **

为了使验证方法使用 ColdFusion 批量工作,请调用init()需要方法org.owasp.esapi.ValidationErrorList class before呼叫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变量而不是抛出错误。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 ColdFusion 中通过多组验证尝试来实现 OWASP ESAPI 验证器? 的相关文章

随机推荐