Коротко — sessionId может попадать в заголовок из множества мест: из JS на странице (fetch/XHR/ServiceWorker), из хранилищ (localStorage/IndexedDB), из другого запроса/ответа, из расширения браузера или из прокси/сети. Ниже чек‑лист и конкретные приёмы, которые обычно находят источник.
1) Просмотреть всю сетевую историю (включая ранние запросы)
- Вкладка Network → отсортировать по времени, посмотрите запросы, которые выполнялись до POST (HTML, XHR, JS, OPTIONS, GET/JSON и т.п.). Иногда sessionId приходит в теле JSON ответа предыдущего запроса.
- Откройте детали каждого ответа (Response) — ищите sessionId в теле, в заголовках ответа или в Set‑Cookie.
2) Инициатор и стек вызовов
- В Network включите колонку Initiator и у интересующего POST нажмите на инициатор → покажется стек вызовов. Это покажет JS‑файл/строку, где была инициирована отправка и, возможно, где добавлялся заголовок.
- Если инициатор — service worker, iframe или другой скрипт — это уже подсказка.
3) Поиск по исходникам
- Sources → Ctrl+Shift+F (Global search) по ключевым словам: sessionId, session, x-session, setRequestHeader, addRequestHeader и т.п.
- Включите "Pretty print" для минифицированных файлов и поищите хэш‑строки/регекс 32 hex символа.
4) Проверить все клиентские хранилища
- Application (Chrome) / Storage:
- localStorage, sessionStorage
- IndexedDB
- Cookies (проверяйте все домены/поддомены и httpOnly)
- Cache Storage
- Service Worker state
Ищите ключи/значения типа sessionId, sid, token и т.д.
5) Service Worker
- Application → Service Workers: если страница регистрирует SW, он может перехватывать fetch и добавлять заголовок. Проверьте код SW (Sources → Service Worker) на fetch event и модификацию Request/Headers.
6) Перехват добавления заголовка в рантайме
- В консоли можно временно подменить методы и вывести стек:
Пример для XHR:
(function(){
const orig = XMLHttpRequest.prototype.setRequestHeader;
XMLHttpRequest.prototype.setRequestHeader = function(name, value){
if (name.toLowerCase().includes('session')) console.trace('setRequestHeader', name, value);
return orig.apply(this, arguments);
};
})();
Для fetch:
(function(){
const origFetch = window.fetch;
window.fetch = function(input, init){
let headers = (init && init.headers) || (input && input.headers);
// логирование упрощённо:
if (headers){
try{
const h = new Headers(headers);
if (h.get('sessionId') || h.get('x-session-id')) console.trace('fetch headers', [...h.entries()]);
}catch(e){}
}
return origFetch.apply(this, arguments);
};
})();
После этого повторите действие на странице — в консоли получите стек вызовов, кто установил заголовок.
7) Breakpoints (Sources)
- В Sources → XHR/fetch breakpoints — поставить брейкпоинт, тогда DevTools остановит выполнение при вызове fetch/XHR и можно посмотреть стек и локальные переменные.
- Можно также поставить Break on DOM modifications (если клик по элементу запускает POST) на элемент.
8) Расширения / прокси / корпоративные промежуточные устройства
- Запустите страницу в режиме инкогнито (без расширений) или в другом браузере — заголовок исчезнет? Если да — виновато расширение.
- Прокси/файерволл/антивирус/корпоративный прокси могут добавлять заголовки. Проверить с внешним сниффером (Wireshark) или через прокси типа Fiddler/Burp, чтобы увидеть реальные исходящие байты.
9) WebSocket / SharedWorker / iframe / embed
- Проверьте, не создаётся ли sessionId по WebSocket или через сообщение между фреймами (postMessage). Иногда один фрейм получает значение и рассылает в основной.
- Проверьте все iframes и их origin.
10) Проверьте серверные подсказки
- Иногда сервер в раннем ответе (HTML/JSON) отдаёт ключ, а JS собирает sessionId из частей (например hashing + salt). Ищите в исходном HTML и в ответах скриптов куски, которые могут служить сырьём.
11) Инструменты
- DevTools (Network, Sources, Application) — основной набор.
- Fiddler/Burp/curl — увидеть «сырые» заголовки.
- chrome://net‑export → net log для детального трейсинга.
- Если нужно — сохраните HAR и просмотрите вручную.
12) Что ещё вы могли упустить
- Заголовок может быть добавлен из другого домена/субдомена (проверьте domain фильтры).
- Название header может быть немного иным (например X-Session-Id, session-id) — ищите вариации.
- Значение может генерироваться на стороне клиента через crypto.getRandomValues() и просто сохраняться в localStorage при первом заходе.
- HTTP/2/QUIC инфраструктура может маскировать источник — используйте сырой сниффер/прокси.
Если хотите, могу помочь более конкретно — пришлите:
- скриншот вкладки Network с выбранным запросом (Headers + Initiator);
- HAR файл (Export HAR);
- небольшой пример кода или адрес страницы (если доступен публично).
Тогда покажу, где именно искать (или укажу, добавляет ли header расширение/ServiceWorker/JS).