【问题标题】:Pattern to allow Percentage symbol while using ESAPI使用 ESAPI 时允许百分比符号的模式
【发布时间】:2012-12-28 08:41:36
【问题描述】:

我正在使用 RegEx ^[\\p{L}\\p{N}:\\-.\\s_&.,$()\\*%]*$ 使用 ESAPI 验证其中一个字段。

如果我的输入是1234%1234%%1234%%%%1,它被认为是TRUE。 但是,如果我可以输入%121234%121234%%12,那就失败了。

我的观察是% 符号之后不允许有多个字符/数字

我可以知道我的 RegEx 中是否有任何错误吗? 什么应该是 RegEx 模式以允许任意数量的 % 符号后跟或前跟任何有效字符?

提前致谢。

【问题讨论】:

  • 这很奇怪...正确,如果1234%% 为真,那么1234%%12 也应该为真...
  • 您的正则表达式匹配 [] 中包含的任何字符(考虑转义序列的含义)零次或多次
  • @NaveedS - 是的,我可以输入任意数量的字符/数字/等。并将验证结果设为 TRUE,但不仅限于 % 符号后有多个文字。

标签: java regex symbols esapi


【解决方案1】:

正如所指出的,您的问题不是您的正则表达式,而是您通过DefaultEncoder.getValidInput(args...) 发送的数据包含某种形式的混合编码。

您并没有过多地讨论上下文,但一般来说,您接受的答案存在极大的致命缺陷,不应该向任何人推荐。

您的输入失败,因为已确定,ESAPI 将规范化您的输入,然后将其传递给正则表达式进行验证。规范化真正为您提供的是两件事,但最重要的是 ESAPI 的实现将检测多重编码攻击。

什么是多重编码?它试图通过多次编码一段数据来破坏输入验证。使用百分比编码,它看起来像这样:

ORIGINAL INPUT:
<script>alert('xss');</script>

ENCODED ONCE:
%3Cscript%3Ealert(%27xss%27)%3B%3C%2Fscript%3E

ENCODED TWICE:
%253Cscript%253Ealert(%2527xss%2527)%253B%253C%252Fscript%253E

您的回答,您建议仅关闭百分比编解码器,这给您的应用程序引入了一个巨大的安全漏洞,您无法再检测到攻击是否试图破坏您的输入验证例程。百分比编码是一种非常标准的攻击技术。尝试将代码强制转换为涉及多种编码技术的应用程序有多种方法。

您真正需要的是更好地讨论为什么您的应用程序正在处理的输入需要使用您正在使用的输入类型。什么是具有更大图景的一些示例数据的实际用例?有了你面前的一切,我唯一能做的就是清楚地说明删除百分比编解码器会让你容易受到攻击。

如果你想在没有规范化的情况下临时验证 ESAPI 有

Validator.getValidInput(String context, String input, String type, int maxLength, boolean allowNull, boolean canonicalize);

它允许您暂时关闭规范化。

但是,规范化是存在的,因此您可以确保您正在处理的输入可以安全地用于正则表达式。

【讨论】:

  • 我的应用中有一个用例,其中“%xxx”用作通配符搜索字符串。关闭规范化不是一种选择。任何想法如何处理?
【解决方案2】:

如果不是真的需要,最好的选择是排除百分比编解码器

为此,需要编写自己的自定义编码器实现,扩展 ESAPI 提供的 org.owasp.esapi.reference.DefaultEncoder 并将其注册到 ESAPI.properties 就像

ESAPI.Encoder=path.to.ESAPIDefaultEncoderImpl

参见下面的实现示例。

package path.to;

import java.util.ArrayList;
import java.util.List;

public class ESAPIDefaultEncoderImpl extends org.owasp.esapi.reference.DefaultEncoder
{
private static List<String> codecs;
private static ESAPIDefaultEncoderImpl singletonInstance ;

static
{
    codecs = new ArrayList<String>();
    codecs.add("HTMLEntityCodec ");
    codecs.add("JavaScriptCodec");
    singletonInstance = new ESAPIDefaultEncoderImpl();
}

public static ESAPIDefaultEncoderImpl getInstance()
      {
        return singletonInstance;
      }
      private ESAPIDefaultEncoderImpl()
      {
         super(codecs);
      }
}

在此定制编码器中,不应注册百分比编解码器,而只注册真正需要的编码器。 (要查看所有 ESAPI 编解码器,请访问 ESAPI 文档)。

【讨论】:

  • 如果你没有精心设计的防御策略,这很危险。删除 PercentageCodec 意味着 ESAPI 不会扫描您的输入字符串是否存在多重编码攻击,这意味着您削弱了应用程序的安全性。下面的解决方案要好得多,您可以在其中通过正则表达式进行管理。
【解决方案3】:

感谢您对 NaveedS 和 GauravM 的帮助。

我能够找出确切的问题。支持 % 是 ESAPI 的核心问题。

  • 在进行实际模式匹配之前,ESAPI 用于规范化输入字符串。
  • 此规范化涉及使用各种编解码器,例如 javascript 编解码器、HTML 代码、百分比编解码器
  • 百分比编解码器扫描输入字符串中的% 符号,并将其视为转义字符。它将接下来的两个文字视为HEX数字,例如%123,它将12视为Hex,即18为十进制,因此UP ARROW 符号等同于字符
  • 因此,在规范化之后,输入字符串转换为UPARROW3,但在RegEx ^[\\p{L}\\p{N}:\\-.\\s_&amp;.,$()\\*%]*$ 中不允许UPARROW,它失败了。

作为一种解决方法,在将字符串传递给 ESAPI 进行验证之前,我们可以删除字符串中的所有百分比并在末尾附加一个 %。 这将执行相同的验证。

但是,对于像 Validator.Email=^[A-Za-z0-9._%-]+@[A-Za-z0-9.-]+\\.[a-zA-Z]{2,4}$ 这样的 RegEx,这种解决方法将不起作用。

在这种特殊情况下,作为替代方案,可以编写自己的正则表达式(明确允许在结尾段中使用百分比),例如 Validator.own.Email=^[A-Za-z0-9._%-]+@[A-Za-z0-9.-]+\\.[a-zA-Z%]{3,5}$

希望这会有所帮助。

【讨论】:

    【解决方案4】:

    Nirav 如果您尝试使用数字,请尝试使用下面的正则表达式。 (\d*%+\d*)+

    它将与您的模式匹配,其中包括数字后跟或前面的 %。

    【讨论】:

    • % 可以在任何有效字符之前和之后。不仅仅是数字。
    猜你喜欢
    • 2014-11-25
    • 2015-05-08
    • 1970-01-01
    • 2015-11-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-14
    相关资源
    最近更新 更多