Не удается заставить ESAPI Validator getValidInput() работать с параметрами URL

Я пытаюсь использовать ESAPI Encoder для идентификации и канонизации параметров запроса в кодировке 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() работает так, а getValidInput() с последним аргументом («canonicalize»), установленным в true, — нет.


person raTM    schedule 03.11.2015    source источник
comment
ОБНОВЛЕНИЕ. Регулярное выражение, определенное в ESAPI.properties для «HTTPParameterValue», выглядит следующим образом: ^[\\p{L}\\p{N}.\\-/+=_ !$*?@]{0,1000}$   -  person raTM    schedule 03.11.2015
comment
В вашем опубликованном коде используется String searchString = "-/+=_ !$*?@";, а не строка в кодировке URL, такая как singleEncoded. Поэтому я ожидаю, что канонизированное значение будет эквивалентно неканонизированной версии.   -  person avgvstvs    schedule 04.11.2015
comment
Спасибо за ваш ответ @avgvstvs .... на ваш вопрос, я согласен, что канонизация делает то, что должна делать. Мой вопрос больше связан с тем, почему второй вызов validator.getValidInput() вызывает исключение, когда все, что от него ожидается, - это канонизировать ввод и проверить, соответствует ли он ожидаемому значению. Другими словами, прямой вызов canonicalize() работает, но вызов getValidInput() завершается ошибкой.   -  person raTM    schedule 04.11.2015


Ответы (1)


Итак, вопрос становится:

почему второй вызов validator.getValidInput() выдает исключение, хотя все, что от него требуется, — это канонизировать ввод и проверить, соответствует ли он ожидаемому значению. Другими словами, прямой вызов canonicalize() работает, но вызов getValidInput() завершается ошибкой.

Что-то здесь очень не так. В версии HTTPParameterValue, которую вы получаете из исходного репозитория OWASP, регулярное выражение ^[a-zA-Z0-9.\\-\\/+=@_ ]*$ Кто-то манипулировал HTTPParameterValue, чтобы он больше походил на SafeString: ^[\\s\\p{L}\\p{N}.]{0,1024}$

См. строку 440.

Это не правильно. Изменять значения ESAPI по умолчанию не следует. Если вам нужны пользовательские изменения, напишите новую запись validator.properties, используя установленный шаблон.

Однако ваш тест все равно не удастся, потому что строка декодируется в -/+=_ !$*?@, а ? является зарезервированным символом в HTTP-запросах.

Из предыдущей спецификации:

3.4. Компонент запроса

Компонент запроса представляет собой строку информации, которую должен интерпретировать ресурс.

  query         = *uric

В компоненте запроса символы ";", "/", "?", ":", "@",
"&", "=", "+", "," и "$" зарезервированы.

Что касается того, почему ввод не выполняется в соответствии с регулярным выражением, в котором вы работаете, ^[\\p{L}\\p{N}.\\-/+=_ !$*?@]{0,1000}$, прочитайте код. В строке 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;

Регулярное выражение проверяется еще до того, как попытается канонизировать ваш ввод.

person avgvstvs    schedule 06.11.2015