当前位置: 首页 > 面试题库 >

用户提供的url属性的ESAPI XSS防护

董品
2023-03-14
问题内容

我的REST API之一期望属性“ url”,该属性期望URL作为用户的输入。我正在使用ESAPI来防止XSS攻击。问题是用户提供的URL类似于

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

来自ESAPI编码器的cannonicalize方法在此处引发入侵异常,声称输入具有混合编码,因为该输入是url编码的,而段’&phi’被视为HTML编码,因此是该异常。

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

现在,由于问题在于,由于整个URL都是作为用户输入的,因此我无法简单地解析出Query参数并分别对其进行清理,因为可以将两个查询参数组合在一起创建恶意输入,并分别对其进行清理,因此无法正常工作。案件。

示例:&ltscr是第一个查询参数值的最后一部分,ipt&gtalert(0); 或作为下一个查询参数控制上下文的第一部分。

有没有人遇到过类似的问题?我真的很想知道你们实施了什么解决方案。感谢您的指导。

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


问题答案:

您在这里面临的问题是,对URL的不同部分进行编码有不同的规则-
为了存储URL中的4个部分,它们具有不同的编码规则。首先,了解为什么在Java中,您需要使用UriBuilder该类来构建URL 。URL
规范将帮助您了解细节。

现在,由于问题在于,由于整个URL都是作为用户输入的,因此我无法简单地解析出Query参数并分别对其进行清理,因为可以将两个查询参数组合在一起创建恶意输入,并分别对其进行清理,因此无法正常工作。案件。

唯一真正的选择是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引用还有其他方法可以提取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形式。URL很可能被视为特殊情况,因此有意将其排除在考虑范围之外。这是我处理您的案件的方式-
没有白名单,这将确保您受到的保护Encoder.canonicalize()

使用上面的代码来获取输入的URI表示形式。

步骤1:将所有URI部分规范化,除了URI.getQuery()
步骤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<org.apache.http.NameValuePair> params = URLEncodedUtils.parse(dirtyURI, "UTF-8");
    Iterator<org.apache.http.NameValuePair> 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(从而减轻了我们的所有负担),然后在解析完每个部分之后对这些部分进行规范化处理。

请注意,我列出的代码不适用于 所有 url类型… URL的内容比scheme / authority / path /
query还要多。(缺少userInfo或port的可能性,如果需要,请相应地修改此代码。)



 类似资料:
  • 我有三个实体。(在本例中,我使用xxx作为占位符) 我已经用 然而,我能够做到: 只适用于它们各自存储库中的一个实体。当我试图为另外两个实体这样做时,我遇到了这个问题: “派生查询无效!找不到类型xxx的属性id!” 我能够运行它并得到正确的结果。但是为什么我得到了两个实体的这个错误,而不是另一个? 我以完全相同的方式设置实体和它们的存储库。唯一的区别是,在存储库不返回任何错误的实体中,我将该实体

  • 在Angular13应用程序中的一个html文件中,我使用了一个元素,我想通过Angular {{attribute的值}}的双重绑定方法提供属性列表及其值,以便可以显示社交媒体图标列表。 例如,这样做,而不是硬编码: 我想这样做: 但是我一直收到下面的错误信息: 错误 NG8002:无法绑定到“xmlns”,因为它不是“:svg:svg”的已知属性。xmlns=“{{socBtn.xmlns}}

  • 我正在使用Cognito用户池,我想知道我们是否有办法创建一个可供所有用户使用的自定义全局属性?我之所以要创建此属性,是因为我们希望以后只使用一个时间和地点更新属性。

  • 嘿,伙计们,我一直在尝试确定Spring boot中的哪些属性是由用户配置的,而不是Spring自动配置。我可以列出所有属性,但我不确定如何只获取用户声明的属性。 //此方法获取Spring环境中的所有属性 有没有办法只获取用户在如下文件中声明的属性:application。房产?

  • 问题内容: 我正在用来创建用户并处理身份验证。 当我尝试通过方法通过简单登录创建新用户时,如果已经使用了电子邮件地址,firebase不会创建该用户。但是,在创建用户并将其用作密钥之后,我还用于将创建的用户保存到我的Firebase中。尝试写入数据库时​​,即使用户名不是唯一的,firebase也会保存记录,因为简单登录只需要电子邮件和密码。因此,当用户名不用作用户对象的密钥时,如何验证其唯一性?

  • 这个问题更侧重于理解maven的生命周期,而不是解决一个真正的问题。 我们有一个包含几个maven模块的项目。Jacoco和Surefire插件都是在父pom中配置的。xml格式如下: 这种配置运行良好,jacoco。执行常见目标时,会在目标目录上创建exec文件,例如: 或 但如果我们执行以下命令,jacoco。未创建exec文件: 通过使用-X选项分析日志,surefire插件表明它将按照预期