Проблеми безпеки CSS

6 хв. читання

Пару тижнів тому з'явилось декілька новин про вбудований в CSS 'keylogger'.

І деякі люди неодмінно стали просити розробників браузерів залатати діру, проте деякі поцікавились проблемою дещо глибше і дізнались, що вона торкнулась лише сайтів побудованих на фреймворках подібних до React. Але реальна проблема – думка, що сторонній контент не може нести у собі загрозу.

Сторонні зображення

<img src="https://example.com/kitten.jpg">

Якщо я вирішив під'єднати до сторінки це зображення, то це означає, що я довіряю example.com. Вони можуть легко спаплюжити цю довіру, просто видаливши ресурс, або повернувши мені 404 помилку, і тим самим зламають мій сайт. Або ж вони можуть підмінити фотографію чимось менш приємним.

У будь-якому випадку, шкода від зображення не виходить за межі елементу або контейнеру. Я можу спробувати пояснити користувачам, що цей контент надається стороннім ресурсом example.com, і якщо, щось пішло не так, це їх провина. Мені залишиться лише сподіватись, що вони мені довіряться. Але, така ситуація, безумовно не зможе зачепити, як приклад, поля вводу паролів.

Сторонні скрипти

<script src="https://example.com/script.js"></script>

У порівнянні з зображеннями, сторонні скрипти мають набагато більше контролю над сторінкою. Якщо я вирішу під'єднати скрипт з прикладу, то я надаю example.com повну владу над моїм сайтом.

Вони можуть:

  • Читати або змінювати контент.
  • Відстежувати дії користувачів.
  • Виконувати ресурсомісткі обчислення (майнери, тощо).
  • Здійснювати запити до мого джерела, використовуючи кукі користувачів, і пересилати відповіді.
  • Читати або змінювати дані джерела.
  • ...а також багато іншого, що тільки забажають.

Дані джерела можуть бути досить важливими, тому, якщо скрипт втрутиться в індексовану базу даних або кеш API пам'яті, то атака може розповсюдитись на весь сервер, навіть після видалення скрипту.

Якщо ви під'єднуєте до сайту скрипт зі стороннього джерела, ви маєте бути абсолютно впевнені у тому, що ви робите, і довіряти цьому самому джерелу.

Якщо ж ви потрапили під атаку скрипта, вам слід знищити дані сайту за допомогою заголовку Clear-Site-Data.

Сторонній CSS

<link rel="stylesheet" href="https://example.com/style.css">

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

  • Видаляти, додавати та модифікувати контент сторінки
  • Робити запит заснований на контенті сторінки
  • Реагувати на більшість дій користувачів

CSS не може модифікувати дані сервера, тому ви не зможете побудувати майнер на CSS, проте він досі може завдати достатньо шкоди для того, щоб ви звернули на нього увагу.

keylogger

Почнемо з найвідомішого:

input[type="password"][value$="p"] {
  background: url('/password?p');
}

Приклад вище, буде здійснювати запит до /password?p, якщо введене значення value атрибуту закінчується на p. Зробіть те ж саме з усіма літерами алфавіту, і ви зможете отримати багато приватних даних.

Браузер, за замовчуванням, не зберігає дані введені користувачем в атрибуті value, тож такий спосіб атаки базується на синхронізації цих значень, саме так відбувається у React.

Щоб імітувати таку поведінку, React може пошукати інший спосіб синхронізації полів паролів, або браузери можуть обмежити селектори, що перевіряють значення атрибутів полів вводу паролів. Але це може створити хибне відчуття захищеності. Так можна вирішити проблему тільки для одного конкретного випадку, проте не усуне всіх можливих проблем.

Якщо React почне використовувати атрибут data-value, то діру буде закрито. Якщо сайт змінить ввід даних на type="text", і користувачі почнуть бачити, що саме вони вводять у поле паролю, проблему буде закрито. Якщо сайт створить власний <better-password-input> і буде отримувати значення у якості атрибута, то проблему буде усунено.

Проте існує безліч інших атак, які використовують CSS:

Контент, що зникає

body {
  display: none;
}

html::after {
  content: 'HTTP 500 Server Error';
}

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

Більш витончені способи могли видаляти кнопку "Придбати", або міняти місцями абзаци у тексті.

Додання контенту

.price-value::before {
  content: '1';
}

І ваші ціни виросли.

Переміщення контенту

.delete-everything-button {
  opacity: 0;
  position: absolute;
  top: 500px;
  left: 300px;
}

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

На щастя, якщо кнопка робить щось дійсно важливе, то зазвичай, спершу сайти виводять діалогове вікно підтвердження. Проте, це не проблема, вам лише необхідно використати ще декілька CSS фокусів, щоб змусити користувача натиснути кнопку «Так» замість «Ні, ніколи, нізащо».

Уявіть собі, що трапиться, якщо браузери спробують усунути keylogger. Нападники зможуть просто взяти поле текстового вводу не пов'язане з паролями, наприклад строку пошуку, і розмістити її поверх вводу паролів.

Зчитування атрибутів

Це не просто паролі, про які вам слід турбуватись, взагалі ви можете мати інші приватні дані в атрибутах:

<input type="hidden" name="csrf" value="1687594325">
<img src="/avatars/samanthasmith83.jpg">
<iframe src="//cool-maps-service/show?st-pancras-london"></iframe>
<img src="/gender-icons/female.png">
<div class="banner users-birthday-today"></div>

Всі вони можуть бути знайдені CSS-селектором, а їх запити можуть бути отримані як результат.

Відстеження взаємодії

.login-button:hover {
  background: url('/login-button-hover');
}

.login-button:active {
  background: url('/login-button-active');
}

Hover і active можуть бути надіслані на сервер. Використовуючи невелику кількість CSS ви можете побудувати досить хорошу картину того, що саме користувачі роблять на сайті.

Зчитування тексту

@font-face {
  font-family: blah;
  src: url('/page-contains-q') format('woff');
  unicode-range: U+85;
}

html {
  font-family: blah, sans-serif;
}

У цьому випадку запит буде надіслано, якщо сторінка містить q. Ви можете створити багато таких для кожної літери, і відстежувати окремі елементи. Шрифти можуть бути внутрішньо пов'язані, тож ви можете почати відстежувати послідовності літер. Ви навіть можете комбінувати фокуси зі шрифтами з відстеженням прокрутки екрану, щоб ліпше розуміти що саме відбувається з контентом.

Сторонній контент може нести у собі загрозу

Це лише декілька трюків, про які я знаю, проте я впевнений, що існує набагато більше.

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

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

Також ви можете використати Subresource Integrity щоб впевнитись у тому, що контент скриптів та стилів відповідає хешу, або ж його буде відхилено.

Якщо ви цікавитесь подібними фокусами, вам слід ознайомитися з наступними посиланнями:

css
Помітили помилку? Повідомте автору, для цього достатньо виділити текст з помилкою та натиснути Ctrl+Enter
Codeguida 6.2K
Приєднався: 7 місяців тому
Коментарі (0)

    Ще немає коментарів

Щоб залишити коментар необхідно авторизуватися.

Вхід / Реєстрація