Java,ESAPI验证器的性能问题

时间:2015-04-21 14:19:07

标签: java performance validation esapi

在我们的java Web应用程序中,我们使用ESAPI验证器来验证URL。它完成了我们所期望的,但是花费了太多时间来获得结果(特别是对于错误的URL)。对于一些错误的网址,获得结果需要两分钟以上。以下是使用ESAPI验证器验证URL的方法。

    public static boolean isSecuredURL(String value) {


    return ESAPI.validator().isValidInput("URL", value, "URL", 255, false);

}

我担心频繁使用此方法会影响我的应用程序的性能。还有更好的方法吗?

2 个答案:

答案 0 :(得分:1)

  1. 分析用于验证的正则表达式模式。你正在使用什么样的正则表达式?
  2. 调试Validator代码。
  3. 此外,您可以使用验证器对象的单个实例。编码器是线程安全的。

答案 1 :(得分:0)

两部分答案:回答您的核心问题 - 性能 - 这不是ESAPI问题。在我的职业生涯中,我已经将esapi部署到至少6个生产应用程序中,并且从未遇到过像您所描述的那样的问题。我的猜测是ESAPI在你的应用程序中发现了一些不好的异常处理/重新抛出,特别是如果你正在使用RuntimeExceptions做任何时髦的事情。 ESAPI的主要规范化异常IntrusionException继承自java.lang.RuntimeException。由于它是一个运行时异常,它可能会在堆栈展开时转动,直到系统最终找到可以处理它的处理程序。我的建议是使用像visualJVM或Jprofiler这样的分析工具来找到完全你的问题是什么。现在......到URL验证。

首先,请谨慎使用esapi“验证”网址known pitfalls.

然而,最大的缺陷是选择使用正则表达式来验证像URL一样复杂的东西。 URL的不同部分具有不同的解析规则:

[scheme:][user-info@][host][:port][path][?query][#fragment]

所以,马上,ESAPI 2.0进行了简化,它实际上不应该:一段URL数据只是一个我们可以做的东西的字符串。

如果您想以正则表达式this is what that monster looks like.

捕获它

此外,您需要警惕URL背后的更精细的业务规则。你能以任何方式限制URL吗?这是一个政策问题,超出范围,但它决定了你能做什么。这是我遵循的方法:

您要做的是遵循以下程序:

  1. 使用java.net.URI拆分并执行初始验证通过。这将处理将URI分解为符合RFC-3986的正则表达式。

  2. 根据上面给出的URI解析规则,使用此伪代码:

  3. //完成RFC-3986基本规则......但我们还没有完成!!!!!

    URI dirtyUri = new URI(input);  
    
    StringBuilder sb = new StringBuilder();
    for(Rule rulePart : dirtyUri){
        //Manually rolling this in a StringBuilder probably means you'll
        //have to add in some components based on what ruleParts are available
        //but at least it has no dependencies.
        sb.append(ESAPI.encoder().canonicalize(rulePart));
        //This will take care of everything but URI queries.  These are special.
    }
    
    1. 我使用Google Guava执行此操作,但如果您不想要依赖项,那么您最喜欢的方式是获取Map<String, String>对象。

    2. 获得网址查询参数地图后:

    3. Iterator<Entry<String,String>> iter = map.iterator();

      while(iter.hasNext()){
         Entry<String, String> entry = iter.next();
         sb.append(ESAPI.encoder().canonicalize(entry.getKey()) + "=");
         sb.append(ESAPI.encoder().canonicalize(entry.getValue());
         if(iter.hasNext()){
            sb.append("&");
         }
      }
      

      到达此处后,您将拥有一个URL字符串,该字符串已针对多种编码攻击,混合编码攻击和RFC-3986进行了扫描。此字符串可以安全地运行正则表达式,并避免上述ESAPI简化所导致的问题。

      在validation.properties中,您将定义

      Validator.CustomUrl={customURLRegex}

      处理您对URL数据的任何进一步限制。

      你会这样称呼:

      validator.getValidInput("urlValidation", input, "CustomUrl", MAX_FIELD_SIZE, false)

      在这种情况下,只有在这种情况下,我们才会关闭esapi在验证方面的规范化。 (我们在构造规范化字符串时已经这样做了。)