Русский

Инструменты разработчика · Кодер и декодер URL

Кодирование перенаправления URL внутри параметра запроса без его нарушения

· Как это работает

URL-кодировка параметры запроса безопасность клятва

Полный URL, закодированный как одно значение параметра запроса, сохраняющий структуру посредством процентного кодирования.
Оригинальная векторная иллюстрация ToolAcre

Вложение одного URL в другой является наиболее распространенной причиной неправильного процентного кодирования. В этом посте показано, почему внутренние символы URL ?, & и = должны быть закодированы, как это сделать и как проверить результат.

Ссылка возврата, в которой удалена половина своих параметров — внутренние URL, поглощенные внешней строкой запроса.

Ссылка возврата, потерявшая половину своих параметров, — это шаблон отладки, с которым сталкивается каждый разработчик. Пользователь входит в систему, приложение пытается перенаправиться на ?next=https://example.com/page?id=1&user=alice,, и в итоге он попадает на example.com/page?id=1. Амперсанд во внутреннем URL анализировался как разделитель между внешними параметрами запроса. Два URL-адреса с разными разделителями означают, что внутренний URL-адрес необходимо закодировать.

При вложении одного URL в другой в качестве параметра запроса этот внутренний адрес становится непрозрачными данными для внешнего уровня. Знак вопроса, амперсанд и знак равенства не должны читаться как структурные разделители. Процентное кодирование преобразует их: становится %3F, & становится %26, = становится %3D. Внешний анализатор затем обрабатывает закодированную строку как одно значение параметра.

Два URL-адреса, два набора разделителей — почему внутренний URL является всего лишь значением для внешнего

encodeURIComponent для полного внутреннего URL обеспечивает полную защиту: encodeURIComponent("https://example.com/a?b=1&c=2") возвращает "https%3A%2F%2Fexample.com%2Fa%3Fb%3D1%26c%3D2". символ становится обозначением %XX, поэтому внешний синтаксический анализатор не может неправильно интерпретировать вложенные разделители. Конкурирующий подход, такой как encodeURI, оставляет косые черты и вопросительные знаки нетронутыми, снова создавая двусмысленность, когда этот результат становится значением запроса.

Сервер декодирует ровно один раз. После извлечения следующего параметра один вызов decodeURIComponent восстанавливает внутренний URL в исходную форму. Анализ результата как новой строки запроса позволяет увидеть правильную структуру параметров. Двойное декодирование представляет собой риск, когда одно и то же значение проходит через несколько уровней; %26 становится & после одного декодирования и остается & после второго.

encodeURIComponent для всего внутреннего URL — что кодируется, включая :, / и ?

Основное правило простое: любой символ, имеющий значение в синтаксисе URL, включая : / ? = & #, должен быть закодирован в процентах, когда он появляется в значении параметра запроса. Это гарантирует, что внешний синтаксический анализатор увидит только нужную вам структуру параметров, а не какие-либо случайные разделители, скрытые внутри передаваемого вами значения. Используйте encodeURIComponent для полной и надежной обработки этого кодирования.

Проверьте эту кодировку в кодере и декодере URL: вставьте внутренний URL, закодируйте его в режиме значений, наблюдайте за выводом %XX. Используйте режим декодера, чтобы проверить точное совпадение туда и обратно. Этот инструмент демонстрирует сквозное кодирование, поэтому вы можете с уверенностью копировать результаты непосредственно в код приложения.

Рабочий пример: правильное построение ?next=https://example.com/a?b=1&c=2 — закодированная строка и декодирование на стороне сервера

Критическая граница безопасности находится рядом с кодированием. Сервер должен убедиться, что декодированный пункт назначения действительно безопасен для перенаправления. Процентное кодирование делает структуру URL однозначной; это не делает произвольные URL-адреса безопасными. Уязвимости открытого перенаправления возникают, когда приложения слепо следуют URL-адресам, предоставленным пользователем. Для проверки требуется явный список разрешенных, проверка домена или подтверждение пользователя.

Кодирование решает проблему синтаксического анализа; проверка устраняет проблему безопасности. Это отдельные проблемы на разных уровнях. Кодер и декодер URL правильно демонстрируют кодирование. Сервер должен добавить проверку: сверить со списком, проверить домен или запросить подтверждение. Без проверки правильно закодированное перенаправление на любой домен остается уязвимым.

Риск открытого перенаправления — почему сервер должен проверять декодированный пункт назначения, а не просто декодировать его

Здесь накапливаются типичные ошибки. Разработчики иногда кодируют только часть запроса, оставляя косые черты нетронутыми, что нарушает структуру. Другие кодируют весь созданный параметр, включая ?next=, создавая двойное кодирование. Некоторые проверяют достоверность путем анализа без декодирования, неправильно считывая закодированную структуру. Сборка с помощью encodeURIComponent обеспечивает согласованность и корректность в каждом случае.

Другая распространенная ошибка — доверять браузеру автоматически исправить неверный параметр. URL-адреса — это данные, и с ними следует обращаться именно как с данными. encodeURIComponent — стандартный инструмент для этой работы. Кодер и декодер URL сохраняет этот процесс локальным, поэтому вы можете проверить точные байты перед отправкой в ​​производство.

Распространенные ошибки — кодирование только части запроса или доверие браузеру для его исправления.

Параметры OAuth redirect_uri точно соответствуют этому шаблону. Сервер авторизации передает управление клиенту по известному адресу, часто полному URL с несколькими параметрами. Кодирование его как одного значения гарантирует, что параметры сохранятся при транспортировке, и клиент декодирует их один раз перед использованием. Неправильное кодирование в потоках OAuth приводит к исчезновению токенов и параметров обратного вызова в середине передачи.

Параметры состояния в OAuth используют кодировку в сочетании с криптографическими подписями для защиты CSRF. Идентификаторы фрагментов остаются на стороне клиента и никогда не передаются на сервер. Токены-носители никогда не должны размещаться в URL-адресах перенаправления независимо от кодировки, поскольку URL-адреса появляются в журналах, истории браузера и заголовках реферера.

Что здесь не распространяется — параметры состояния OAuth и конструкция защиты CSRF.

Стратегия тестирования: построить свой внутренний URL с реальными параметрами, закодировать его как внешнее значение, декодировать в принимающем коде. Убедитесь, что декодированный результат побайтно идентичен оригиналу. Используйте кодировщик и декодер URL перед развертыванием в рабочей среде. Проверьте сетевой трафик и журналы, чтобы убедиться в правильности поступления и отсутствии усечения или искажения закодированных данных.

Опечатка типа %2e вместо %2E может декодироваться правильно, но не пройти двусторонние проверки во вторичных системах, которые ожидают согласованности. Несоответствия кодировки между библиотеками на разных платформах редки, но возможны; тестирование полного пути туда и обратно выявляет их до того, как они вызовут производственные проблемы и жалобы клиентов.

Вывод: относитесь к внутреннему URL как к данным — как однозначный режим кодера и декодера URL полностью кодирует его, а его декодер подтверждает передачу туда и обратно.

Граница кодирования ясна: encodeURIComponent обрабатывает вводимые вами данные как непрозрачные данные и экранирует все символы, кроме незарезервированных знаков препинания, что позволяет безопасно вкладывать их в любой слой URL. Граница проверки является отдельной: после декодирования убедитесь, что пункт назначения — это то место, куда пользователь намеревался отправиться. Используйте кодировщик и декодер URL, чтобы просмотреть сквозное кодирование.

С самого начала относитесь к внутреннему URL как к данным. Закодируйте его как одно значение запроса, декодируйте ровно один раз при получении, а затем примените проверку перед перенаправлением. Кодер и декодер URL отображает процентное кодирование любого полного URL как одно значение запроса и локально проверяет туда и обратно. И кодирование, и проверка важны; этот инструмент правильно обрабатывает кодировку.