XSS: напад та захист
Якщо вас не зламали вчора і сьогодні — вас зламають завтра. Механізми: XSS, SQL-injection та інші. і в цій статті я розповім про XSS.
XSS: вас зламали
Ви точно чули про атаки на великі інфраструктури, при яких викрадали персональні дані, медичні дані користувачів та клієнтів. знань, часу та грошей. За таких розкладів атака на ваш ресурс була невигідною для зловмисників.
XSS - це міжсайтовий скриптинг. Простіше кажучи, це спроба керування вашим браузером без вашого відома. провернути ще багато різних неприємних речей, але про це згодом.
Суть будь-якого XSS - це впровадження JavaScript в кишочки вашого порталу і виконання їх на стороні вашого браузера або браузера-жертви.
Працює це досить просто. Браузер сприймає будь-який код, який ми передаємо та обробляємо на веб-сервері, як набір html-форм JavaScript та CSS.При впровадженні XSS у ваш ресурс браузер починає обробляти його як легітимний код, який потрібно виконати. Мета будь-якого девопса та фахівця з кібербезпеки - мінімізувати ризик виконання довільного коду, який передається у форми на ваших сайтах, порталах та ресурсах.
Впровадження XSS
Є два види XSS: перший не потребує взаємодії з користувачем, а другий – так. Взаємодія з користувачем може вважатися елементарне наведення курсору на XSS. Один легкий рух – і XSS вже буде виконано. Тут варто ввести два важливі визначення, які нам знадобляться, щоб розібратися, що таке XSS:
- XSS-вектор це механізм, який ми впроваджуємо в портал, сайт або ресурс. Це набір html-коду та JavaScript.
- XSS-контент - Це місце, куди ми впроваджуємо XSS-вектор. Форма чи змінні, які ми намагаємось замінити на порталі жертви.
Експлуатувати XSS можна скрізь, де користувач може ввести свій текст — будь-яка форма, пошуковий запит і звернення до служби підтримки. Хороший приклад множинних зломів опенсорсних CMS навів в одній зі своїх доповідей гуру XSS Ігор Саксаковський (@psihoz26):
Звучить, мабуть, дуже страшно. Але погляньмо на ті приклади, які підготував для вас я. Приклад елементарного чатика:
Тут ми бачимо, як користувач звертається на підтримку. Він надсилає посилання на якусь сторінку і каже, що там неможливо, наприклад, відкрити певну вкладку. Внутрішній парсер форми зворотного зв'язку обробляє нашу сторінку як href-посилання. Ось приклад, як це має відображатися в html-коді нашого чату:
Тут зловмисник розуміє, як парсер html-запитів та розбір типів протоколів існують у чаті.Далі він відправляє свій email та просить зв'язатися з ним за вказаною адресою. Обробка цього повідомлення відбувається наступним чином: додається "mailto", а html-форма виглядає як "a href=mailto" плюс адресу тієї скриньки, яку зловмисник направив у чат. У цю форму можна відправити і XSS, яка легко розпариться, а коли співробітник техподу перейде куди треба, зловмисник отримає керування браузером спеціаліста технічної підтримки.
Захищаємось
Існує кілька методів захисту від злому через XSS. Один із них — формування content security policy, яка забороняє на порталі міжсайтовий скриптинг та завантаження картинок, додаткового коду, html-форм та всього іншого. Це дозволить мінімізувати ризик використання XSS. Ще один метод захисту від XSS - це використання фреймів, які тегуються для форм зворотного зв'язку та того, куди саме користувачі вводять дані. Наприклад, контроль вхідних параметрів та контроль цих полів з додатковими методами.
З погляду розробки необхідно завжди контролювати форми, які заповнюють користувачі, повністю екранувати їх, здійснювати парсинг та аналіз всього, що вводиться користувачами у форми. Ще один механізм боротьби з XSS, який використовують девопси та інженери з кібербезпеки - це WAF, web application firewall. Але, одразу хочу сказати, WAF – це не ультрасупермегапілюля, яка вирішить вашу проблему. Цей механізм покликаний захистити ті форми, які ви свідомо завели у WAF і змогли описати, що можна робити у цій формі, а що не можна.
У наступній статті планую розповісти про SQL-injection та інші популярні інструменти та способи кіберпроникнення зі зломом. Stay tuned!
Що таке XSS-уразливість і як тестувальнику не пропустити її
Привіт колеги. Мене звуть Віталій Котов. На моє спостереження досить багато тестувальників коли-небудь чули таке поняття, як XSS-вразливість. Але мало хто може просто і на пальцях розповісти на співбесіді про неї. Або ефективно перевірити веб-сайт на наявність цієї вразливості. Давайте разом розберемося з цим докладніше і спробуємо самі знайти нескладну XSS-вразливість на демо-сторінці, яку я спеціально підготував до цієї статті.
Якщо ви гуру тестування безпеки і на раз-два берете участь у баунті-програмах великих IT-компаній, а кількість знайдених вами XSS обчислюється десятками або навіть сотнями - можна сміливо проходити повз цю статтю. Якщо ж ви новачок у темі і тільки починаєте цікавитися пошуком уразливостей – ласкаво просимо під кат.
Визначення
XSS (англ. Cross-Site Scripting - "міжсайтовий скриптинг") - досить поширена вразливість, яку можна виявити на безлічі веб-додатків. Її суть досить проста, зловмиснику вдається впровадити на сторінку JavaScript-код, який не було передбачено розробниками. Цей код буде виконуватися щоразу, коли жертви (звичайні користувачі) заходитимуть на сторінку програми, куди цей код було додано. А далі є кілька сценаріїв розвитку.
Перший: зловмиснику вдасться отримати авторизаційні дані користувача та увійти до його облікового запису.
Друге: зловмисник може непомітно для жертви перенаправити його на іншу сторінку-клон. Ця сторінка може виглядати цілком ідентично тій, де користувач розраховував опинитися. Але належатиме вона зловмиснику.Якщо користувач не помітить заміни і на цій сторінці введе якісь sensitive data, тобто особисті дані, вони виявляться у зловмисника.
Третій ... та загалом багато чого ще можна придумати. Майже все, що може JavaScript стає доступним для зловмисника. Трохи нижче ми розглянемо докладніше один із таких прикладів. А поки давайте спробуємо трохи докладніше обговорити, як саме влаштовано вразливість. І чому зловмиснику вдається впровадити свій код у чужу програму без доступу до його вихідців.
Невелике попередження. Вся інформація далі представлена виключно з інформаційною метою. Тестувальник повинен вміти перевіряти свій веб-додаток на вразливості. Однак, використання XSS-уразливостей на чужих ресурсах є незаконним.
Якщо говорити про чинне російське законодавство, коли дослідник тестує чужий продукт на предмет вразливостей або проникає в чужу мережу без відома та згоди власника, його дії можуть бути розцінені як неправомірні.
Як влаштована вразливість?
Насамперед, як саме вдається впровадити на сторінку JavaScript-код, якого там раніше не було? І як виходить розповсюдити цей код серед інших користувачів?
Наприклад, можна додати JavaScript-код у поле введення, текст якого зберігається і надалі відображається на сторінці для всіх користувачів. Це може бути поле для введення інформації про себе на сторінці профілю соціальної мережі або коментарі на форумі.
Зловмисник вводить текст (і за один шкідливий код), який зберігається на сторінці. Коли інші користувачі зайдуть на цю сторінку, разом з текстом вони завантажать і JavaScript-код зловмисника. Саме на момент завантаження цей код відпрацює.Звичайно, вразливість спрацює, тільки якщо текст при збереженні не буде захищений. Про те, як це зробити, і чому розробники іноді забувають про це, поговоримо трохи згодом.
Це лише найпростіший і очевидніший приклад того, де може бути захована вразливість. Цікавіший приклад ми з вами трохи нижче розглянемо на спеціально підготовленій демо-сторінці.
А поки що давайте рухатися далі.
Чому такі помилки часто трапляються на веб-проектах?
Суть у тому, що браузер не може самостійно відрізнити звичайний текст від тексту CSS, HTML або JavaScript-кодом. Він намагатиметься обробляти все, що знаходиться між тегами , як JavaScript-код. Все, що знаходиться між тегами, вважати CSS. І все, що схоже на тег, вважати HTML-кодом.
Якщо розробник хоче, щоб якийсь текст виглядав лише як код, але таким не був (тобто не оброблявся браузером, а виводився як є), цей текст треба спеціально обробити перш, ніж віддати його браузеру. Така обробка називається "екрануванням".
У процесі екранування тексту у цьому тексті все спец. символи замінюються їх "аналогами", і браузер вже знає, напевно, що це просто текст. Найважливіше обробляти той текст, який надходить від користувача, тому що будь-який користувач може виявитися зловмисником і разом з текстом надіслати якийсь код. На жаль, іноді розробники забувають про екранування в тих чи інших місцях веб-програми, і текст виводиться без будь-якої обробки. Причин цього може бути кілька.
Наприклад, не завжди програміст тримає в голові всі місця, де текст, заданий користувачем, потрапляє на сторінку.Більше того, іноді різні частини сайту можуть створюватися у різний час та/або різними людьми. І тут ймовірність помилки зростає.
Ще причина може бути в тому, що вразливість не в коді самого розробника, а в коді бібліотеки, яку він використовує. Зазвичай, це якісь готові фреймворки для створення веб-сервісів. У такому разі розробник, звичайно, може навіть не підозрювати те, що підключаючи до проекту цей фреймворк, він автоматично підключає до нього вже готову вразливість.
Такий ризик є завжди. Все ж таки писати додаток повністю з нуля, не використовуючи взагалі ніяких бібліотек, в наш час довго і дорого. Не кожна компанія може дозволити собі розробку такого рівня.
І тут вся надія на тестувальників.
Чим небезпечна XSS-уразливість?
Давайте ще раз, детальніше, поговоримо про небезпеку XSS-уразливості. Сама по собі вразливість не є небезпечною. Небезпечною вона стає тоді, коли її знаходить зловмисник і починає її використовувати у своїх цілях. Використання вразливості називається "вектором атаки". У випадку XSS векторів атаки досить багато.
Найпростіший приклад - крадіжка авторизаційних cookie користувачів веб-програми. Найчастіше сайт, на якому є авторизація, відрізняє авторизованого користувача за так званою сесійною cookie. Якщо її немає, користувач не авторизований. А якщо вона є, то за значенням цієї кукі сервер може відрізнити одного користувача від іншого.
Усі cookie зберігаються на комп'ютері користувачів. Якщо я авторизуюсь своїм користувачем, я бачитиму своє значення cookie. А значення чужого просто так дізнатися не зможу.
Те саме стосується JavaScript-коду, який виконується у браузері користувача.Цей JavaScript-код бачитиме значення cookie того користувача, у браузері якого він виконується і лише його.
Тепер припустимо, що зловмиснику вдасться впровадити JavaScript-код на сторінку веб-програми. У будь-якого користувача, який тепер зайде на цю сторінку, буде виконуватись у браузері JavaScript-код. Він читатиме значення cookie цього користувача (тепер уже жертви). Залишилося лише передати це значення зловмисникові — і справа зроблена. Але як передати значення, адже шкідливий код виконується у браузері жертви?
Все досить просто. Цей JavaScript-код може створити AJAX-запит на віддалений сервер. Наприклад, на ось таку URL: www.zloy-site.ru/stolen=
Домен zloy-site належить зловмиснику з нашого прикладу. Всі запити, які надходять на цей домен, записуються до бази даних. Подивившись на параметри URL, зловмисник дізнається значення cookie жертв і зможе їх використовувати, щоб потрапити до їх облікових записів.
Як ми обговорили вище, це не єдине, ніж небезпечна XSS-уразливість. Так що заради безпеки та захисту своїх користувачів необхідно вміти шукати і закривати подібні вразливості на ваших проектах.
Де шукати XSS? Як із нею боротися? Демо-сторінка з прикладом
В першу чергу варто перевіряти на XSS-уразливості місця на сайті, в яких у звичайного користувача є можливість вплинути на контент. Якщо він може додати до певного місця певний текст, він зможе спробувати додати і JavaScript-код.
Давайте розглянемо це на конкретному прикладі. Я підготував дуже просту пісочницю, де сховалася XSS-уразливість. Пропоную спробувати знайти її разом.
Спочатку подивимося, як влаштована сторінка. Це насправді дуже простий каталог книг, в якому є пошук.Якщо ввести в запиті “Рей Бредбері”, ми побачимо всі книги, які є в цьому каталозі цього автора.
Уважний користувач уже помітив, що текст, який ми вводили в поле пошуку, відразу опинився в URL. Нам цей момент ще стане в нагоді.
А поки давайте спробуємо вставити якусь нісенітницю в поле пошуку: "fwefewf".
Ми побачимо, що в цьому випадку нічого знайти на сторінці не вдалося. А текст запиту повторився у тексті помилки:
Отже, ми з вами виявили місце, де з'являється текст, який ми вводимо. Отже, це і є потенційним місцем для XSS-уразливості. Спробуємо вставити найпопулярніший JavaScript-код для перевірки, чи є там вразливість.
У випадку, якщо сторінка є вразливою, після введення цього коду на сторінці з'явиться таке віконце:
Воно й означатиме, що наш JavaScript-код здійснився, і ми знайшли XSS-вразливість.
Отже, вводимо код і бачимо таке попередження:
Форма не дозволяє нам здійснити пошук за таким значенням, оскільки форма валідується і хоче працювати лише з літерами та цифрами. На перший погляд здається, що розробник все врахував і захистив сторінку XSS, але це не зовсім так.
Пам'ятайте, що трохи вище ми з вами помітили, що текст, який ми вводимо в поле пошуку, відображається в URL у так званому GET-параметрі? Ім'я цього параметра “q”, а значення – те, що ми вводимо у полі пошуку. Це зроблено для того, щоб можна було скопіювати URL разом з цим рядком пошуку і наступного разу відкрити сторінку відразу з потрібними авторами.
Наприклад, ось така URL відкриє сторінку відразу тільки з книгами Рея Бредбері: playground.learnqa.ru/demo/xss?q=Рей+Бредбері
На відміну від форми, валідацію URL розробник зробити не міг - будь-який користувач у своєму браузері може ввести будь-яку URL, яку захоче, в тому числі і з будь-яким значенням GET-параметра. Завдання розробника в цьому випадку - не забути врахувати всі варіанти та написати правильний обробник значення GET-параметра.
Перевіримо, чи не забув наш розробник все врахувати тут. Спробуємо в GET-параметр "q" підставити цей JavaScript-код: https://playground.learnqa.ru/demo/xss?q=
Перейшовши цією URL ми бачимо, що на сторінці з'явилося віконце зі значенням 123. Але чому?
Все досить просто. Пам'ятаєте, коли сайт не може знайти потрібні книги за заданим пошуковим запитом, чи текст цього пошукового запиту виводить у тексті помилку? Мовляв, не знайшли нічого на запит “бла-бла”. Ось натомість “бла-бла” у нас тепер JavaScript-код з алертом. Розробник написав валідацію поля введення та вирішив, що так він захистив сайт від того, щоб JavaScript міг опинитися у пошуковому запиті. І не став екранувати текст помилки. Нам вдалося обійти валідацію через URL, змінивши там значення пошукового запиту.
Заради інтересу тепер можемо вивести значення нашої сесійної cookie, для цього замість в URL треба підставити інший код:
З цим я вже надам погратись вам самостійно. :)
Знайшовши помилку, варто звернутися до розробників – вони її виправлять.
Способів закрити помилку чимало. Екранувати текст – не єдиний із них. Ще можна заборонити JavaScript бачити деякі cookie. Для цього cookie має спеціальний параметр "http only".Якщо він виставлений у TRUE, JavaScript ніяк не зможе дізнатися, що така cookie взагалі виставлена і не зможе її прочитати та передати зловмиснику навіть у тому випадку, якщо йому вдасться знайти XSS на вашому проекті.
Все це лише малий, далеко не повний список маніпуляцій, що запобігає XSS-уразливості.
Якщо Вам цікаво знати більше про тестування безпеки, хочеться краще розібратися у пристрої клієнт-серверної архітектури, зрозуміти та відточити найефективніші способи пошуку вразливостей на цьому веб-додатку, приходьте на мій курс “Тестування безпеки”.
На вас чекає тільки корисна і потрібна теорія без води і велика кількість практичних прикладів і завдань. , Facebook, Twitter і так далі.