Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Що таке Trusted Types і як вони закривають DOM XSS?

DOM XSS виникає повністю в браузері: JavaScript бере дані з контрольованого нападником джерела (location.hash, location.search, postMessage, відповідь API) і передає в небезпечний приймач (sink):

element.innerHTML = location.hash.slice(1);      // HTML-приймач
script.src = params.get('widget');               // URL скрипта
setTimeout(userInput);                            // рядок як код
document.write(...);  eval(...);  new Function(...);

Сервер такої вразливості не бачить: шкідливе значення взагалі може не доходити до нього (фрагмент #... не надсилається на сервер). Знайти всі такі місця у великому застосунку й бібліотеках - важко.

Trusted Types змінюють правила гри: з увімкненою політикою небезпечні приймачі відмовляються приймати звичайні рядки. Їм потрібні спеціальні типізовані об'єкти (TrustedHTML, TrustedScript, TrustedScriptURL), які можна створити лише через зареєстровані політики.

Увімкнення - через CSP:

Content-Security-Policy: require-trusted-types-for 'script'; trusted-types app-sanitizer

Політика - єдине місце, де рядок стає «довіреним»:

const sanitizer = trustedTypes.createPolicy('app-sanitizer', {
  createHTML: (input) => DOMPurify.sanitize(input),
});

element.innerHTML = sanitizer.createHTML(userHtml);   // дозволено
element.innerHTML = userHtml;                         // TypeError - заблоковано

Що це дає:

  • кількість місць для перевірки зменшується до кількох політик замість сотень присвоєнь innerHTML по всьому коду;
  • порушення помітні: спроба записати рядок у приймач кидає помилку (і може звітувати через CSP);
  • контроль над бібліотеками: директива trusted-types обмежує, які політики можна створювати, - стороння бібліотека не створить «свою» лазівку непомітно.

Впровадження:

  1. Content-Security-Policy-Report-Only: require-trusted-types-for 'script' - зібрати всі місця, де рядки потрапляють у приймачі;
  2. переписати їх на безпечні API (textContent, setAttribute для безпечних атрибутів) або пропустити через політику з санітизацією;
  3. увімкнути блокування.

Обмеження:

  • підтримка браузерами: Trusted Types давно є в Chromium, інші браузери додавали її пізніше - перед покладанням на них як на основний захист варто перевірити актуальну підтримку. Там, де Trusted Types немає, код має лишатися безпечним сам по собі;
  • фреймворки (React, Vue) мають власний захист від XSS у шаблонах; Trusted Types закривають «аварійні виходи» на кшталт dangerouslySetInnerHTML, v-html і прямої роботи з DOM.

Докладніше в документації: MDN: Trusted Types API

Перевір себе

20 випадкових питань за спробу, після завершення - розбір кожної помилки

Схожі питання