vyvchy
    Теми розділу

    03 · Веб і мережі для AQA

    HTTPS, TLS і безпека

    Зміст

    Кожен клік у браузері — це мережевий запит, який летить через невідому кількість чужих пристроїв: домашній роутер, провайдера, магістральні вузли, балансувальники на боці сервера. Будь-хто на цьому шляху фізично може прочитати або підмінити те, що передається. HTTPS існує саме для того, щоб зробити це нездійсненним на практиці. Для AQA це не абстрактна теорія: сертифікати на staging, mixed content у консолі, HttpOnly-кукі, які не читаються з JavaScript, CSP, що блокує ваш ін’єктований скрипт — усе це щодня впливає на те, працює автотест чи «падає без причини».

    HTTP vs HTTPS

    HTTP (HyperText Transfer Protocol) передає дані у відкритому вигляді. Запит і відповідь — це звичайний текст, який будь-який посередник читає як листівку. HTTPS — це той самий HTTP, але «загорнутий» у криптографічний шар TLS (Transport Layer Security). Літера S означає Secure: спершу встановлюється захищений канал, і вже всередині нього ходить звичний HTTP-трафік.

    ОзнакаHTTPHTTPS
    Порт за замовчуванням80443
    Шифруваннянемаєє (TLS)
    Цілісність данихне гарантуєтьсяконтролюється
    Автентифікація серверанемаєчерез сертифікат
    Позначка в браузері«Not secure»нейтральний значок
    URL-схемаhttp://https://

    Важливий нюанс: TLS шифрує тіло і заголовки HTTP, але не приховує сам факт з’єднання. Посередник усе одно бачить IP-адресу сервера і — через SNI (Server Name Indication) під час рукостискання — доменне ім’я, до якого ви йдете. Він не бачить конкретний шлях (/account/settings), параметри, кукі й тіло. Тобто «що ви відкрили на сайті» приховано, а «на який сайт ви пішли» — здебільшого ні. Розширення ECH (Encrypted Client Hello) шифрує й це доменне ім’я в рукостисканні. Свіжі версії основних браузерів (Chrome, Firefox, Safari) вмикають його за замовчуванням за наявності DNS-over-HTTPS, але працює воно лише там, де ECH підтримує сам сервер чи CDN, — а такого покриття поки що небагато, тож на практиці домен здебільшого все ще видно.

    Нюанс. Наскільки ECH реально працює у твоєму середовищі — залежить від браузера, CDN і DNS-резолвера; підтримка поступово розширюється, тож перевіряй на цільовій конфігурації.

    Сучасні браузери позначають http:// як небезпечний, а багато сайтів автоматично перенаправляють з HTTP на HTTPS редиректом (301/308) та вмикають заголовок Strict-Transport-Security (HSTS). Він змушує браузер надалі ходити на цей домен тільки через HTTPS, навіть якщо користувач набрав http:// вручну.

    # 1) відкритий HTTP-запит → редирект на HTTPS
    GET / HTTP/1.1
    Host: app.example.com
    
    HTTP/1.1 301 Moved Permanently
    Location: https://app.example.com/
    
    # 2) уже по HTTPS сервер віддає HSTS
    HTTP/1.1 200 OK
    Strict-Transport-Security: max-age=31536000; includeSubDomains

    Важлива деталь: заголовок HSTS браузер приймає лише з HTTPS-відповіді — надісланий у відкритій HTTP-відповіді, він ігнорується. Тому HSTS має сенс віддавати вже на захищеному з’єднанні, після редиректу. А коли політику збережено, наступний http→https перехід браузер робить внутрішньо, ще до будь-якого мережевого запиту (у DevTools Chrome це видно як запис «307 Internal Redirect», який насправді не йде на сервер).

    Для тестів це означає ось що: якщо ви жорстко зашили http:// у базовий URL, а домен уже під HSTS, браузер сам перепише схему на https:// ще до першого запиту в мережу, і ваші перевірки редиректу можуть поводитися не так, як ви очікуєте. Перевіряйте фактичну схему в отриманій відповіді, а не в тому, що набрали.

    Що саме захищає TLS

    TLS дає три різні гарантії, і плутати їх не варто — вони закривають різні атаки.

    Конфіденційність (confidentiality). Дані шифруються, тож посередник бачить лише беззмістовний набір байтів. Реалізується симетричним шифруванням (наприклад, AES): обидві сторони використовують один спільний ключ сесії.

    Цілісність (integrity). Отримувач може виявити будь-яку підміну чи пошкодження даних у дорозі. Якщо зловмисник змінить хоч один байт, перевірка не збіжиться і з’єднання розірветься. Забезпечується автентифікованим шифруванням (AEAD, Authenticated Encryption with Associated Data).

    Автентифікація сервера (server authentication). Клієнт переконується, що розмовляє саме з app.example.com, а не з тим, хто прикинувся ним. Це роль сертифіката, і саме тут ховається основна складність.

    Ключова ідея рукостискання (handshake): асиметрична криптографія (пара «відкритий/приватний ключ») працює лише на старті, щоб сторони узгодили спільний симетричний ключ сесії, а далі весь трафік шифрується швидким симетричним алгоритмом. У сучасному TLS 1.3 ключ сесії виводиться через ефемерний обмін Діффі — Гелмана (ECDHE), а приватний ключ із сертифіката використовується для підпису рукостискання, тобто для автентифікації, а не для передавання самого ключа. Наслідок — пряма секретність (forward secrecy): навіть якщо приватний ключ сервера пізніше витече, раніше записаний трафік із нього розшифрувати не вдасться. Актуальні версії — TLS 1.2 і TLS 1.3 (RFC 8446). Старіші SSL 2.0/3.0 та TLS 1.0/1.1 вважаються небезпечними й вимкнені.

    СерверКлієнтСерверКлієнтПеревіряє сертифікат і підписОбидві сторони виводять спільний ключ сесіїClientHello (шифри, ключ ECDHE)ServerHello, сертифікат, підпис рукостисканняЗашифрований трафік (симетричне шифрування)Зашифрована відповідьСерверКлієнтСерверКлієнтПеревіряє сертифікат і підписОбидві сторони виводять спільний ключ сесіїClientHello (шифри, ключ ECDHE)ServerHello, сертифікат, підпис рукостисканняЗашифрований трафік (симетричне шифрування)Зашифрована відповідь

    У тестах. Перелік cipher suites на конкретному сервері — питання його конфігурації: перевіряй openssl s_client або зовнішнім сканером, а не по памʼяті.

    Зверніть увагу: за замовчуванням TLS автентифікує лише сервер. Клієнт лишається анонімним, доки не увійде через логін/токен уже всередині захищеного каналу. Взаємну автентифікацію (mutual TLS, mTLS), де клієнт теж пред’являє сертифікат, застосовують у сценаріях «сервіс до сервісу», і в тестах вона зазвичай потребує окремого налаштування клієнтського сертифіката.

    Сертифікат і хто його видає

    Сертифікат (certificate) — це файл формату X.509, який пов’язує доменне ім’я з відкритим ключем сервера. Спрощено він містить:

    • домен(и), для яких дійсний — поле SAN (Subject Alternative Name);
    • відкритий ключ сервера;
    • хто видав сертифікат (issuer);
    • строк дії (від / до);
    • цифровий підпис центру сертифікації.

    Видає сертифікат центр сертифікації (Certificate Authority, CA) — організація, якій браузери й операційні системи довіряють «за замовчуванням». Приклади: Let’s Encrypt (безкоштовний, автоматичний), DigiCert, Sectigo.

    Довіра будується ланцюжком (chain of trust):

    Root CA  →  Intermediate CA  →  Сертифікат сервера (leaf)
    (у сховищі довіри ОС/браузера)                (для app.example.com)
    

    Кореневі сертифікати (root) вшиті у сховище довіри (trust store) вашої операційної системи та браузера. Сервер зазвичай пред’являє свій leaf-сертифікат разом із проміжними. Браузер перевіряє підписи вгору по ланцюгу до кореня, якому довіряє, а також:

    • чи збігається домен із SAN (сучасні браузери дивляться саме на SAN, а не на застаріле поле Common Name);
    • чи не вичерпався строк дії;
    • чи не відкликаний сертифікат (через OCSP або CRL).

    ні

    так

    ні

    так

    ні

    так

    Сервер пред'явив сертифікат

    Ланцюг веде до довіреного root?

    Помилка: невідомий CA

    Домен збігається із SAN?

    Помилка: домен не той

    Строк чинний і не відкликаний?

    Помилка: прострочено/відкликано

    З'єднання довірене

    ні

    так

    ні

    так

    ні

    так

    Сервер пред'явив сертифікат

    Ланцюг веде до довіреного root?

    Помилка: невідомий CA

    Домен збігається із SAN?

    Помилка: домен не той

    Строк чинний і не відкликаний?

    Помилка: прострочено/відкликано

    З'єднання довірене

    Перевірка відкликання на практиці ненадійна: OCSP-запит може заблокуватися чи «мовчати», тому браузери додатково возять власні куровані списки відкликаних сертифікатів (наприклад, CRLSets у Chrome, OneCRL у Firefox) і покладаються радше на них. Ба більше, галузь відходить від OCSP: Let’s Encrypt повністю вимкнув свій OCSP-сервіс у серпні 2025 року, лишивши тільки CRL — зокрема через приватність, адже кожен OCSP-запит розкриває оператору CA, які сайти й з якої IP-адреси відвідує користувач.

    Якщо будь-яка перевірка не проходить, браузер показує помилку. Найчастіші в роботі AQA:

    Помилка (Chrome)Причина
    NET::ERR_CERT_DATE_INVALIDсертифікат прострочений або дата на машині невірна
    NET::ERR_CERT_COMMON_NAME_INVALIDдомен не збігається з SAN
    NET::ERR_CERT_AUTHORITY_INVALIDпідписаний невідомим CA (часто self-signed)

    Окремо про прострочений сертифікат: це реальна причина масового «падіння» тестів вранці, коли сертифікат staging протух уночі. Перш ніж лізти в код, варто відкрити середовище руками й глянути на значок біля адреси.

    Self-signed сертифікати на dev/staging

    Self-signed сертифікат — це сертифікат, який підписав сам себе, без участі довіреного CA. На проді так не роблять, а от на dev/staging це нормально: випускати повноцінний публічний сертифікат для внутрішнього стенду часто недоцільно. Браузер такому сертифікату не довіряє й показує попередження (NET::ERR_CERT_AUTHORITY_INVALID).

    Ручний обхід — натиснути «Advanced → Proceed». Але в автотестах так не вийде, тому інструменти дають прапорці, які кажуть «не перевіряй сертифікат».

    Playwright — опція контексту ignoreHTTPSErrors:

    const context = await browser.newContext({
      ignoreHTTPSErrors: true,
    });

    Selenium — можливість acceptInsecureCerts:

    const options = new chrome.Options();
    options.setAcceptInsecureCerts(true);

    curl у скриптах і CI — прапорець -k / --insecure:

    curl -k https://staging.internal/api/health

    Компроміс тут важливий, і його треба усвідомлювати. Вимикаючи перевірку, ви робите тест сліпим до реального MITM і до помилок конфігурації сертифіката. Тому:

    • вмикайте ignoreHTTPSErrors тільки для середовищ, де це справді очікувано (dev/staging), а не глобально «щоб не заважало»;
    • на проді, навпаки, корисно мати окремий тест, який перевіряє, що сертифікат валідний і не близький до прострочення;
    • кращий за прапорець варіант там, де це можливо, — додати кореневий сертифікат вашого внутрішнього CA у сховище довіри агента CI. Тоді ланцюг стане валідним «по-справжньому», і перевірку вимикати не доведеться.

    Mixed content

    Mixed content — це коли сторінка завантажена по HTTPS, але тягне підресурси по HTTP. Проблема очевидна: значок обіцяє захист, а частина трафіку йде відкрито, тож зловмисник може підмінити той HTTP-скрипт і зламати всю сторінку.

    Браузери розрізняють два типи:

    • пасивний (passive) mixed content — картинки, відео, аудіо. Такі ресурси не керують сторінкою, тож ризик нижчий. Сучасні браузери автоматично підвищують ці запити з http до https, а якщо по HTTPS ресурс недоступний — блокують його, без відкату на HTTP (історично їх могли просто завантажити з попередженням у консолі);
    • активний (active) mixed content — скрипти, стилі, iframe, XHR/fetch. Ризик високий, бо ці ресурси керують сторінкою. Такий контент браузери за замовчуванням блокують.

    Реальне попередження в консолі Chrome виглядає приблизно так:

    Mixed Content: The page at 'https://app.example.com/' was loaded over HTTPS,
    but requested an insecure script 'http://cdn.example.com/app.js'.
    This request has been blocked; the content must be served over HTTPS.
    

    Для AQA це часте джерело плаваючих (flaky) падінь: тест «раптом» не бачить елемент, бо скрипт, який його малює, заблоковано як active mixed content. У консолі при цьому буде явне попередження. Тому при діагностиці «елемент не з’явився» варто відразу заглядати в консоль браузера — Playwright дає це через подію console:

    page.on('console', (msg) => {
      if (msg.type() === 'error') console.log('BROWSER:', msg.text());
    });

    Часто корінь проблеми — жорстко зашитий http:// у конфізі середовища або протокол-залежне посилання, яке зламалося після переїзду стенду на HTTPS.

    XSS — Cross-Site Scripting

    XSS — це впровадження чужого JavaScript у сторінку, яку бачать інші користувачі. Корінь проблеми один: дані, введені користувачем, потрапляють у HTML без належного екранування, і браузер виконує їх як код. Наслідки — крадіжка сесії, дії від імені жертви, підміна вмісту.

    Оглядово три типи:

    ТипДе живе payloadПриклад сценарію
    Stored (persistent)зберігається на сервері (БД)коментар зі <script> показується всім читачам
    Reflectedу параметрі запиту, вертається у відповідішкідливе посилання з ?q=<script>
    DOM-basedу клієнтському JS, сервер не задіянийinnerHTML = location.hash

    Захист — екранування виводу (output encoding), санітизація вводу, сучасні фреймворки (React, Angular), які за замовчуванням екранують вставки, і CSP як другий рубіж. Небезпечні місця — прямі присвоєння innerHTML, document.write, dangerouslySetInnerHTML.

    Для тестувальника XSS — це не лише про безпеку, а й про негативні перевірки: варто мати кейси, де у поле вводять <img src=x onerror=alert(1)> чи "><script>… і перевіряють, що на сторінці цей рядок показується як текст, а не виконується. Простий детектор у тесті: після сабміту поля переконатися, що в DOM не з’явився новий виконаний <script>, а рядок відрендерився екранованим (&lt;script&gt;).

    CSRF — Cross-Site Request Forgery

    CSRF експлуатує те, що браузер автоматично додає кукі до кожного запиту на домен. Ідея атаки: користувач залогінений у bank.example, заходить на сайт зловмисника, а той тихо шле форму чи запит на bank.example/transfer. Браузер прикріплює кукі сесії, і сервер думає, що це легітимна дія користувача.

    bank.exampleСайт зловмисникаБраузер жертвиbank.exampleСайт зловмисникаБраузер жертвиЖертва вже залогінена, кукі сесії збереженоВідкриває сторінку зловмисникаПрихована форма на bank.example/transferPOST /transfer (браузер додає кукі сесії)200 OK — переказ виконано правами жертвиbank.exampleСайт зловмисникаБраузер жертвиbank.exampleСайт зловмисникаБраузер жертвиЖертва вже залогінена, кукі сесії збереженоВідкриває сторінку зловмисникаПрихована форма на bank.example/transferPOST /transfer (браузер додає кукі сесії)200 OK — переказ виконано правами жертви

    Ключова відмінність від XSS: при CSRF зловмисник не читає відповідь і не краде дані напряму — він змушує браузер жертви виконати дію її ж правами.

    Захист:

    • CSRF-токен — унікальне непередбачуване значення, яке сервер кладе у форму й перевіряє при сабміті; чужий сайт його не знає;
    • атрибут кукі SameSite (Lax/Strict) — браузер не надсилає кукі при міжсайтових запитах;
    • перевірка заголовків Origin/Referer на боці сервера.

    У тестах CSRF-токени — часте джерело болю в API-перевірках в обхід UI: сервер відповість 403, бо ви не передали свіжий токен. Правильний шлях — спершу отримати токен зі сторінки чи спеціального ендпоінта, а потім підставити його в запит, а не хардкодити.

    SQL-injection

    SQL-injection — це впровадження SQL-коду через дані, які потрапляють у запит до бази без параметризації. Класичний приклад — конкатенація рядка:

    // небезпечно
    db.query("SELECT * FROM users WHERE name = '" + input + "'");

    Якщо у input передати ' OR '1'='1, умова стане завжди істинною і запит поверне всіх користувачів. Ще гірше — '; DROP TABLE users; --.

    Захист один і надійний — параметризовані запити (prepared statements), де дані передаються окремо від тексту запиту й ніколи не інтерпретуються як код:

    // безпечно
    db.query("SELECT * FROM users WHERE name = ?", [input]);

    AQA сюди дотичний через негативні кейси: у поля вводу підставляють характерні payload’и (' OR 1=1 --, лапки, крапка з комою) і перевіряють, що застосунок повертає коректну помилку валідації або порожній результат, а не «раптом» видає чужі дані чи 500. Робити це варто виключно на своїх тестових середовищах і ніколи — на чужих чи продакшн-системах без дозволу.

    CSP — Content-Security-Policy

    CSP — це заголовок відповіді, який каже браузеру, з яких джерел дозволено завантажувати ресурси й виконувати код. Це головний рубіж проти XSS: навіть якщо зловмисник впровадив скрипт, CSP не дасть браузеру його виконати, бо джерело не в білому списку.

    Content-Security-Policy: default-src 'self'; script-src 'self' https://cdn.example.com; style-src 'self' 'unsafe-inline'; img-src 'self' data:

    Основні директиви:

    ДирективаЩо обмежує
    default-srcзначення за замовчуванням для решти
    script-srcзвідки можна вантажити/виконувати JS
    style-srcджерела стилів
    img-srcджерела зображень
    connect-srcкуди дозволено fetch/XHR/WebSocket
    frame-srcщо можна вбудовувати в iframe

    Є також режим тільки-звіт — заголовок Content-Security-Policy-Report-Only, який нічого не блокує, а лише надсилає звіти про порушення. Його зручно вмикати перед бойовим запуском політики, щоб побачити, що вона зламала б, не ламаючи насправді.

    Для автотестів CSP має цілком практичний бік. Якщо ви звикли інжектити допоміжний скрипт або додавати inline-обробники в DOM самої сторінки — сувора CSP (без 'unsafe-inline', без 'unsafe-eval') це заблокує, і в консолі з’явиться повідомлення про порушення. При цьому сам page.evaluate у Playwright здебільшого проходить: код їде через протокол налагодження (Chrome DevTools Protocol) і виконується в контексті сторінки, а не вставляється як <script>, тож директива script-src його зазвичай не зачіпає. Виняток — дуже сувора CSP без 'unsafe-eval': окремі механізми на кшталт page.waitForFunction спираються на eval-подібні конструкції й під такою політикою можуть падати. А от addScriptTag чи спроба вставити inline-обробник у розмітку сторінки під суворою CSP не спрацюють — саме для таких випадків Playwright має окрему опцію bypassCSP. І навпаки: корисно мати перевірку, що CSP взагалі присутній і що список джерел не «поплив» після релізу (наприклад, ніхто не дописав 'unsafe-inline' заради швидкого фіксу).

    Кукі: HttpOnly і Secure

    Кукі керують сесіями, тож їхні атрибути безпеки — критичні. Три ключові:

    АтрибутЩо робитьПроти чого захищає
    HttpOnlyкукі недоступне з JavaScript (document.cookie його не бачить)крадіжка сесії через XSS
    Secureкукі надсилається тільки по HTTPSперехоплення по відкритому HTTP
    SameSiteобмежує надсилання при міжсайтових запитахCSRF
    Set-Cookie: session=abc123; HttpOnly; Secure; SameSite=Lax; Path=/

    Логіка проста: HttpOnly розриває головний вектор XSS — навіть якщо чужий скрипт виконався, він не прочитає токен сесії. Secure гарантує, що кукі не «витече» випадковим HTTP-запитом. SameSite=Lax обмежує надсилання кукі при більшості міжсайтових переходів; у Chromium-браузерах (Chrome, Edge) це ще й типова поведінка для кукі без явно заданого атрибута, тоді як Firefox і Safari до такого дефолту так і не перейшли — тож покладатися на «дефолт Lax» не варто, атрибут краще задавати явно. SameSite=None дозволяє крос-сайт, але тоді браузер вимагає ще й Secure.

    Прямий наслідок для AQA: токен сесії з HttpOnly ви не прочитаєте через document.cookie в тесті. Це не баг тесту — це так задумано. Читати й підставляти такі кукі треба через API контексту браузера, а не через JS сторінки:

    const cookies = await context.cookies();
    const session = cookies.find((c) => c.name === 'session');

    Це ж стосується ізоляції стану між тестами: очищення document.cookie не прибере HttpOnly-кукі. Надійніше стартувати з чистого контексту або керувати станом через storageState / context.clearCookies().

    Чому секретам не місце у фронтенді й у query

    Фронтенд-код повністю видимий користувачеві. Будь-хто відкриває DevTools, вкладку Sources, і читає весь ваш JavaScript, включно з тим, що «заховане» у змінну чи згорнуте мініфікатором. Тому будь-який ключ, зашитий у клієнтський код — API-секрет, приватний токен, пароль сервісу — це вже не секрет. Фронтенду можна давати лише публічні ідентифікатори (наприклад, публічний ключ, який і призначений бути відкритим).

    Окремо про query-рядок. Здавалося б, по HTTPS URL зашифрований — то чому не покласти токен у ?token=…? Тому що повний URL із параметрами зазвичай:

    • пишеться в логи сервера, проксі та балансувальників;
    • зберігається в історії браузера;
    • може «протекти» у заголовку Referer при переході на інший сайт;
    • потрапляє в аналітику й системи моніторингу.
    # погано: токен видно всюди, де логуються URL
    GET /api/data?token=SECRET123 HTTP/1.1
    
    # краще: секрет у заголовку, який не логується за замовчуванням
    GET /api/data HTTP/1.1
    Authorization: Bearer SECRET123

    Тому секрети передають у заголовках (найчастіше Authorization) або в тілі POST, а не в query. Для тестів це теж робоче правило: у CI токени тримають у секретах середовища й підставляють через змінні оточення, а не хардкодять у репозиторій. Логи автотестів корисно фільтрувати, щоб токен не осів у публічному звіті білда.

    MITM і як HTTPS йому протидіє

    MITM (Man-in-the-Middle) — атака, коли зловмисник вклинюється між клієнтом і сервером: перехоплює, читає, а то й підміняє трафік, лишаючись непоміченим для обох сторін. Класичний сценарій — підставна Wi-Fi-точка в кафе, яка вдає легітимну мережу.

    HTTPS протидіє двома механізмами одночасно, і важливо, що потрібні обидва:

    • шифрування — перехоплений трафік нечитабельний, тож пасивне підслуховування марне;
    • автентифікація сервера — щоб не просто підслухати, а видати себе за сервер, зловмиснику потрібен валідний сертифікат на потрібний домен, підписаний довіреним CA. Отримати такий без контролю над доменом він не може, а self-signed чи чужий сертифікат браузер відхилить із попередженням.

    Саме тому попередження про сертифікат, яке хочеться «просто проклацати», — це і є момент, коли HTTPS ловить потенційний MITM. Ігнорувати його наосліп означає власноруч відкрити канал атаки.

    Практичний парадокс для AQA: інструменти, якими ми перехоплюємо й аналізуємо трафік — mitmproxy, Charles, Burp Suite — це, по суті, легальний MITM. Вони працюють так: встановлюють свій кореневий сертифікат у сховище довіри вашої машини, і тоді браузер довіряє сертифікатам, які проксі генерує на льоту для кожного домену. Без цього кореневого сертифіката браузер підняв би тривогу — що й доводить, що захист працює.

    Логічне продовження — перехоплення мережі в самих автотестах. Playwright дає page.route, яким ви підмінюєте відповіді, мокаєте API, імітуєте помилки й таймаути:

    await page.route('**/api/user', (route) => {
      route.fulfill({
        status: 200,
        contentType: 'application/json',
        body: JSON.stringify({ id: 1, name: 'Test User' }),
      });
    });

    По суті це контрольований MITM усередині вашого тесту: ви навмисне стаєте посередником, щоб ізолювати фронтенд від бекенду, прибрати мережеву нестабільність (одну з головних причин flakiness) і детермінувати дані. Різниця з атакою лише в намірі й у тому, що ви робите це у власному, ізольованому оточенні.

    Розуміння цієї механіки замикає всю тему: сертифікати, ланцюг довіри, Secure-кукі, CSP і заборона на секрети у фронтенді — це різні шари однієї відповіді на просте питання «як довіряти каналу, який фізично проходить через чужі руки».