在我们的java Web应用程序中,我们使用ESAPI验证器来验证URL。它完成了我们所期望的,但是花费了太多时间来获得结果(特别是对于错误的URL)。对于一些错误的网址,获得结果需要两分钟以上。以下是使用ESAPI验证器验证URL的方法。
public static boolean isSecuredURL(String value) {
return ESAPI.validator().isValidInput("URL", value, "URL", 255, false);
}
我担心频繁使用此方法会影响我的应用程序的性能。还有更好的方法吗?
答案 0 :(得分:1)
答案 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吗?这是一个政策问题,超出范围,但它决定了你能做什么。这是我遵循的方法:
您要做的是遵循以下程序:
使用java.net.URI
拆分并执行初始验证通过。这将处理将URI分解为符合RFC-3986的正则表达式。
根据上面给出的URI解析规则,使用此伪代码:
//完成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.
}
我使用Google Guava执行此操作,但如果您不想要依赖项,那么您最喜欢的方式是获取Map<String, String>
对象。
获得网址查询参数地图后:
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在验证方面的规范化。 (我们在构造规范化字符串时已经这样做了。)