java esapi_java – 用户提供的url属性的ESAPI XSS预防

我的一个REST API期望一个属性“url”,它希望URL作为用户的输入.我正在使用ESAPI来防止XSS攻击.问题是用户提供的URL就像

http://example.com/alpha?abc=def\u0026amp;phil=key=bdj

来自ESAPI编码器的cannonicalize方法抛出入侵异常,声称输入具有混合编码,因为它是url编码的,并且片段’& phi’被视为HTML编码,因此是例外.

我在清理我的一个应用程序URL时遇到了类似的问题,其中第二个查询参数以’pa’或’pi’开头,并通过HTML解码转换为delta或pi字符.请参考我的previous Stackoverflow question here

现在问题是因为整个URL都是来自用户的输入,我不能简单地解析查询参数并单独清理它们,因为可以结合两个查询参数创建恶意输入并单独清理它们不会在那里工作案件.

示例:& ltscr来自第一个查询参数值和ipt& gtalert(0)的最后一部分;或者某些东西作为下一个查询参数控制上下文的第一部分.

有没有人遇到过类似的问题?我真的很想知道你们实施了哪些解决方案.谢谢你的任何指示.

编辑:’avgvstvs’的以下答案不会引发入侵异常(谢谢!).但是,cannonicalize方法现在更改原始输入字符串. ESAPI将查询参数的& phi视为一些html编码的char并将其替换为’?’焦炭.像我之前在这里链接的问题.区别在于我的应用程序的URL,而这是用户输入.我唯一的选择是在这里保留一份白名单吗?

最佳答案 您在这里遇到的问题是,对URL的不同部分进行编码有不同的规则 – 对于内存,URL中有4个具有不同编码规则的部分.首先,了解为什么在Java中,您需要使用UriBuilder类构建URL. URL

specification将帮助解决细节问题.

Now since the problem is that since the entire URL is coming as input

from the user, I cannot simply parse out the Query parameters and

sanitize them individually, since malicious input can be created

combining the two query parameters and sanitizing them individually

wont work in that case.

这里唯一真正的选择是java.net.URI.

试试这个:

URI dirtyURI = new URI("http://example.com/alpha?abc=def&phil=key%3dbdj");

String cleanURIStr = enc.canonicalize( dirtyURI.getPath() );

对URI.getPath()的调用应该给你一个非百分比编码的URL,如果enc.canonicalize()在那个阶段之后检测到双重编码,那么你真的有一个双重编码的字符串,并且应该通知调用者你将只接受单编码的URL字符串. URI.getPath()非常智能,可以为URL字符串的每个部分使用解码规则.

如果它仍然给你一些麻烦,API reference还有其他方法可以提取URL的其他部分,如果你需要对URL的不同部分做不同的事情.例如,如果您需要手动解析GET请求中的参数,您实际上可以让它返回查询字符串本身 – 它将对其进行解码传递.

============= JUNIT测试用例============

package org.owasp.esapi;

import java.net.URI;

import java.net.URISyntaxException;

import org.junit.Test;

public class TestURLValidation {

@Test

public void test() throws URISyntaxException {

Encoder enc = ESAPI.encoder();

String input = "http://example.com/alpha?abc=def&phil=key%3dbdj";

URI dirtyURI = new URI(input);

enc.canonicalize(dirtyURI.getQuery());

}

}

=================回答更新的问题=====================

没有办法解决它:Encoder.canonicalize()旨在将转义的字符序列减少为简化的本机到Java格式.网址很可能被视为特殊情况,因此很可能会故意将其排除在考虑范围之外.这是我处理你的情况的方式 – 没有白名单,它将保证你受Encoder.canonicalize()的保护.

使用上面的代码获取输入的URI表示.

第1步:规范化除URI.getQuery()之外的所有URI部分

步骤2:使用库解析器将查询字符串解析为数据结构.我会使用来自commons的httpclient-4.3.3.jar和httpcore-4.3.3.jar.然后你会做这样的事情:

import java.net.URI;

import java.net.URISyntaxException;

import java.util.Iterator;

import java.util.List;

import javax.ws.rs.core.UriBuilder;

import org.apache.http.client.utils.URLEncodedUtils;

import org.junit.Test;

import org.owasp.esapi.ESAPI;

import org.owasp.esapi.Encoder;

public class TestURLValidation

{

@Test

public void test() throws URISyntaxException {

Encoder enc = ESAPI.encoder();

String input = "http://example.com/alpha?abc=def&phil=key%3dbdj";

URI dirtyURI = new URI(input);

UriBuilder uriData = UriBuilder.fromUri(enc.canonicalize(dirtyURI.getScheme()));

uriData.path(enc.canonicalize(enc.canonicalize(dirtyURI.getAuthority() + dirtyURI.getPath())));

println(uriData.build().toString());

List params = URLEncodedUtils.parse(dirtyURI, "UTF-8");

Iterator it = params.iterator();

while(it.hasNext()) {

org.apache.http.NameValuePair nValuePair = it.next();

uriData.queryParam(enc.canonicalize(nValuePair.getName()), enc.canonicalize(nValuePair.getValue()));

}

String canonicalizedUrl = uriData.build().toString();

println(canonicalizedUrl);

}

public static void println(String s) {

System.out.println(s);

}

}

我们在这里真正做的是使用标准库来解析inputURL(从而减轻我们的负担),然后在我们解析每个部分之后规范化部分.

请注意,我列出的代码不适用于所有网址类型…网址的部分多于方案/权限/路径/查询. (缺少userInfo或端口的可能性,如果需要,请相应地修改此代码.)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值