Як запобігти XSS

У цьому розділі ми опишемо деякі загальні принципи запобігання уразливості міжсайтових сценаріїв та способи використання різних поширених технологій для захисту від атак XSS.

введення користувача

Запобігання сценаріям між сайтами, як правило, можна досягти за допомогою двох рівнів захисту:

Ви можете використовувати сканер відрижки для сканування веб-сайтів на наявність численних вразливих місць безпеки, включаючи XSS. Сучасна логіка сканування Берпа повторює дії кваліфікованого зловмисника і здатна досягти відповідно високого охоплення вразливостей XSS. Ви можете використовувати сканер відрижки, щоб отримати впевненість у тому, що ваш захист від атак XSS працює ефективно.

Кодувати дані на виході

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

У контексті HTML вам слід перетворити значення, що не внесені до білого списку, в сутності HTML:

  • перетворює на:
  • > перетворює на:>

У контексті рядка JavaScript нелітерально-цифрові значення повинні бути захищені Unicode:

  • перетворює на: \ u003c
  • > перетворює на: \ u003e

Іноді вам потрібно застосувати кілька шарів кодування у правильному порядку. Наприклад, щоб безпечно вбудувати введення користувача в обробник подій, вам потрібно мати справу як з контекстом JavaScript, так і з контекстом HTML. Отже, спочатку потрібно вникнути вхідного коду Unicode, а потім HTML-кодувати його:

Підтвердити вхід після прибуття

Кодування - це, мабуть, найважливіший напрямок захисту XSS, але цього недостатньо для запобігання вразливості XSS у кожному контексті. Ви також повинні перевірити введення якомога суворіше в той момент, коли він вперше отриманий від користувача.

Приклади перевірки вхідних даних включають:

  • Якщо користувач подає URL-адресу, яка буде повернута у відповідях, підтверджуючи, що вона починається з безпечного протоколу, такого як HTTP та HTTPS. Інакше хтось може використати ваш сайт із шкідливим протоколом, таким як javascript або дані .
  • Якщо користувач надає значення, яке, як він очікував, буде числовим, перевіряючи, що значення насправді містить ціле число.
  • Перевірка того, що введення містить лише очікуваний набір символів.

Перевірка вхідних даних в ідеалі повинна працювати, блокуючи недійсне введення. Альтернативний підхід - спроба очистити недійсний ввід, щоб зробити його дійсним, є більш схильним до помилок, і його слід уникати, де це можливо.

Білий чи чорний списки

Перевірка вхідних даних, як правило, повинна використовувати білі списки, а не чорні списки. Наприклад, замість того, щоб намагатися скласти список усіх шкідливих протоколів (javascript, дані тощо), просто складіть список безпечних протоколів (HTTP, HTTPS) і забороніть будь-що, що не входить до списку. Це гарантуватиме, що ваш захист не зламається, коли з’являться нові шкідливі протоколи, і зробить його менш сприйнятливим до атак, які намагаються заплутати недійсні значення, щоб уникнути чорного списку.

Дозвіл "безпечного" HTML

Дозволяти користувачам розміщувати розмітку HTML слід уникати, де це можливо, але іноді це бізнес-вимога. Наприклад, сайт блогу може дозволити розміщувати коментарі, що містять обмежену розмітку HTML.

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

Найменш поганим варіантом є використання бібліотеки JavaScript, яка виконує фільтрацію та кодування в браузері користувача, наприклад DOMPurify. Інші бібліотеки дозволяють користувачам надавати вміст у форматі розмітки та конвертувати розмітку в HTML. На жаль, усі ці бібліотеки час від часу мають вразливості XSS, тому це не ідеальне рішення. Якщо ви використовуєте такий, вам слід уважно стежити за оновленнями безпеки.

На додаток до JavaScript, інший вміст, такий як CSS і навіть звичайний HTML, може бути шкідливим у деяких ситуаціях.

Як запобігти XSS за допомогою механізму шаблонів

Багато сучасних веб-сайтів використовують механізми шаблонів на стороні сервера, такі як Twig та Freemarker, для вбудування динамічного вмісту в HTML. Вони, як правило, визначають власну систему виходу. Наприклад, у Twig ви можете використовувати фільтр e () з аргументом, що визначає контекст:

Деякі інші механізми шаблонів, такі як Jinja та React, за замовчуванням уникають динамічного вмісту, що ефективно запобігає більшості випадків XSS.

Ми рекомендуємо уважно ознайомитися з функціями, що виходять з екрана, коли ви оцінюєте, чи використовувати певний механізм шаблону або фреймворк.

Якщо ви безпосередньо об'єднаєте введення користувача у рядки шаблонів, ви будете вразливі до введення шаблону на стороні сервера, що часто є більш серйозним, ніж XSS.

Як запобігти XSS в PHP

У PHP є вбудована функція для кодування сутностей, які називаються htmlentities. Вам слід викликати цю функцію, щоб уникнути введення даних, коли всередині контексту HTML. Функцію слід викликати з трьома аргументами:

  • Ваш вхідний рядок.
  • ENT_QUOTES, що є прапором, який визначає, що всі котирування повинні кодуватися.
  • Набір символів, який у більшості випадків повинен бути UTF-8.

Коли ви знаходитесь у контексті рядка JavaScript, вам потрібно ввести Unicode-escape, як уже було описано. На жаль, PHP не надає API для Unicode-екранування рядка. Ось декілька кодів, щоб зробити це в PHP:

функція jsEscape ($ str) $ output = '';
$ str = str_split ($ str);
для ($ i = 0; $ i ":
$ output. = sprintf ("\\ u% 04x", $ chrNum);
перерва;
за замовчуванням:
$ output. = $ str [$ i];
перерва;
>
>
повернути вихід $;
>
?>

Ось як використовувати функцію jsEscape у PHP:

Як варіант, ви можете використовувати механізм шаблонів.

Як запобігти XSS на стороні клієнта в JavaScript

Щоб уникнути введення даних користувача в контексті HTML у JavaScript, вам потрібен власний кодер HTML, оскільки JavaScript не надає API для кодування HTML. Ось приклад коду JavaScript, який перетворює рядок у сутності HTML:

Потім ви використовуєте цю функцію наступним чином:

Якщо ваше введення знаходиться всередині рядка JavaScript, вам потрібен кодер, який виконує перехід в Unicode. Ось зразок кодера Unicode:

функція jsEscape (str) return String (str) .replace (/ [^ \ w.]/gi, function (c) return '\\ u' + ('0000' + c.charCodeAt (0) .toString (16) ). фрагмент (-4);
>);

Потім ви використовуєте цю функцію наступним чином:

Як запобігти XSS у jQuery

Найпоширеніша форма XSS у jQuery - це коли ви передаєте введення користувача в селектор jQuery. Веб-розробники часто використовують location.hash і передають його селектору, що спричиняє XSS, оскільки jQuery відображатиме HTML. jQuery розпізнав цю проблему та виправив логіку селектора, щоб перевірити, чи введення починається з хешу. Тепер jQuery відображатиме HTML лише в тому випадку, якщо першим символом є. Якщо ви передаєте ненадійні дані селектору jQuery, переконайтеся, що ви правильно втекли значення за допомогою функції jsEscape вище.

Пом'якшення XSS за допомогою політики безпеки вмісту (CSP)

Політика безпеки вмісту (CSP) - це остання лінія захисту від міжсайтових сценаріїв. Якщо запобігання XSS не вдається, ви можете використовувати CSP для пом'якшення XSS, обмеживши можливості зловмисника.

CSP дозволяє керувати різними речами, наприклад, чи можна завантажувати зовнішні сценарії та чи будуть виконуватися вбудовані сценарії. Для розгортання CSP потрібно включити заголовок відповіді HTTP, який називається Content-Security-Policy, зі значенням, що містить вашу політику.

Прикладом CSP є такий:

default-src 'само'; script-src 'само' object-src 'немає'; frame-src 'немає'; base-uri 'немає';

Ця політика визначає, що такі ресурси, як зображення та сценарії, можна завантажувати лише з того самого джерела, що і головна сторінка. Отже, навіть якщо зловмисник може успішно ввести корисне навантаження XSS, він може завантажувати ресурси лише з поточного джерела. Це значно знижує ймовірність того, що зловмисник може використати вразливість XSS.

Якщо вам потрібно завантаження зовнішніх ресурсів, переконайтеся, що ви дозволяєте лише сценаріям, які не допомагають зловмиснику використовувати ваш сайт. Наприклад, якщо ви додали певні домени в білий список, то зловмисник може завантажити будь-який сценарій із цих доменів. Де це можливо, спробуйте розмістити ресурси у власному домені.

Якщо це неможливо, ви можете використовувати політику на основі хешу або nonce, щоб дозволити сценарії в різних доменах. Nonce - це випадковий рядок, який додається як атрибут скрипта або ресурсу, який буде виконаний лише в тому випадку, якщо випадковий рядок відповідає згенерованому сервером. Зловмисник не може вгадати рандомізований рядок і тому не може викликати сценарій або ресурс із дійсним nonce, тому ресурс не буде виконаний.

Читати далі

Хочете відстежувати свій прогрес і мати більш персоналізований досвід навчання? (Це безкоштовно!)