Продвинутые техники кодирования для эзотерических и устаревших веб-систем

Работа с эзотерическими сайтами — это вызов для любого разработчика или исследователя безопасности․ Под «эзотерическими» здесь понимаются не мистические порталы, а ресурсы с нестандартной, устаревшей или плохо документированной архитектурой: легаси-системы банков, закрытые корпоративные порталы, старые форумы на самописных движках, API IoT-устройств или сайты с агрессивными WAF (Web Application Firewall)․ Именно здесь стандартные библиотеки кодирования (вроде encodeURIComponent в JS или urllib․parse․quote в Python) часто бессильны․

Актуально на 19 августа 2026 года․


Фундамент: Зачем вообще кодировать? (По данным OWASP)

Суть процесса

Кодирование выходных данных (Output Encoding) — это преобразование специальных символов в эквивалентные, но безопасные для целевого интерпретатора комбинации․

  • Пример для URL: Пробел становится %20 или +, а амперсанд & — %26, чтобы не разделить параметры запроса․

Почему «эзотерические» сайты ломают стандартные правила?

На Reddit (в треде ELI5: why do websites limit specific special characters?) пользователи справедливо замечали: сайты часто блокируют спецсимволы не из злобы, а из-за страха перед инъекциями или технического долга․ Эзотерические сайты уходят дальше:

  1. Кастомные парсеры: Написанные 15 лет назад стажером регулярные выражения для разбора URL, которые ломаются на %2F (слэш) или %00 (null-байт)․
  2. Двойная обработка (Double Decoding): Запрос проходит через Nginx (декодирует), потом WAF (декодирует снова), потом PHP (urldecode)․ Если вы заранее заэнкодили % в %25, на выходе получите чистый спецсимвол, который «пролезает» фильтры․
  3. Кодировки не UTF-8: Windows-1251, KOI8-R, CP866․ Отправка UTF-8 в форму, ожидающую Windows-1251, превратит «Ш» в «РЎ» или мусор․
  4. WAF/IDS эвристики: Блокируют запросы, содержащие <script>, union select, даже если они заэнкожены․ Приходится использовать обфускацию․

Специфика контекстов: Где стандартные библиотеки подводят

Query String vs Path Parameter vs Fragment

Стандартный encodeURIComponent кодирует /, ?, #․ Но что, если эзотерический API ждет Path Parameter с пробелом?

// Стандарт: /api/user/John%20Doe
// Эзотерика (старые IIS/Apache mod_rewrite): /api/user/John+Doe или даже /api/user/John Doe (сырой пробел!)

Cookie Header Hell

RFC 6265 запрещает в куках запятые, точки с запятой, пробелы․ Но эзотерический бэкенд на Java Servlet API 2․5 может требовать именно сырые кавычки или неэкранированные двоеточия внутри значения․ Стандартные Cookie-jar’ы здесь бессильны — придется собирать заголовок Cookie: вручную строкой․

JSON внутри URL (JSONP / Legacy APIs)

Передача JSON в query-параметре, антипаттерн, но встречается․

  • Сначала JSON-стрингификация (экранирование кавычек ", бэкслешей \)․
  • Потом URL-кодирование всего результата․
  • Подвох: Некоторые парсеры ждут одинарное URL-кодирование, другие — двойное (где % превращается в %25)․

Продвинутые техники для «трудных» случаев

Техника 1: Контекстно-зависимое ручное кодирование (Context-Aware Manual Encoding)

Не верьте фреймворкам․ Пишите свои хелперы для конкретной цели․

function encodeForLegacySearch(query) {
 // 1․ Приводим в целевую кодировку (например, Windows-1251)
 // В браузере: new TextEncoder('windows-1251')․encode(query) -> Uint8Array
 // В Node․js: iconv-lite
  // 2․ Байты в %XX формат (RFC 3986), НО сохраняем ~ ! * ( ) ' как есть, если парсер их не трогает
 // 3․ Заменяем пробел на + (application/x-www-form-urlencoded standard)
 return encodedString;
}

Техника 2: Обход WAF через нюансы декодирования

Если WAF блокирует alert(1), но пропускает aler%74(1) (частичное кодирование), а бэкенд делает urldecode дважды:

  • Отправляем: aler%2574(1) (двойное кодирование символа t)․
  • WAF видит: aler%2574(1) — чисто, сигнатур нет․
  • Nginx (1-й проход): aler%74(1)․
  • Backend (2-й проход): alert(1) — код выполняется․

Внимание: Используйте только на своих стендах/багбаунти с разрешением!

Техника 3: Unicode Normalization Bypass

Эзотерические парсеры часто делают NFKC или NFKD нормализацию после проверки безопасности․

  • Символ ff (U+FB00, LATIN SMALL LIGATURE FF) нормализуется в ff․
  • Полуширинные символы (Halfwidth/Fullwidth forms): < (U+FF1C) -> <․

Техника 4: Null Byte Injection (Legacy)

В старых версиях PHP (< 5․3․4), Perl, C-функциях fopen, include нуль-байт %00 обрезает строку․

// Запрос: file=secret․php%00․jpg
// WAF видит расширение ․jpg -> OK
// Backend (C/Old PHP) видит "secret․php" -> RCE/LFI

В современных реализациях часто блокируется, но в эзотерике — рабочий вектор․


Отладка: Как понять, что съел сервер?

Главная проблема эзотерики — «черный ящик»․ Вы шлете %2527, а в логах (если есть доступ) видите ', %27 или пустоту․

Инструментарий:

  • curl -v —trace-ascii dump․txt: Видим сырые байты, уходящие на кабель․ Критично для проверки кодировки (UTF-8 vs Win-1251)․
  • Python requests с кастомным PreparedRequest: Полный контроль над заголовками и телом без автокодирования․
    req = requests․Request('POST', url, data=raw_payload_bytes, headers={'Content-Type': 'application/x-www-form-urlencoded'})
    prepped = session․prepare_request(req)
    
    session․send(prepped)
  • Эндпоинт-эхо (Reflector): Если есть страница, отражающая ввод (search, 404, callback) — используйте её как зеркало․ Шлите уникальные маркеры: TEST_%E2%80%8B_MARKER (Zero Width Space)․

Чек-лист выживания при интеграции с эзотерическим API

  1. Найдите точку входа: Query param? Body (form-data / urlencoded / json)? Header? Cookie? Path?
  2. Проверьте двойное декодирование: Отправьте %253Cscript%253E․ Если вернется <script>, бэкенд декодирует дважды․
  3. Проверьте нормализацию Unicode: Отправьте полноширинные <script>․ Если сработало — фильтры обходимы․
  4. Тестируйте границы: Null bytes (%00), переносы строк (%0A%0D), табы (%09), невидимые символы (%E2%80%8B)․
  5. Документируйте «анти-паттерны»: «Этот эндпоинт требует плюс вместо %20», «Этот заголовок не любит кавычки», «Тут нужен base64 от urlencoded строки»․

Работа с эзотерическими сайтами, это археология протоколов․ Стандарты (RFC 3986, OWASP Encoding Rules) — это ваш компас, но карта местности (поведение конкретного парсера, WAF, бэкенда) рисуется только руками через пробу и ошибку․

Помните главное: кодирование — это не магия, это соглашение между отправителем и получателем․ Если получатель (эзотерический сайт) нарушает соглашение — вы должны нарушить его так же, но предсказуемо и контролируемо․ Автоматизируйте рутину кастомными энкодерами, логируйте сырой трафик и всегда имейте под рукой Burp Decoder․


Источники: OWASP Proactive Controls C4: Encode and Escape Data; Reddit r/explainlikeimfive (дискуссия о ограничении спецсимволов)․