Уязвимости и атаки типа Cross-Site Scripting (XSS) не исчезнут в ближайшее время, но можно снизить риск успешных XSS атак.
JavaScript прошел путь от добавления динамичности к статическим HTML-страницам до ключевого компонента современных веб-приложений, делая XSS распространенной уязвимостью безопасности. Атаки типа XSS стали более влиятельными из-за увеличения использования JavaScript не только на клиентской, но и на серверной стороне с помощью Node.js. Добавив к этому большое количество внешних зависимостей, загружаемых во время выполнения, получается запутанная сеть взаимосвязанных скриптов. Некоторые из которых могут быть уязвимыми или даже вредоносными.
Cross-Site Scripting – это сложная и запутанная сфера безопасности веб-приложений, которая делает практически невозможным предотвратить каждую отдельную атаку. (JavaScript является самым популярным средством атаки, но XSS возможен и с другими типами скриптов, включая XSS в CSS.) Большинство XSS уязвимостей и атак можно предотвратить, соблюдая несколько практик в разработке и внедрении.
Предотвращение XSS атак
Соблюдая эти практики, можно предотвратить большинство атак типа Cross-Site Scripting:
- Установить заголовки безопасности HTTP: Нужно определить правильные заголовки Content Security Policy (CSP) в ответах HTTP, чтобы предотвратить загрузку вредоносных скриптов.
- Считать все вводные данные ненадежными: ЗВсегда проверять входные данные пользователя (включая входные и выходные данные API), выполнять валидацию входных данных и использовать контекстно-зависимое кодирование выходных данных.
- Использовать безопасные практики кодирования и инструменты: Избегать использования inline скриптов и правильно использовать любые функции, устойчивые к XSS, которые предоставляет фреймворк приложений, такие как автоматические функции кодирования.
- Проводить регулярное тестирование на уязвимости: Периодически проверять веб-сайты и приложения с помощью актуального сканера веб-уязвимостей, чтобы своевременно выявлять их.
(Важно: фильтрация здесь намеренно не упоминается – далее описано, почему нельзя доверять фильтрации XSS.)
Уязвимости типа Cross-Site Scripting
По сути, XSS является типом инъекционной атаки, как и SQL-инъекция, но внедряется JavaScript код вместо SQL-инструкций. Но в отличие от SQL-инъекции, где всегда пытаются изменить SQL-запрос, существует много различных типов XSS, в зависимости от способа доставки и выполнения вредоносного кода. Основные типы XSS атак:
- Reflected XSS атаки: Классическая XSS уязвимость, когда значение параметра ввода HTTP запроса непосредственно используется в ответе, отображая вредоносный код из ввода и выполняя его в браузере пользователя. Хотя это самый распространенный тип XSS, его последствия ограничиваются одним пользователем и браузером.
- Stored XSS атаки: Чтобы внедрить JavaScript в несколько браузеров, злоумышленник может попытаться ввести XSS-атаку на внутренний ресурс, к которому будет иметь доступ много пользователей. Если вредоносный код сохраняется как есть и веб-сервер не очищает его при загрузке, одна запись в базе данных или сериализованном файле может привести к XSS в тысячах браузеров, когда они будут загружать эту запись.
- DOM-based XSS атаки: Многие веб-приложения переписывают свою внутреннюю объектную модель документа (DOM) во время выполнения без перезагрузки страницы. Если злоумышленник сможет внедрить вредоносный JavaScript код в DOM и запустить его, этот код будет существовать только в браузере пользователя. Такие атаки будут невидимы (и невозможны для предотвращения) на серверной стороне.
Единственное, что объединяет все XSS уязвимости — это то, что они позволяют JavaScript коду существовать где-то во вводе или выводе приложения. Фильтры пытались найти этот код и блокировать его, однако в долгосрочной перспективе это не сработало.
Почему нельзя доверять XSS-фильтрации
Ранние подходы к предотвращению XSS-атак основывались на удалении тегов <script> из введенных данных, начиная с самодельных фильтрующих функций, которые со временем переросли в мощные фильтры, встроенные в веб-браузеры. Проблема заключалась в том, что, хотя надежно идентифицировать и блокировать конкретный вредоносный код легко, создать общие шаблоны для остановки вредоносных скриптов без вмешательства в легитимные оказалось почти невозможным.
XSS-фильтрация не работает и не может быть единственной защитой от XSS-атак. Хотя большинство фаерволов (WAF) имеют встроенные XSS-фильтры, которые могут остановить основные атаки, обход XSS-фильтров для обмана правил WAF является основой для любого серьезного злоумышленника. Поэтому, никогда не стоит полагаться только на XSS-фильтр для обеспечения защиты от атак.
Cross-Site Scripting в API
Стереотипная XSS-атака – это когда кто-то вводит <script>alert(1)</script> в поле формы или параметр URL. Но как насчет XSS в современных приложениях, управляемых API? С бэкендом, который теперь действует как отдельный поставщик данных для любого количества фронтендов, общающихся с ним через API, невозможно централизованно предотвратить XSS на сервере. Запросы API, которые включают чувствительные данные, являются привлекательной целью для злоумышленников. Это делает XSS очень реальной угрозой, даже без видимого поля формы.
Лучшие практики многоуровневой безопасности для предотвращения XSS
Не существует решения, которое бы полностью защитило приложения от XSS. Но, если придерживаться нескольких безопасных практик для создания нескольких уровней защиты, можно сделать успешные XSS-атаки крайне маловероятными.
Победное сочетание заключается в значительном ограничении поверхности атаки с помощью правильных заголовков CSP, а также использовании безопасных практик кодирования и инструментов для минимизации количества XSS-уязвимостей, которые попадают в продакшн. Финальным штрихом будет регулярное сканирование на уязвимости с помощью качественного инструмента DAST.







