Збережені xss-атаки і захист від них (видаляємо javascript з html в браузері)
Збережені XSS-атаки
Cross Site Scripting атака - це зловмисне програмне вплив на браузер користувача з метою крадіжки даних або заподіяння іншої шкоди. Щоб не кидати тінь на CSS (Caskading Style Sheets), домовилися в скороченому позначенні замінювати перший символ, отримали абревіатуру: XSS-атаки.
Збережені XSS-атаки - такі, при яких скрипт додається зловмисником в тіло сторінки (за допомогою форм введення - текстових полів, інпут, contenteditable- елементів - на форумах, в гостьових книгах і т.п.). Вставлений в повідомлення замаскований XSS-скрипт зберігається (звідси і назва) сайтом, потім, при запиті користувачами зараженої сторінки, запускається і атакує.
Варіанти оформлення впроваджуваного XSS-коду, що краде кукі
У тегах .
У вигляді обробника подій в html-тегу.
Якийсь текст
Серверна захист від збережених XSS-атак
Найпростіший приклад. Зловмисник вводить:
Повідомлення відправляється на північ. На сервері фільтр "бачить" небезпечну символьну послідовність onmouseover і вирізає її. У підсумку, не являє ніякої загрози (нерозпізнаних браузерами) oonmouseovernmouseover перетворюється в onmouseover. тобто в ясна браузерам вказівку на подію. У загальному випадку, збережені XSS-атаки так і здійснюють: вводять в поля сайту комбінації символів, відправляють, дивляться, що виходить на виході. Далі роблять припущення про те, як працює фільтр і починають складати "бойову" комбінацію для нього.
Щоб повноцінно розпізнавати html на сервері, там потрібен html-парсер, який врахує всі, аж до особливостей різних версій того чи іншого браузера. Чи не крос, а ПОНАД-браузерні парсер. Рішення може бути більш складним, ніж сама задача.
Браузерна захист від збережених XSS-атак
Html-парсери адже вже є - в браузерах. Користуючись цим, принадно перекласти задачу розпізнавання збережених XSS-атак (ну, і захист від них) на самі браузери. Тоді стане непотрібним передбачати на сервері, чи побачить в доданому до форуму повідомленні активний вміст Firefox, чи побачить там активний вміст Інтернет-експлорер і т.д. Логічніше запитати у браузера: "Ти, Firefox, бачиш тут скрипт?". Або: "Ти, Інтернет-експлорер, бачиш в цьому повідомленні активний вміст?" Якщо браузер - саме цей, конкретний, цієї версії - виявив скрипт, тоді можна віддати браузеру наказ нейтралізувати виявлене.
Безпечне завантаження в браузер
Скрипти виконуються браузером по ходу завантаження сторінки. Нехай навіть фрагмент тексту невидимий або прихований - якщо там є скрипт, скрипт обов'язково буде запущений. Якогось html-контейнера, який забороняє виконання скриптів, до сих пір не винайдено (якби такий контейнер придумали, питання збережених XSS-атак не стояло б в принципі).
Після закінчення завантаження, браузер повинен відмічені нами частини тексту проаналізувати, убезпечити їх, потім тільки показати користувачеві. Подія, відповідне закінчення завантаження сторінки, є, називається воно onload. може бути застосовано до контейнера body. Значить, тіло сторінок нашого сайту, по крайней мере, тих з них, які містять додається користувачами контент, має реагувати на закінчення завантаження:
де getid ( "message") - функція, що приймає ідентифікатор того html-контейнера, вміст якого має бути проаналізовано і знешкоджено.
Функція: вибірник фрагментів
Шостий експлорер у відповідь на document.getElementByClassName () видає об'єкт (не колекція об'єктів, як можна було б очікувати). Підлаштовуватися доводиться під найслабшого, тому, будемо отримувати фрагменти тексту так, як хоче експлорер 6 - по одному. Спиратися будемо все ж на id. але при цьому допускаючи безліч фрагментів з однаковим id на одній сторінці. Таке проти правил, зате вийде кросбраузерності.
Нічого складного, проте, по кожному рядку є пояснення - в титли (просто наведіть курсор).
Функція: чистильник html
Користуючись методами і властивостями DOM, зокрема, можна отримати:
- масив вкладених html-контейнерів;
- ім'я кожного вкладеного html-контейнера;
- імена всіх атрибутів кожного html-контейнера.
У записі виду
Застосуємо підхід "білого списку" - вичерпного переліку дозволених тегів і атрибутів. Все, що не відповідає білому списку, будемо безжально знищувати. Алгоритм: перебрати всі дочірні вузли, видаляючи такі, яких немає в дозвільному списку, таким же чином перебрати всі атрибути для кожного з дозволених вузлів.
Функції вищого порядку - array.forEach (), array.some () - застосувати не вийде, шостий Інтернет-експлорер таких функцій не зрозуміє. Обійдемося простими циклами. Крім того, шостий експлорер для будь-якого тега буде знаходити повний комплект атрибутів (кілька десятків), навіть в тому випадку, якщо ніяких атрибутів в тезі записано не було. Тому, доведеться простежувати по властивості specified. заданий кожен атрибут явно.
Ще одна складність, пов'язана з шостим Експлорером. Неможливо в ньому видалити атрибути-обробники подій, використовуючи загальновживане для інших браузерів node.removeAttribute ( "attrName"). Спрацьовує в експлорері для атрибутів-обробників таке: node.attrName = null. однак, тоді треба буде перевіряти (хоча б по перших символах "on"), чи є атрибут оброблювачем - інакше отримаємо аварійне прерваним скрипта при спробі обнулити який-небудь необнуляемий атрибут (наприклад, contentEditable).
Пояснення в титли. Поняття тег. вузол. html-контейнер використовуються, як синоніми.
Для тих, хто бажає використовувати це, не вникаючи в сенс, викладу в формі рецепта, придатного до швидкого застосування.
Сторінка сайту на сервері: