12 сентября 2016

Баг генерации ссылок в Laravel 4


В случае, если имеется следующий blade шаблон:

<a href="{{ URL::route('index', Input::except('password')) }}">Index</a>

При обычных попытках использовать XSS ничего не получится, и при запросе

http://site.com/index?test<>'"=test<>'"

Будет сгенерирована следующая ссылка:

<a href="http://site.com/index?test%3C%3E%27%22=test%3C%3E%27%22">Index</a>

Но, если использовать числовой параметр:

http://site.com/index?123="><script>alert(1)</script>

То результат будет:

<a href="http://site.com/index?"><script>alert(1)</script>">Index</a>

Код генерации query_string:

    protected function getRouteQueryString(array $parameters)
    {
        // First we will get all of the string parameters that are remaining after we
        // have replaced the route wildcards. We'll then build a query string from
        // these string parameters then use it as a starting point for the rest.
        if (count($parameters) == 0) {
            return '';
        }
        $query = http_build_query(
            $keyed = $this->getStringParameters($parameters)
        );
        // Lastly, if there are still parameters remaining, we will fetch the numeric
        // parameters that are in the array and add them to the query string or we
        // will make the initial query string if it wasn't started with strings.
        if (count($keyed) < count($parameters)) {
            $query .= '&'.implode(
                '&', $this->getNumericParameters($parameters)
            );
        }
        return '?'.trim($query, '&');
    }

Для обычных параметров используется http_build_query, который автоматически делает urlencode, а числовые параметры добавляются без обработки.

В Laravel 5 такого уже нет, так как ссылку кодируют целиком, оставляя только символы из белого списка.

    protected $dontEncode = [
        '%2F' => '/',
        '%40' => '@',
        '%3A' => ':',
        '%3B' => ';',
        '%2C' => ',',
        '%3D' => '=',
        '%2B' => '+',
        '%21' => '!',
        '%2A' => '*',
        '%7C' => '|',
        '%3F' => '?',
        '%26' => '&',
        '%23' => '#',
        '%25' => '%',
    ];
    ...
    $uri = strtr(rawurlencode($uri), $this->dontEncode);

Комментариев нет :

Отправить комментарий