HTTPS, TLS і безпека
Зміст
Запит із браузера летить через пристрої, яких ви не контролюєте: домашній роутер, провайдера, магістральні вузли, балансувальники на боці сервера. Кожен фізично здатен прочитати чи підмінити те, що передається, — і HTTPS існує рівно для того, щоб зробити це недосяжним на практиці. Для AQA це не абстракція: сертифікат стенда, у , кукі з HttpOnly, яку не видно з JavaScript, сувора політика, що блокує ваш власний допоміжний скрипт, — усе це щодня вирішує, зелений прогін чи «падає без причини».
Ця глава — канон механіки на сайті: інші глави посилаються сюди по те, як улаштований захищений канал і політики браузера навколо нього. Глибші перевірки — набори шифрів і конфігурація транспорту, повна валідація сертифіката, склад , типи й пейлоади XSS — предмет розділу про безпеку. Мета одна: за хвилину сказати, який саме шар зупинив запит — TLS, політика браузера чи застосунок — і чому.
HTTPS — це HTTP усередині TLS
HTTPS — це звичайний HTTP, загорнутий у криптографічний шар TLS (Transport Layer Security): спершу встановлюється захищений канал, і вже всередині нього ходить знайомий HTTP-трафік. Семантика при цьому не змінюється — ті самі методи, заголовки й коди статусів, які розбирає глава «HTTP: методи, структура, заголовки».
Головна мета TLS — дати захищений канал між двома сторонами, і від транспорту він вимагає лише надійного впорядкованого потоку даних; на практиці це TCP. Сам протокол має дві частини: (handshake) автентифікує сторони й узгоджує параметри та ключі, а record-протокол цими параметрами захищає трафік.
Три гарантії й асиметрія лише на старті
TLS дає рівно три гарантії, і плутати їх не варто — вони закривають різні . Автентифікація: сервер автентифікується завжди, клієнт — опційно. Конфіденційність: після встановлення каналу дані видно лише кінцевим точкам. Цілісність: зміну даних у дорозі буде виявлено.
Ключова ідея рукостискання — асиметрична криптографія працює лише на старті, щоб сторони узгодили спільний симетричний ключ сесії; далі трафік шифрується швидким . Ефемерний обмін ключами дає (perfect forward secrecy). Свою особу сервер доводить трьома повідомленнями: Certificate, CertificateVerify — підпис усього рукостискання приватним ключем — і Finished. У TLS 1.3 усе після ServerHello уже зашифроване, зокрема й сам сертифікат.
Опційність клієнтської автентифікації має практичний наслідок: за замовчуванням сервер не знає, хто до нього прийшов, доки користувач не увійде вже всередині каналу. Саме цю дірку закриває (mutual TLS, mTLS), де сторони автентифікують одна одну, — і в тестах він вимагає окремо налаштованого клієнтського сертифіката.
Наша практика (не канон). Специфікація каже лише «provide forward secrecy». Явна назва ECDHE і звичне формулювання «витік приватного ключа сервера пізніше не розшифрує раніше записаний трафік» — наші робочі формули, у джерелі їх немає.
Версії: «заборонено» і «застаріло» — різні слова
Тут кандидати найчастіше говорять з памʼяті, а точна відповідь коротка. Чинна версія за специфікацією одна — TLS 1.3. RFC 8446 обсолетить попередницю і в шапці, і в тексті: «This document supersedes and obsoletes previous versions of TLS, including version 1.2». Тобто називати TLS 1.2 «актуальною версією» з джерел не випливає.
Але TLS 1.2 і не заборонений — на відміну від решти. Заборони адресні, і кожна має власний документ IETF:
| Версія | Статус | Документ |
|---|---|---|
| TLS 1.3 | чинна | RFC 8446 |
| TLS 1.2 | обсолетнута, але не заборонена | RFC 8446 |
| TLS 1.1 і TLS 1.0 | MUST NOT be used | RFC 8996 |
| SSL 3.0 | MUST NOT be used, узгодження заборонене | RFC 7568 |
| SSL 2.0 | клієнту заборонено надсилати CLIENT-HELLO цього формату | RFC 6176 |
Звідси й правильна підстава практичної межі «TLS 1.2 і вище»: не «актуальність», а відсутність заборони. І тонкість, яку легко втратити при переказі: заборонено узгоджувати старий протокол, а не розпізнавати його байти — сервер MAY і далі приймати повідомлення у форматі SSL 2.0, «Note that this does not contradict the prohibition against actually negotiating the use of SSL 2.0».
Наша практика (не канон). Слово «допустима» щодо TLS 1.2 — наше: специфікації оперують обсолетністю й заборонами, а категорії «допустимість» у них немає.
Що посередник бачить, а що ні
TLS шифрує тіло й заголовки HTTP, але не приховує сам факт зʼєднання. бачить IP-адресу сервера і — через SNI (Server Name Indication) у рукостисканні — доменне імʼя, до якого ви йдете. Конкретний шлях, параметри запиту, кукі й тіло лишаються закритими. Тобто «на який сайт ви пішли» здебільшого видно, а «що саме ви там відкрили» — ні.
Звідси випливає пастка. Секрет у query-рядку не захищений навіть по HTTPS — не тому, що канал слабкий, а тому, що повний URL осідає поза каналом: у логах серверів і , в історії браузера, у заголовку Referer і в аналітиці. Місце секрету — заголовок Authorization зі схемою Bearer або тіло POST.
Наша практика (не канон). Того, що посередник бачить SNI у відкритому вигляді, RFC 6066 прямо не каже — це наш висновок із того, що імʼя передається в ClientHello до встановлення захисту.
Сертифікат стенда — і чому прогін падає вранці
Сертифікат — файл формату X.509, який повʼязує доменне імʼя з відкритим ключем сервера. Браузер перевіряє ланцюг підписів до довіреного кореня, збіг домену з полем SAN (Subject Alternative Name), строк дії та відкликання. Якщо хоч одна перевірка не проходить — зʼєднання не встановлюється, і жодного застосунку тест не побачить.
На dev і staging сертифікат часто самопідписаний — для внутрішнього стенда це звична практика. Обходити помилку кліком «Advanced → Proceed» у прогоні незручно й ненадійно, тому інструменти дають прапорці: ignoreHTTPSErrors у Playwright, acceptInsecureCerts у WebDriver, -k у curl.
// тільки для проєкту, де self-signed справді очікуваний
export default defineConfig({
projects: [
{
name: 'staging',
use: { baseURL: 'https://staging.internal', ignoreHTTPSErrors: true },
},
],
});
Компроміс усвідомлений: вимкнена перевірка робить тест сліпим до реальних помилок конфігурації сертифіката. Тому вмикають точково, а не глобально «щоб не заважало». Кращий варіант — додати кореневий сертифікат внутрішнього CA у сховище довіри агента CI: тоді ланцюг стає валідним по-справжньому.
Наша практика (не канон). Прострочений уночі сертифікат стенда — реальна причина масового «падіння» тестів уранці; це наше спостереження, а не норма документа. Наслідок практичний: перш ніж лізти в код, відкрийте середовище руками й гляньте на значок біля адреси.
HSTS: схема переписується ще до мережі
Strict-Transport-Security — заголовок, яким сервер каже браузеру ходити на цей домен лише захищено. Перше: у HTTP-відповіді він не працює. Специфікація прямо забороняє його там надсилати, а браузер такий заголовок ігнорує — отже, перевіряти треба на HTTPS-відповіді, і заголовок у відкритій відповіді є порушенням, а не зайвою обережністю.
# так він виглядає у відповіді по HTTPS: час життя політики і поширення на піддомени
HTTP/1.1 200 OK
Strict-Transport-Security: max-age=31536000; includeSubDomains
Далі найважливіше для автотестів. Коли браузер збирається завантажити будь-який http-URI відомого HSTS-хоста, він MUST замінити схему на https, а явний порт 80 — на 443, і це відбувається до першого мережевого запиту. Тому базовий URL із жорстко зашитим http:// на такому домені мовчки перепишеться: перевіряти треба фактичну схему у відповіді, а не ту, що ви набрали. Сам факт редиректу http→https перевіряється інакше — автопрямування вимикають і проміжний код разом із Location (постійні редиректи це 301 і 308).
Ще дві межі, які економлять години. Політика переживає зникнення заголовка: хост лишається відомим HSTS-хостом до кінця max-age, тож «заголовок прибрали» видно в заголовках, а не в поведінці. І на такому хості зникає «клікнути далі» повз помилку сертифіката — браузер не пропонує продовжити, а специфікація вимагає обірвати зʼєднання за будь-якої помилки транспорту. Директива preload при цьому незворотна — «can have PERMANENT CONSEQUENCES».
Змішаний контент: «елемент не зʼявився без причини»
Змішаний контент (mixed content) — це коли сторінка завантажена по HTTPS, а частину ресурсів тягне по HTTP. Значок обіцяє захист, а частина трафіку йде відкрито: такий ресурс можна прочитати або підмінити, і найнебезпечніші тут скрипти — вони змінюють будь-що на сторінці.
Чинний поділ — на оновлюваний (upgradable) і блокований (blockable) вміст. Оновлюваний запит браузер сам переписує зі схеми http на https; якщо сервер там ресурсу не віддає, запит просто зазнає невдачі — відкоту на HTTP немає. Блокованим є все, що не оновлюване: <script src>, стилі через <link href>, <iframe src>, а також fetch() і XMLHttpRequest. Старі назви «активний» і «пасивний» джерело відносить до ранішої редакції специфікації — у баг-репорті надійніше писати «блокований» і «оновлюваний».
Пастка
Межа проходить не лише по типу ресурсу, а й по способу задання джерела. До оновлюваних належить <img>, чиє джерело задано атрибутом src (включно з SVG-документами), але той самий <img> зі srcset чи всередині <picture> стоїть у переліку блокованих. Плюс окреме правило поверх усього: запити, які інакше були б підвищені, блокуються, якщо хостом у URL є IP-адреса, а не доменне імʼя.
Слід у консолі є завжди: браузер попереджає і про підвищення, і про блокування. Тому діагностика «елемент не зʼявився» починається з консолі, а не з нарощування :
page.on('console', (msg) => {
if (msg.type() === 'error') console.log('BROWSER:', msg.text());
});
Три межі, на яких плутаються найчастіше. Локальний стенд блокувань не відтворює: file:-URL і loopback-адреси (http://127.0.0.1/, http://localhost/) вважаються захищеними , тож перевіряти треба на адресі з доменним імʼям. Навігація з HTTPS-сторінки на HTTP-сторінку змішаним контентом не вважається — створюється новий контекст. І симптом не завжди виглядає як «немає картинки»: заблокованим може бути fetch, і тоді сторінка лишається без даних. Масово перевести підресурси на HTTPS вміє директива CSP upgrade-insecure-requests.
Той самий механізм пояснює річ, яку часто заводять як баг реалтайму: зі сторінки на https не відкрити ws://. Схем WebSocket дві, і поверх TLS працює саме wss; деталі — глава «WebSockets і реалтайм».
Наша практика (не канон). Ланцюжок «заблокований скрипт → тест не бачить елемент → флак» і типовий корінь — зашитий http:// у конфізі після переїзду стенда на HTTPS — це наші висновки; джерело описує лише блокувальну поведінку.
Походження: схема — це безпекова межа
Походження (origin) — це трійка «схема + хост + порт». Дві адреси належать одному походженню тоді й лише тоді, коли збігаються всі три складові, тож інша схема — це вже інше походження. Типовий порт схеми https — 443, і в адресі його опускають: https://app.example.com і https://app.example.com:443 — те саме походження.
Навіщо це в главі про транспорт. Браузер групує адреси в походження як домени захисту: доступ до обʼєктів дозволено тоді й лише тоді, коли адреси належать одному походженню. Звідси формальне означення XSS: документ несе повні повноваження свого походження, будь-який підвантажений у нього скрипт дістає доступ до всіх його ресурсів — а застосунок, який необережно домішує недовірений вміст, зливає йому ці повноваження. Практичний наслідок: переїзд стенда з http на https — не косметика, а зміна межі безпеки. Саму й її послаблення розбирає глава «CORS і політика одного походження».
CSP: хто вирішує, що сторінці можна виконувати
CSP (Content Security Policy) — механізм, яким розробник керує тим, які ресурси конкретна сторінка може завантажувати й виконувати. Призначення — зменшити вразливостей через вмісту, насамперед XSS. При цьому специфікація застерігає: CSP не задумана як перша лінія захисту — це механізм , який зменшує шкоду від успішної інʼєкції, але не замінює й .
Каналів доставки два, і це головна практична деталь. Основний — заголовок відповіді. Але документ може доставити політику й розміткою: «A Document may deliver a policy via one or more HTML meta elements whose http-equiv attributes are an ASCII case-insensitive match for the string "Content-Security-Policy"». Канали не рівносильні: у meta частина можливостей не працює, а сама політика не діє назад — «policies in meta elements are not applied to content which precedes them», тож скрипт вище за неї вона не зупинить.
Для автотестів це має цілком приземлений бік: сувора політика вміє блокувати те, що робить сам тест. Звична інʼєкція допоміжного скрипта чи вставка inline-обробника в DOM під політикою без 'unsafe-inline' і 'unsafe-eval' не спрацює, а в консолі зʼявиться повідомлення про порушення; для таких випадків у Playwright є опція bypassCSP. Склад директив і — предмет розділу про безпеку; де саме шукати слід порушення, розбирає глава «DevTools: вкладка Network і дебаг»: у мережевій панелі буває зелено, а повідомлення про порушення лежить у консолі.
Наша практика (не канон). Порада шукати політику в обох місцях — наша: джерело описує канали, а не діагностику. Наші й два висновки поруч: page.evaluate під суворою політикою здебільшого проходить, бо код їде через протокол налагодження, а page.waitForFunction без 'unsafe-eval' може падати; і корисно мати зворотну перевірку — що заголовок узагалі присутній, а список джерел не «поплив» після релізу.
XSS — рівно стільки, щоб зрозуміти CSP
XSS (Cross-Site Scripting) — різновид інʼєкційних атак, коли шкідливий скрипт потрапляє на загалом безпечний і довірений сайт, а застосунок доставляє його іншому користувачеві. Корінь один: дані з недовіреного джерела потрапляють у згенерований вивід без валідації чи екранування, і браузер жертви виконує їх як код — відрізнити внесений інʼєкцією скрипт від легітимного він не може.
Оскільки скрипт вважається «своїм», він отримує доступ до кукі, сесійних токенів та іншої чутливої інформації, збереженої браузером для цього сайту, і може переписати вміст сторінки. Найтяжчий наслідок — розкриття сесійної кукі, а отже, та облікового запису жертви. Захист — кодування виводу, санітизація вводу й фреймворки, які екранують вставки за замовчуванням; CSP додається другим рубежем. Типи, пейлоади й сінки — предмет розділу про .
Кукі під кутом транспорту
Без TLS вміст заголовків Cookie і Set-Cookie передається у відкритому вигляді — звідси й вимога атрибута Secure разом із HTTPS: із ним кукі йде лише захищеним каналом, по відкритому HTTP не піде (виняток — localhost). HttpOnly обмежує кукі лише HTTP-запитами: скриптові API браузера її не бачать, і це базовий захист сесійного токена від крадіжки через XSS.
Прямий наслідок для тестів: кукі з HttpOnly не прочитати ні через document.cookie, ні через page.evaluate — це не баг тесту, а задум. Читати й підставляти таку кукі треба на рівні :
const session = (await context.cookies()).find((c) => c.name === 'session');
Те саме стосується ізоляції: очищення document.cookie не прибере HttpOnly-кукі. Решта атрибутів (зокрема SameSite) і сховища браузера — глава «Кукі, сесії та сховище браузера»; CSRF — глава «Автентифікація та авторизація».
Перехоплення трафіку в тестах — легальний MITM
Посередник бачить увесь трафік, що крізь нього йде, тож може не лише передавати його, а й інспектувати та змінювати. Але звичайний проксі не бачить і не змінює TLS-потік: запит CONNECT лише просить відкрити трубу між клієнтом і сервером. Щоб зазирнути всередину, інструмент прикидається сервером для клієнта й клієнтом для сервера — саме тому перехоплення HTTPS вимагає власного сертифіката, а браузер приймає його лише тоді, коли корінь цього сертифіката лежить у сховищі довіри машини. Прийом той самий, що й внутрішній CA на агенті CI, тільки мета інша.
Дзеркальний бік корисно тримати в голові при діагностиці: вузол, якого клієнт не обирав, — корпоративний фаєрвол чи публічний Wi-Fi — протокольно «indistinguishable (at a protocol level) from an on-path attacker», і поведінка запиту може змінитися без жодної зміни в застосунку. Той самий принцип вбудований у фреймворки автотестів, тільки перехоплення живе всередині браузера; механіку розбирає глава «Перехоплення й мокання мережі».
Типові помилки
- Виглядає як «TLS ховає все», а насправді посередник бачить IP-адресу сервера і доменне імʼя через SNI; закриті лише шлях, параметри, кукі й тіло.
- Виглядає як «TLS 1.2 актуальний», а насправді RFC 8446 його обсолетнув, а практична межа «1.2 і вище» стоїть на відсутності заборони.
- Виглядає як «тест перевіряє редирект
http→https», а насправді на HSTS-хості браузер переписує схему ще до мережевого запиту:http-запит на сервер не піде, тож і редиректу у відповіді не буде. - Виглядає як «картинки завжди підвищуються до HTTPS», а насправді підвищується
<img>ізsrc, а той самий<img>зіsrcsetабо в<picture>блокується; запит до хоста-IP не підвищується взагалі — його блокують. - Виглядає як «CSP немає — у заголовках порожньо», а насправді політику могли доставити елементом
metaв розмітці. - Виглядає як баг тесту («не читається кукі сесії»), а насправді це
HttpOnlyпрацює як задумано: така кукі читається лише на рівні контексту браузера.
Підсумок
- HTTPS не змінює HTTP — він кладе його всередину TLS, а TLS вимагає від транспорту лише надійного впорядкованого потоку.
- Асиметрія працює лише на старті, щоб узгодити симетричний ключ сесії; ефемерний обмін дає пряму секретність, сервер автентифікується завжди, клієнт — опційно.
- Заборони на версії адресні: TLS 1.0/1.1, SSL 3.0 і SSL 2.0 заборонені поіменними документами IETF, а TLS 1.2 обсолетнутий, але не заборонений.
- Схема — безпекова межа: вона входить у походження, тож
httpіhttpsдля браузера різні світи; звідси ростуть змішаний контент, HSTS і поведінка кукі. - Більшість «падінь без причини» на цьому шарі має слід у консолі або в заголовках: заблокований ресурс, порушення політики, переписана схема, прострочений сертифікат.
Можливі питання
- «Чим HTTPS відрізняється від HTTP?» Перевіряють, чи ви бачите шар, а не лише замочок: це той самий HTTP усередині TLS, і TLS дає три гарантії — автентифікацію сервера, конфіденційність, цілісність.
- «Що з HTTPS-трафіку все одно бачить посередник?» Питання на точність. Очікують IP і доменне імʼя через SNI — і те, що шлях, параметри, кукі й тіло закриті; бонус — чому секрет у query-рядку небезпечний навіть по HTTPS.
- «Навіщо асиметрія, якщо трафік шифрується симетрично?» Дивляться на роль рукостискання: асиметрія узгоджує ключ сесії й автентифікує сервера, далі працює швидкий симетричний алгоритм.
- «Тест не бачить елемент, у консолі — попередження про змішаний контент. Що сталося?» Міні-кейс на порядок дій: спершу причина в консолі, потім різниця «оновлюваний проти блокованого», і лише тоді код чи таймаути.
- «Що таке CSP і як сувора політика впливає на автотести?» Очікують механізм і наслідок: політика керує тим, що сторінці можна вантажити й виконувати, доставляється заголовком або елементом
meta— і вміє заблокувати вставку допоміжного скрипта самим тестом.
Джерела
- RFC 6797 — HTTP Strict Transport Security (HSTS) — HTTPS як HTTP, загорнутий у криптографічний шар TLS.
- RFC 8446 — TLS 1.3 — мета TLS, вимога надійного впорядкованого потоку від транспорту, поділ на рукостискання й record-протокол.
Три гарантії й асиметрія лише на старті
- RFC 8446 — TLS 1.3 — три гарантії каналу, фази рукостискання,
Certificate/CertificateVerify/Finished, шифрування всього післяServerHello, роль асиметрії на старті й пряма секретність. - OWASP Cheat Sheet — Transport Layer Security — взаємний TLS як те, що закриває невизначеність з особою клієнта.
Версії: «заборонено» і «застаріло» — різні слова
- RFC 8446 — TLS 1.3 — обсолетність попередніх версій, включно з TLS 1.2.
- RFC 8996 — Deprecating TLS 1.0 and TLS 1.1 — пряма заборона TLS 1.0 і TLS 1.1.
- RFC 7568 — Deprecating Secure Sockets Layer Version 3.0 — заборона SSL 3.0 і його узгодження з будь-якої версії TLS.
- RFC 6176 — Prohibiting Secure Sockets Layer (SSL) Version 2.0 — заборона SSL 2.0 і межа між «узгоджувати» та «розпізнавати формат».
- RFC 8446 — TLS 1.3 — що саме захищає канал після встановлення.
- RFC 6066 — TLS Extensions: Extension Definitions — SNI як розширення, що несе доменне імʼя в рукостисканні.
- RFC 6750 — The OAuth 2.0 Authorization Framework: Bearer Token Usage — Bearer-токен, вимога захищеного транспорту й місце секрету поза URL.
Сертифікат стенда — і чому прогін падає вранці
- RFC 5280 — Internet X.509 PKI Certificate and CRL Profile — сертифікат X.509 і ланцюг підписів до довіреного кореня.
- RFC 9525 — Service Identity in TLS — звірка домену з ідентифікатором у сертифікаті.
- Playwright — Test use options —
ignoreHTTPSErrorsяк опція контексту. - W3C — WebDriver Level 2 — можливість
acceptInsecureCerts. - curl — manual page — прапорець
-kдля запитів зі скриптів і CI.
HSTS: схема переписується ще до мережі
- RFC 6797 — HTTP Strict Transport Security (HSTS) — заборона віддавати заголовок по відкритому транспорту, нормативна заміна схеми й порту, час життя політики, обрив зʼєднання при помилці транспорту.
- MDN — Strict-Transport-Security — браузер ігнорує заголовок з HTTP-відповіді й не пропонує продовжити повз помилку сертифіката.
- OWASP — HTTP Strict Transport Security Cheat Sheet — незворотність
preload. - MDN — Redirections in HTTP — постійні редиректи
301/308і перевірка самого факту перенаправлення з вимкненим автопрямуванням.
Змішаний контент: «елемент не зʼявився без причини»
- MDN — Mixed content — поділ на оновлюваний і блокований вміст, правила для
<img>і хоста-IP, попередження в консолі, локальні ресурси як захищені походження, межа з навігацією,upgrade-insecure-requests. - Playwright — class Page — подія
consoleяк спосіб побачити ці попередження з тесту. - RFC 6455 — The WebSocket Protocol — схеми
wsіwss, друга з яких іде поверх TLS.
Походження: схема — це безпекова межа
- MDN — Same-origin policy — походження як трійка «схема / хост / порт» і умова збігу всіх трьох.
- RFC 6454 — The Web Origin Concept — походження як домен захисту й означення XSS через повноваження походження.
- WHATWG URL Standard — типові порти «особливих» схем, які в серіалізації опускають.
CSP: хто вирішує, що сторінці можна виконувати
- W3C — Content Security Policy Level 3 — призначення CSP, роль шару в глибині захисту, два канали доставки, нерівносильність
metaй правило про вміст перед ним. - MDN — Content Security Policy (CSP) — блокування вбудованого коду суворою політикою й повідомлення про порушення в консолі.
- Playwright — Test use options — опція
bypassCSP.
XSS — рівно стільки, щоб зрозуміти CSP
- OWASP — Cross Site Scripting (XSS) — означення, корінь вразливості, доступ внесеного інʼєкцією скрипта до кукі й токенів, розкриття сесійної кукі як найтяжчий наслідок.
- MDN — Cross-site scripting (XSS) — кодування виводу, санітизація й фреймворки як основний захист.
- W3C — Content Security Policy Level 3 — CSP як другий рубіж саме проти інʼєкції вмісту.
- RFC 6265 — HTTP State Management Mechanism — передавання кукі у відкритому вигляді без TLS, семантика
SecureіHttpOnly. - MDN — Using HTTP cookies — виняток
localhostдляSecureі читанняHttpOnly-кукі на рівні контексту браузера.
Перехоплення трафіку в тестах — легальний MITM
- mitmproxy — How mitmproxy works — межа звичайного проксі на TLS-потоці, підміна ролей обох сторін і потреба у власному сертифікаті.
- RFC 9110 — HTTP Semantics — перехоплювальний вузол, якого клієнт не обирає, і його нерозрізнюваність з на шляху.
- Playwright — Network — той самий принцип перехоплення всередині браузера.
Чим HTTPS відрізняється від HTTP?
Це той самий HTTP, покладений усередину криптографічного шару TLS: спершу дві сторони піднімають захищений канал, і вже по ньому їздять звичні методи, заголовки й коди статусів. Семантика протоколу від цього не змінюється — GET, 404 і Content-Type означають рівно те саме, що й без шифрування. Сам TLS складається з двох частин: , яке автентифікує сервера й узгоджує ключі, і record-протоколу, який цими ключами захищає далі весь трафік. Від транспорту TLS вимагає небагато — надійного потоку зі збереженням порядку, і на практиці це TCP. Для тестувальника головний висновок практичний: коли «запит не пішов», спочатку треба зрозуміти, чи канал узагалі встановився. Якщо ні — шукати треба в сертифікаті чи версії протоколу, а не в коді застосунку, який про цей запит навіть не дізнався.
Які гарантії дає TLS і чого він не гарантує?
Гарантій рівно три, і корисно називати їх окремо, бо закривають вони різні . Автентифікація — клієнт переконується, що говорить із власником домену, а не з кимось на шляху. Конфіденційність — після встановлення каналу зміст даних доступний лише двом кінцевим точкам. Цілісність — підміну байтів у дорозі буде виявлено. А от чого TLS не приховує, так це самого факту зʼєднання: адреса сервера й доменне імʼя лишаються видимими. Ще одна асиметрія, яку варто памʼятати: сервер доводить свою особу завжди, а клієнт — лише якщо це окремо налаштували. Тому без окремого налаштування особа клієнта серверу невідома аж до логіна, який відбувається вже всередині піднятого каналу.
Навіщо в рукостисканні асиметрична криптографія, якщо далі трафік шифрується симетрично?
Асиметрія працює рівно на старті й вирішує дві задачі, які симетричний ключ вирішити не може: дає двом сторонам, що ніколи не бачилися, спільний секрет і дозволяє клієнту переконатися в особі сервера. Далі вона стає зайвою — узгоджений симетричний ключ сесії шифрує весь корисний трафік, бо для потокових обсягів асиметричні операції надто дорогі. Свою особу сервер підтверджує трійкою повідомлень: віддає сертифікат (Certificate), підписує ним усе рукостискання (CertificateVerify) і фіксує підсумок (Finished). Якщо матеріал для обміну ключами одноразовий (ефемерний), канал додатково отримує (perfect forward secrecy). Деталь для глибшої відповіді: у TLS 1.3 усе, що йде після ServerHello, уже зашифроване — і сам сертифікат теж, — тож у перехопленому дампі не видно навіть, на чиє імʼя його виписано.
Що з HTTPS-трафіку все одно бачить посередник?
Видно, куди ви йдете, але не що ви там робите. читає IP-адресу сервера і доменне імʼя — воно їде в розширенні SNI (Server Name Indication) під час рукостискання. Закритими лишаються шлях, параметри запиту, заголовки (зокрема кукі) і тіло. Тобто «зайшов на example.com» — публічна інформація, а «відкрив там сторінку конкретного замовлення» — ні. Це питання люблять саме тому, що воно розводить два поширені перекоси: «TLS ховає геть усе» і «HTTPS нічого не дає, бо домен видно». Правильна відповідь — посередині, і саме з неї випливає наступна класична пастка про секрети в URL.
Чому токен у query-рядку небезпечний навіть по HTTPS?
Бо канал тут ні до чого — повний URL осідає в місцях, до яких шифрування не має стосунку. Він потрапляє в логи серверів і , в історію браузера, у заголовок Referer при переході на зовнішній ресурс і в системи аналітики. Тобто секрет захищений у дорозі й розкритий на обох кінцях та в усьому, що по дорозі веде записи. Носити токен треба там, куди журнали не зазирають: у заголовку Authorization зі схемою Bearer або в тілі POST-запиту. Практичний наслідок для QA: посилання з токеном у параметрах, надіслане в баг-репорт чи в тікет, — це вже потенційний інцидент, а не просто незручність. І окремо варто заводити знахідку, якщо продукт сам генерує такі URL, наприклад у листах «підтвердити пошту».
Яка версія TLS чинна за специфікацією і чи коректно називати TLS 1.2 актуальним?
Чинна версія одна — TLS 1.3: RFC 8446 прямо оголошує попередні версії обсолетними, і TLS 1.2 у цей перелік входить. Тож формулювання «1.2 — актуальна версія» з документів не випливає. Але обсолетність і заборона — різні речі: 1.2 ніхто не забороняв, а от TLS 1.1 і TLS 1.0 заборонені окремим документом (RFC 8996), SSL 3.0 — своїм (RFC 7568), SSL 2.0 — своїм (RFC 6176). Звідси й коректне обґрунтування звичної вимоги «TLS 1.2 і вище»: підстава — не сучасність версії, а відсутність заборони на неї. Тонкість, за яку зазвичай дають бали: заборона стосується узгодження старого протоколу, а не вміння сервера розпізнати повідомлення у старому форматі — приймати байти формату SSL 2.0 йому не заборонено, доки він на цій версії не працює.
Що саме браузер перевіряє в сертифікаті сервера?
Сертифікат — це файл формату X.509, який звʼязує доменне імʼя з відкритим ключем сервера, і перевірок над ним кілька. Браузер будує ланцюг підписів до кореня, якому він довіряє; звіряє домен зі списком імен у полі SAN (Subject Alternative Name); дивиться строк дії; перевіряє, чи сертифікат не відкликано. Провал будь-якої з цих перевірок зупиняє встановлення зʼєднання — жодного HTTP-запиту не буде взагалі. Для тестів це дає впізнаваний симптом: падає не один сценарій, а всі, що ходять на цей хост, і падають вони до першої взаємодії зі сторінкою. Масовість і однаковість помилки самі по собі є діагностичною ознакою й майже завжди виводять на інфраструктуру, а не на код.
Зранку впали всі тести на стенді з помилкою сертифіката. Ваш порядок дій?
Перший крок — не код, а сам стенд: відкрити його в браузері й подивитися на значок біля адреси, там одразу видно строк дії й ким виданий сертифікат. Типовий перший кандидат — сертифікат стенда з коротким строком, який ніхто не продовжив, і він протух посеред ночі. Другий кандидат — сертифікат живий, але виданий внутрішнім центром сертифікації, кореня якого немає у сховищі довіри агента CI; діагностична ознака тут — локально все зелено, а в червоно. Третій — стенд переїхав на інше імʼя, і домен більше не збігається з тим, що записано в сертифікаті. І тільки коли всі три відкинуто, є сенс дивитися в конфіг тестів. Лікування теж різне: перший і третій випадки — це тікет на інфраструктуру, а другий закривається на боці агента, куди треба покласти корінь внутрішнього CA.
Коли доречно вмикати ignoreHTTPSErrors і чим за це платять?
доречний там, де самопідписаний сертифікат — свідома й очікувана властивість середовища, тобто на внутрішньому dev- чи staging-стенді. Свій важіль має кожен інструмент: у WebDriver це можливість acceptInsecureCerts, у curl — прапорець -k. Ціна очевидна, але про неї часто мовчать: із вимкненою перевіркою тест перестає бачити реальні проблеми конфігурації — протухлий сертифікат, невірний домен, зламаний ланцюг. Тобто ви навмисно робите себе сліпим до цілого класу продакшн-багів. Тому вмикають його адресно — в одному проєкті конфіга, під конкретне середовище, — а не одним рядком на всю . Де це можливо, кращий шлях інший: занести корінь внутрішнього CA у сховище довіри агента, щоб ланцюг сходився чесно, а перевірка лишалася живою.
Що робить HSTS і чому цей заголовок у HTTP-відповіді нічого не змінює?
Strict-Transport-Security — це вказівка браузеру ходити на цей домен виключно захищено протягом заданого часу. Віддавати його по відкритому HTTP специфікація забороняє, а браузер такий заголовок просто ігнорує, і логіка тут пряма: заголовок, отриманий незахищеним каналом, міг бути підкинутий будь-ким на шляху. Практичний висновок для перевірки: шукати Strict-Transport-Security треба у відповіді по HTTPS, а його наявність у відкритій відповіді — це не «зайва обережність», а порушення, яке варто завести. Друга властивість, що економить час: політика переживає зникнення заголовка — хост лишається під нею до кінця max-age. Тому «заголовок прибрали з релізу» видно тільки в заголовках; поведінка браузера ще довго виглядатиме нормальною.
Тест перевіряє редирект http → https, а редиректу в записі немає. Що сталося?
Найімовірніше, домен уже відомий браузеру як -хост, і той переписав схему сам. Заміна http на https (а явного порту 80 на 443) відбувається до того, як запит піде в мережу, тому жодного відкритого запиту, а отже, й відповіді з редиректом, у трафіку не зʼявиться. Звідси й сусідній сюрприз: якщо базова адреса прибита в конфізі як http://, запит однаково піде захищено, і тест, який нібито працює з відкритою схемою, працює насправді із захищеною. Правильний спосіб перевірити сам редирект — інструмент, що не тримає HSTS-політики (наприклад, curl без відповідного налаштування), з вимкненим автопрямуванням: тоді видно проміжний код і заголовок Location. Постійне перенаправлення при цьому виражають коди 301 і 308. І в на схему покладатися варто на фактичну адресу у відповіді, а не на ту, що ви набрали у конфізі.
Що таке змішаний контент і чим оновлюваний вміст відрізняється від блокованого?
Про (mixed content) говорять тоді, коли документ прийшов захищеним каналом, а окремі його ресурси підтягуються відкритим: значок в адресному рядку обіцяє захист, хоча частину трафіку можна прочитати чи підмінити. Категорій дві — оновлюваний вміст (upgradable) і блокований (blockable). Перший браузер переписує на захищену схему самотужки, і якщо за новою адресою нічого не лежить, запит завершується невдачею: назад на відкриту схему ніхто не відкотиться. До другої категорії належить усе інше — fetch() і XMLHttpRequest, вбудовані документи в <iframe src>, стилі з <link href> і, звісно, скрипти з <script src>. Тонка межа, на якій ловлять: картинка з атрибутом src підвищиться, а варіант зі srcset чи всередині <picture> потрапляє до блокованих; а запит, де хостом стоїть IP-адреса, не підвищується взагалі — його блокують. Пара «активний» і «пасивний» — спадок ранішої редакції специфікації, тож у баг-репорті точніше вживати сучасні назви.
Чому змішаний контент не відтворюється, коли розробник перевіряє його локально?
Тому що локальні адреси браузер вважає захищеними . file:-URL і loopback — http://localhost/, http://127.0.0.1/ — не вважаються небезпечним джерелом, тож блокування там просто не вмикається. Звідси й класичний діалог «у мене все працює»: у розробника фронт крутиться на localhost, а на стенді з нормальним доменом той самий ресурс блокується. Практичне правило — відтворювати такі дефекти на адресі з доменним імʼям і по HTTPS, інакше перевірка не має сенсу. І друга половина того ж непорозуміння: клік по посиланню, що веде з захищеної сторінки на незахищену, до змішаного контенту не належить — це нова навігація й новий контекст, тож там мовчить законно.
Що таке походження і чому перевести стенд на HTTPS — більше, ніж змінити адресу?
Походження (origin) — це трійка «схема, хост, порт», і одним походженням дві адреси стають лише за збігу всіх трьох складових. Типовий порт схеми в адресі зазвичай не пишуть, тому запис https://app.example.com рівносильний варіанту з явним :443. Ключове для питання: схема входить у трійку, тобто http://app.example.com і https://app.example.com — це для браузера два різні світи. А походження браузер використовує як домен захисту: доступ до обʼєктів дає лише в межах одного походження. Тому зміна схеми на стенді переносить межу безпеки — і разом із нею їдуть кукі з Secure, поведінка змішаного контенту й усе решта, що прибито до конкретного походження. Тести, які «раптом» посипалися після такого переїзду, зазвичай не зламані, а просто опинилися по інший бік межі.
Що таке CSP і чому специфікація застерігає не робити з неї першу лінію захисту?
CSP (Content Security Policy) — це набір обмежень, які автор сторінки задає браузеру: що їй дозволено підтягувати й запускати. Мішень — чужого вмісту, передусім XSS. Застереження в специфікації прямолінійне: це механізм , тобто він зменшує шкоду від уже успішної інʼєкції, а не запобігає їй. Причина в тому, що корінь XSS лежить у застосунку — недовірені дані потрапили у вивід без кодування, — і політика браузера цього кореня не прибирає. Тому на першому місці лишаються обробка вводу й , разом із фреймворками, де воно ввімкнене з коробки; політика працює рівнем нижче. Для QA звідси випливає конкретне: «у нас є CSP» не закриває тест на XSS, і навпаки — знайдений XSS не перестає бути дефектом від того, що політика його частково глушить.
У заголовках відповіді CSP немає, а браузер усе одно блокує скрипт. Де шукати політику?
У розмітці. Каналів доставки два: заголовок відповіді й один або кілька елементів meta з атрибутом http-equiv, який відповідає рядку Content-Security-Policy. Тому висновок «CSP немає, бо в заголовках порожньо» передчасний — треба глянути в сам HTML. Канали при цьому не рівносильні: у варіанті з meta частина можливостей недоступна, і головне — політика не діє назад, тобто на вміст, що стоїть у документі вище за неї, вона не поширюється. Ще одна деталь для діагностики: у мережевій панелі така історія може виглядати цілком зелено, а повідомлення про порушення лежатиме в консолі — саме тому розбір «елемент не зʼявився» починають із консолі.
Як сувора CSP ламає автотести і що з цим робити?
Ламає рівно те, що тест робить сам: інʼєкцію допоміжного скрипта чи вставку inline-обробника в DOM. Якщо політика не містить 'unsafe-eval' і 'unsafe-inline', обидві операції не пройдуть, а в консолі осяде запис про порушення — сам же тест виглядатиме як «локатор не знайшовся». Симптоми бувають вибірковими й через це особливо заплутаними: page.evaluate зазвичай працює, бо його код доставляється протоколом налагодження, а от page.waitForFunction під політикою без дозволу на eval цілком здатен упасти. Швидке лікування — опція bypassCSP у Playwright, але це саме анестезія: під нею ви більше не перевіряєте реальну політику продукту. Тому нормальний підхід — вимикати політику точково, для тих сценаріїв, де вона не є предметом перевірки, і паралельно мати окремий тест на те, що заголовок узагалі присутній і список джерел не поплив після релізу.
Що таке XSS і чому найтяжчим наслідком називають саме крадіжку сесійної кукі?
XSS (Cross-Site Scripting) — інʼєкційна атака, коли чужий скрипт потрапляє на нормальний, довірений користувачем сайт, а застосунок доставляє його іншим відвідувачам. Корінь завжди той самий: у згенеровану сторінку потрапили неперевірені й неекрановані дані, а браузер жертви прочитав їх як код — законний скрипт від підкинутого він розрізнити не вміє. А оскільки скрипт вважається своїм, він працює з повноваженнями походження: читає кукі, сесійні токени й решту того, що браузер тримає під цим сайтом, а заразом вільно перемальовує сторінку. Звідси й найтяжчий сценарій — витік сесійної кукі, тобто та облікового запису жертви без жодного пароля. Саме тому атрибут HttpOnly на сесійній кукі вважають базовим помʼякшенням: він прибирає її з поля зору скриптових API. Типи, сінки й пейлоади — окрема велика тема, але цього рівня вистачає, щоб пояснити, навіщо поруч існує CSP.
Тест не може прочитати кукі сесії через document.cookie. Це баг тесту?
Ні, це найімовірніше атрибут HttpOnly, який працює точно так, як задумано: кукі з ним доступна лише в HTTP-запитах і невидима для скриптових API браузера. Тому ні document.cookie, ні page.evaluate її не покажуть, і скільки не переписуй селектор чи очікування — не зʼявиться. Правильний рівень доступу — : у Playwright це context.cookies(), звідки видно і значення, і атрибути. Той самий механізм дає другу пастку, вже в ізоляції тестів: очищення document.cookie не прибирає HttpOnly-кукі, тож «розлогінення» через JavaScript тихо не спрацює, а наступний тест стартує з живою сесією. Поруч варто памʼятати про Secure: із ним кукі не піде по відкритому HTTP взагалі, з винятком для localhost, — і це ще одна причина, чому сценарії на HTTP-стенді поводяться інакше.
Як інструменти на кшталт mitmproxy читають HTTPS, якщо TLS усе шифрує?
Ніяк — доки лишаються звичайним проксі. Через CONNECT такий вузол лише просить прокласти трубу до сервера, а TLS-потік усередині неї лишається для нього непрозорим. Щоб зазирнути в канал, інструмент має стати посередником по-справжньому: для клієнта видати себе за сервер, а для сервера — за клієнта, тобто підняти окремий TLS на кожному боці. Звідси й вимога власного сертифіката: браузер погодиться на нього тільки тоді, коли машина довіряє його кореню, — механіка та сама, що з внутрішнім CA на агенті CI, хоч мета й протилежна. Дзеркальне спостереження стане в пригоді при діагностиці: якщо посередника обрав не клієнт, а корпоративний фаєрвол чи точка в кафе, протокол не відрізнить його від зловмисника на шляху — і трафік поводиться інакше, хоча в продукті не змінилося нічого. Саме тому «у мене з дому працює, а з офісу ні» — це гіпотеза про мережу, а не про продукт.
Три кейси про одну навичку: за хвилину сказати, який шар зупинив запит. Спершу — розбір масового ранкового падіння, далі — як перевести транспортні домовленості з «сподіваємось» у , і наостанок — діагностика «елемент не зʼявився», де відповідь лежить у , а не в .
Кейс 1. «Зранку червоне все»: який шар зупинив запит
Червоний прогін цілком — це майже завжди не про . Питання одне: запит узагалі дійшов до застосунку? Шарів між тестом і кодом три — TLS, політика браузера, застосунок, — і кожен має власний слід.
| Що видно у звіті чи логах | Шар-підозрюваний | Дешева перевірка |
|---|---|---|
Жоден тест не відкрив сторінку, у помилці — ERR_CERT_DATE_INVALID | TLS: сертифікат стенда протух | відкрити стенд руками й глянути строк дії в замочку |
Локально зелено, у CI — ERR_CERT_AUTHORITY_INVALID | TLS: кореня внутрішнього CA немає у сховищі довіри агента | той самий URL з машини розробника проти агента |
| Зʼєднання обривається, сторінки помилки з «продовжити» немає | HSTS-хост плюс будь-яка помилка транспорту | перевірити Strict-Transport-Security на HTTPS-відповіді |
Базовий URL записаний як http://, а у відповіді схема https | HSTS: браузер переписав схему до виходу в мережу | глянути, чи є в трафіку сам http-запит: немає — схему переписав браузер, є — спрацював звичайний редирект |
Сторінка відкрилась, частини елементів немає, у консолі — Mixed Content | політика браузера: підресурс заблоковано | знайти в консолі URL заблокованого ресурсу |
Сторінка ціла, у консолі — Refused to execute inline script | політика браузера: CSP | шукати політику в заголовку і в розмітці |
Тест дійшов до застосунку й отримав 401 або 500 | застосунок | звичайний розбір за кодом відповіді й логами бекенду |
Три висновки, які економлять ранок.
- Масовість — це вже діагноз. Помилка сертифіката валить саме зʼєднання, тож падає все, що ходить на цей хост, і падає до першої взаємодії зі сторінкою. Один червоний сценарій серед зелених так виглядати не може — там шукайте в іншому місці.
- «Локально працює» тут не , а вказівник. Різниця між машиною розробника й агентом CI найчастіше зводиться до сховища довіри: сертифікат живий, просто його корінь агенту невідомий. Лікується це не прапорцем у конфізі тестів, а додаванням кореня внутрішнього CA на агента.
- Помилку сертифіката на -хості не «проклікати». Браузер не запропонує продовжити, а обірве зʼєднання, тому звична порада «натисни Advanced → Proceed» тут не працює навіть руками. Це не поломка стенда, а закладена поведінка.
Кейс 2. Транспортний контракт як предмет асерту
й атрибути кукі — така сама домовленість, як формат тіла, і так само тихо ламаються після релізу. Перевірка коштує кілька рядків, а ловить , яких не видно в поведінці ще тижнями.
import { test, expect } from '@playwright/test';
test('HTTPS-відповідь несе політику HSTS', async ({ page }) => {
const res = await page.goto('/');
const hsts = res!.headers()['strict-transport-security'];
expect(hsts, 'заголовок зник — політика доживає max-age і мовчки протухне').toBeTruthy();
expect(hsts).toMatch(/max-age=\d+/);
});
test('сесійна кукі закрита від відкритого каналу й від скриптів', async ({ page, context }) => {
await page.goto('/login');
// ... вхід ...
const session = (await context.cookies()).find((c) => c.name === 'session');
expect(session, 'кукі з HttpOnly видно лише на рівні контексту').toBeDefined();
expect(session!.secure).toBe(true);
expect(session!.httpOnly).toBe(true);
});
test('CSP присутня, а список джерел не поплив', async ({ page }) => {
const res = await page.goto('/');
const csp = res!.headers()['content-security-policy'];
expect(csp, 'політику могли доставити через meta — тоді дивіться в HTML').toBeTruthy();
expect(csp).toContain("default-src 'self'");
});
Сам редирект http → https у браузері перевірити не вийде: на відомому HSTS-хості відкритий запит просто не піде в мережу. Тому беруть інструмент без HSTS-сховища й вимикають автопрямування — тоді видно проміжний код і Location:
# без -L curl за редиректом не йде: у виводі буде сам 301/308 і заголовок Location
curl -sS -D - -o /dev/null http://app.example.com/
Що дивитися і чому:
- Асерт на
SecureіHttpOnly— це тест безпеки, а не педантизм. ЗникненняHttpOnlyне змінює жодного продуктового сценарію: усе працює, просто сесійна кукі стала доступною будь-якому скрипту на сторінці. Побачити таку регресію можна лише в атрибутах. - Наявність заголовка перевіряють окремо від його вмісту. Політика HSTS переживає зникнення заголовка до кінця
max-age, тож у поведінці регресії не буде — і тест на поведінку її не спіймає. - Порожній заголовок CSP ще не означає, що політики немає. Її могли доставити елементом
metaв розмітці, тому падіння цього асерту читають як «перевір обидва канали», а не як «CSP прибрали». - Перевірку редиректу не змішують із перевіркою HSTS. Це різні механізми: перший живе у відповіді сервера, другий — у сховищі браузера, і другий уміє повністю приховати перший.
Кейс 3. «Елемент не зʼявився»: консоль замість таймаутів
Симптом виглядає як : локатор не дочекався, іноді рятує, у мережевій панелі нічого підозрілого. Найдешевший перший крок — вивести в лог те, що браузер уже сказав. Обидві історії цієї глави — і , і CSP — лишають слід саме там.
test.beforeEach(async ({ page }) => {
page.on('console', (msg) => {
if (msg.type() === 'error' || msg.type() === 'warning') {
console.log(`[${msg.type()}]`, msg.text());
}
});
page.on('requestfailed', (req) => {
console.log('FAILED', req.url(), req.failure()?.errorText);
});
});
Далі повідомлення читається однозначно.
| Що в консолі | Що сталося | Куди йти |
|---|---|---|
Mixed Content: ... This request has been blocked | блокований підресурс — скрипт, стиль, iframe або fetch | прибрати зашитий http:// з конфігу чи розмітки |
Mixed Content: ... was automatically upgraded to HTTPS, а запит червоний | запит підвищили, але по HTTPS сервер ресурсу не віддає | відкоту на HTTP не буде — це проблема самого ресурсу |
Refused to execute inline script | сувора CSP | знайти політику в заголовку або в meta |
Refused to connect to ... | CSP ріже саме мережевий запит | звірити хост із дозволеними джерелами політики |
| у консолі порожньо, у мережі — жодного запиту до ресурсу | запит не робився взагалі | перевірити код сторінки, а не транспорт |
Що дивитися і чому:
- Порожньо в мережевій панелі — ще не діагноз. Слід блокування лежить у консолі, і саме з неї починається розбір; у панелі Network заблокований підресурс доводиться шукати цілеспрямовано — наприклад, фільтром
mixed-content:all. - Локально це не відтворюється.
file:-адреси й loopback браузер вважає захищеними , тому наhttp://localhostблокувань не буде. Перевіряти треба на доменному імені, інакше перевірка не має сенсу. - «Картинка не завантажилась» — не єдиний вигляд симптому. Заблокованим буває
fetch, і тоді сторінка малюється цілою, але порожньою; шукати доводиться не відсутню графіку, а відсутні дані. bypassCSP— анестезія, а не лікування. Він доречний там, де політика не є предметом перевірки й заважає технічній обвʼязці тесту. Ставити його на всю означає більше ніколи не перевіряти реальну політику продукту.ws://зі сторінки наhttpsне відкриється. Це той самий механізм, а не баг реалтайму: поверх TLS працює схемаwss, і в баг-репорті це варто називати саме так.
Механіка захищеного каналу
- Можу пояснити, що HTTPS не змінює HTTP, а кладе його всередину TLS, і назвати дві частини протоколу: автентифікує сервера й узгоджує ключі, record-протокол ними захищає весь подальший трафік.
- Називаю три гарантії TLS окремо — автентифікація, конфіденційність, цілісність — і додаю, що сервер доводить особу завжди, а клієнт лише за окремим налаштуванням (mutual TLS).
- Можу відповісти, навіщо асиметрія, якщо трафік симетричний: вона працює тільки на старті — узгодити ключ сесії й підтвердити особу сервера, — а ефемерний обмін додає .
Версії протоколу
- Знаю різницю «обсолетнуто» vs «заборонено»: TLS 1.3 чинний, TLS 1.2 обсолетнутий RFC 8446, а заборонені поіменно TLS 1.1 і TLS 1.0 (RFC 8996), SSL 3.0 (RFC 7568) і SSL 2.0 (RFC 6176).
- Можу правильно обґрунтувати вимогу «TLS 1.2 і вище»: підстава — відсутність заборони, а не сучасність версії, і не називаю 1.2 «актуальною».
Що видно ззовні
- Розводжу «куди ви пішли» і «що ви там робили»: бачить IP сервера й доменне імʼя через SNI, а шлях, параметри, заголовки з кукі й тіло лишаються закритими.
- Можу пояснити, чому токен у параметрах адреси лишається вразливим навіть при HTTPS (журнали, історія браузера,
Referer, аналітика) і куди його класти замість цього — вAuthorization: Bearerабо в тілоPOST.
Сертифікат і стенд
- Перелічую перевірки сертифіката — збіг домену з іменами в SAN, ланцюг до кореня, якому браузер довіряє, строк дії, відкликання — і впізнаю «впало все й одразу» як ознаку транспортного шару, а не окремого сценарію.
- Знаю різницю між
ignoreHTTPSErrorsі коренем внутрішнього CA у сховищі агента: перше залишає тест без зору на справжні поломки конфігурації, друге лишає перевірку живою.
HSTS
- Можу пояснити, чому
Strict-Transport-Securityперевіряють на HTTPS-відповіді, а поява того самого заголовка у відповіді по HTTP — це дефект, а не запасна перестраховка. - Розумію, чому на -хості тест не побачить редиректу
http→https(схема й порт переписуються до виходу в мережу) і як перевіряти сам факт перенаправлення: вимкнене автопрямування плюс на проміжний код іLocation, де постійні —301і308. - Памʼятаю дві межі: політика живе до кінця
max-ageнавіть після зникнення заголовка, а «продовжити» повз помилку сертифіката на такому хості браузер не запропонує.
Змішаний контент
- Знаю різницю «оновлюваний vs блокований» і те, що підвищений запит при невдачі не відкочується на HTTP, а просто провалюється.
- Памʼятаю межу за способом задання джерела: картинка з атрибутом
srcпідвищується, а варіант зіsrcsetчи в<picture>іде до блокованих; адреси з IP замість імені не підвищуються взагалі. - Розумію, чому локальна перевірка нічого не доводить (
file:і loopback вважаються захищеними ) і що заблокованим буваєfetch, а не картинка — тоді симптом виглядає як порожній екран.
Походження, CSP і XSS
- Можу дати означення походження як трійки «схема, хост, порт» і пояснити, чому переїзд стенда на HTTPS зсуває межу безпеки, а не просто адресу.
- Знаю два канали доставки CSP — заголовок і елемент
meta, який не діє на вміст вище за себе, — і як сувора політика ламає сам тест ( скрипта, inline-обробник), аbypassCSPлікує симптом, а не продукт. - Можу пояснити XSS через повноваження походження (внесений інʼєкцією скрипт вважається своїм і дістає кукі й сесійні токени сайту) і чому CSP при цьому другий рубіж, а не заміна .
Кукі та перехоплення
- Знаю різницю
SecurevsHttpOnly(перший не пускає кукі по відкритому каналу, з виняткомlocalhost; другий ховає її від скриптових API) і не заводжу баг на «тест не читає кукі сесії» — таку кукі беруть на рівні . - Можу пояснити, чому перехоплення HTTPS вимагає власного сертифіката в сховищі довіри машини і чому вузол, якого клієнт не обирав, протокольно не відрізняється від на шляху.
Квіз
Перед стартом
- Питань: 15
- Поріг «зараховано»: ≥70% правильних відповідей.
- Результат впливає на прогрес; завалені питання підуть у чергу повторення.
- Квіз впливає на компліт теми: тема стає «пройдено», лише коли прочитано теорію І квіз складено на ≥70%.
Питання
Де в стеку живе TLS відносно HTTP
