Когда я 3-4 года назад работал менеджером ИТ-проектов в веб-студии, то разработал корпоративный шаблон ТЗ. Эх, ностальгия... Среди требований ИБ я прописал, что не допускается проведение различных инъекций:
SQL (в канале было опубликовано 2 поста), JS и т.д.
Разберем JS-инъекцию на примере XSS-атаки.
🔪 XSS (Cross-Site Scripting, ЭксЭсЭс, Межсайтовый скриптинг). Уязвимость в веб-приложениях, которая позволяет внедрять и исполнять произвольный скрипт (обычно JS).
Часто проверяют есть ли уязвимость вызывая функцию alert. alert выводит на экран модальное окно с сообщением. Если функция вызовется, значит уязвимость есть.
Есть 3 основных разновидности XSS:
🔴 Reflected (Отраженная).
Вредоносный скрипт «отражается» от веб-приложения, т.е. сервер возвращает (отражает) этот код обратно в ответе. Например, в сообщении об ошибке, результатах поиска или статусе).
В самом простом задании на Portswigger на эту уязвимость нужно вставить в строку поиска:
<script>alert(1)</script>
🔴 Stored (хранимая).
Более опасный вариант. Вредоносный скрипт «сохраняется» на сервере или в БД. Часто используется там, где человек вводит информацию, и она видна многим: личка и беседы, комменты, отзывы...
В самом простом задании на Portswigger на эту уязвимость нужно опубликовать <script>alert(1)</script> в поле ввода текста комментария.
🔴 DOM-based (на основе DOM-дерева).
Угроза возникает, когда на клиенте JS обрабатывает данные из ненадежного источника небезопасным способом, обычно записывая данные обратно в DOM. То есть значения вставляются "как есть" в код страницы. Значит можно сформировать URL, где параметры будут содержать не обычные значения, а вредоносный скрипт. Он вставится в форму и выполнится.
В самом простом задании на Portswigger предлагается:
1. Написать что-то в строку поиска, например, rocknroll. Отправится GET-запрос с передачей квери-параметра /?search=rocknroll.
2. Открываем инспектором сформированное DOM-дерево. В поиске по дереву ищет rocknroll.
Видим:
<script>
function trackSearch(query) {
document.write('<img src="/resources/images/tracker.gif?searchTerms='+query+'">');
}
var query = (new URLSearchParams(window.location.search)).get('search');
if(query) {
trackSearch(query);
}
</script>
<img src="/resources/images/tracker.gif?searchTerms=rocknroll">
3. Ага. Произошла подстановка в <img src="">.
А что если мы закроем этот тэг, и после него вызовем что-то иное?
4. Передаем в строку поиска (можно сразу в адресную строку браузера):
"><svg onload=alert(1)>
Получится:
<img src="/resources/images/tracker.gif?searchTerms="><svg onload=alert(1)>
что закроет тэг <img> и вызовет функцию alert.
❓ А есть еще XSS-варианты?
В замечательной статье на SecurityLab описаны разные виды атак и даны рекомендации по защите.
Еще есть: Blind, Mutated, Polyglot, Contextual.
🤡 И даже Self-XSS, когда мошенник убеждает пользователя выполнить в консоле скрипт, который накрутит ему кучу денег/токенов/еще чего-то.
Хорошая статья на Хабре.
❓ Как защититься?
На английском языке подробно написано здесь.
В основном это:
1. Валидировать и экранировать данные ввода/вывода.
2. Настроить сервер таким образом, чтобы в ответах он отправлял HTTP-заголовок Content-Security-Policy. Он задает белый список источников для загрузки скриптов, стилей и прочих ресурсов.
⚡️ Ограничит источники контента только исходным сервером (без поддоменов):
Content-Security-Policy: default-src 'self'
⚡️ Разрешает получение контента с доверенного домена и всех его поддоменов:
Content-Security-Policy: default-src 'self'*.trusted.com
Больше примеров в доках mdm.
Понравился пост? Подписывайся, чтобы не пропустить следующий.
Артем Лещев