我正在尝试使用ESAPI编码器来识别和规范化URL编码的查询参数。它可以正常工作,但不能按照API指示的方式工作。这是我的课程,下面是其生成的输出:



package test.test;

import org.owasp.esapi.ESAPI;
import org.owasp.esapi.Validator;
import org.owasp.esapi.errors.EncodingException;
import org.owasp.esapi.errors.IntrusionException;
import org.owasp.esapi.errors.ValidationException;

public class ESAPITester {

    public static void main(String argsp[]) throws ValidationException,
    IntrusionException, EncodingException {

        String searchString = "-/+=_ !$*?@";
        String singleEncoded = ESAPI.encoder().encodeForURL(searchString);
        String doubleEncoded = ESAPI.encoder().encodeForURL(singleEncoded);
        Validator validator = ESAPI.validator();
        System.out.println("Searched        : " + searchString);
        System.out.println("Single encoded  : " + singleEncoded);
        System.out.println("Double encoded  : " + doubleEncoded);
        System.out.println("Decode from URL : " + ESAPI.encoder().decodeFromURL(singleEncoded));
        System.out.println("Canonicalized   : " + ESAPI.encoder().canonicalize(singleEncoded));
        System.out.println("Valid input     : " + validator.getValidInput("http",
                searchString, "HTTPParameterValue", 100, true, true));
        System.out.println("Valid from Encoded : " + validator.getValidInput("http",
                singleEncoded, "HTTPParameterValue", 100, true, true));

    }
}


输出值

Searched        : -/+=_ !$*?@
Single encoded  : -%2F%2B%3D_+%21%24*%3F%40
Double encoded  : -%252F%252B%253D_%2B%2521%2524*%253F%2540
Decode from URL : -/ =_ !$*?@
Canonicalized   : -/+=_+!$*?@
Valid input     : -/+=_ !$*?@
log4j:WARN No appenders could be found for logger (IntrusionDetector).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
Exception in thread "main" org.owasp.esapi.errors.ValidationException: http: Invalid input. Please conform to regex ^[\p{L}\p{N}.\-/+=_ !$*?@]{0,1000}$ with a maximum length of 100
    at org.owasp.esapi.reference.validation.StringValidationRule.checkWhitelist(StringValidationRule.java:144)
    at org.owasp.esapi.reference.validation.StringValidationRule.checkWhitelist(StringValidationRule.java:160)
    at org.owasp.esapi.reference.validation.StringValidationRule.getValid(StringValidationRule.java:284)
    at org.owasp.esapi.reference.DefaultValidator.getValidInput(DefaultValidator.java:214)
    at test.test.ESAPITester.main(ESAPITester.java:25)


我的问题是:为什么getValidInput()无法规范化URL编码的输入参数?我很好奇为什么canonicalize()方法会这样做,但最终参数('canonicalize')设置为true的getValidInput()却没有。

最佳答案

所以问题变成了:


  为什么第二个validator.getValidInput()调用会引发异常,何时
  预期要做的就是规范输入并验证
  它与期望值匹配。换句话说,直接呼叫
  canonicalize()有效,但是对getValidInput()的调用失败。


这里有些错误。在从OWASP源存储库中获得的HTTPParameterValue版本中,正则表达式为^[a-zA-Z0-9.\\-\\/+=@_ ]*$有人操纵HTTPParameterValue使其看起来更像SafeString^[\\s\\p{L}\\p{N}.]{0,1024}$

See line 440.

错了不应更改默认的ESAPI值,如果需要自定义更改,请使用已建立的模式编写一个全新的validateator.properties条目。

但是,您的测试仍将失败,因为字符串会解码为-/+=_ !$*?@,并且?是http查询中的保留字符。

From an earlier spec:


  3.4。查询组件
  
  查询组件是要由其解释的信息字符串
  资源。

  query         = *uric

  
  在查询组件中,字符“;”,“ /”,“?”,“:”,“ @”,
  保留“&”,“ =“,“ +”,“,”和“ $”。


关于为什么输入失败的原因是您运行的正则表达式^[\\p{L}\\p{N}.\\-/+=_ !$*?@]{0,1000}$read the code.在第266行,您将看到受影响的方法。

这是您要查看的内容:

public String getValid( String context, String input ) throws ValidationException
    {
        String data = null;

        // checks on input itself

        // check for empty/null
        if(checkEmpty(context, input) == null)
            return null;

        if (validateInputAndCanonical)
        {
            //first validate pre-canonicalized data

            // check length
            checkLength(context, input);

            // check whitelist patterns
            checkWhitelist(context, input);

            // check blacklist patterns
            checkBlacklist(context, input);

            // canonicalize
            data = encoder.canonicalize( input );

        } else {

            //skip canonicalization
            data = input;
        }

        // check for empty/null
        if(checkEmpty(context, data, input) == null)
            return null;

        // check length
        checkLength(context, data, input);

        // check whitelist patterns
        checkWhitelist(context, data, input);

        // check blacklist patterns
        checkBlacklist(context, data, input);

        // validation passed
        return data;


正则表达式会在甚至试图规范化您的输入之前进行检查。

09-05 14:16