Збережений XSS
Підкинуто один раз — і воно виконується для кожного наступного відвідувача.
Що таке Збережений XSS?
Збережений міжсайтовий скриптинг достатньо підкинути один раз. Кожен користувач, який завантажує сторінку згодом, виконує скрипт зловмисника у своїй власній сесії, без посилання, на яке треба натиснути, і без нічого, що привернуло б увагу. Ви вставите в гостьову книгу тег зображення з обробником onerror , потім самі завантажите сторінку й побачите, як виводиться ваш сесійний cookie. Виправлення екранує на межі рендерингу, тож той самий пейлоад, що досі лежить у базі даних, відображається як текст. Збережене значення не потрібно очищати, щоб виправлення спрацювало.
Що ви дізнаєтесь у Збережений XSS
- Відрізняйте збережений XSS від відбитого: модель загроз змінює тривале зберігання пейлоада на сервері
- Поясніть, чому тег <img src=x onerror=alert(...)> спрацьовує, навіть коли в пейлоаді немає тега <script>
- Визначайте екранування HTML на межі рендерингу як правильний основний захист і пояснюйте, чому недостатньо ні списків заборонених на рівні введення, ні підходів, що спираються лише на CSP
- Читайте функцію рендерингу на Node.js достатньо добре, щоб помітити помилку з вклеюванням у HTML і розпізнати рядок, куди треба вставити екранування
- Розумійте, що збережене значення може лишатися без змін, щойно код рендерингу екранує вивід правильно: базу даних не потрібно санітизувати, щоб виправлення спрацювало
Збережений XSS — Кроки навчання
-
Знайдіть форум спільноти
Сьогодні Боб націлюється на Signal Coast: на форумі спільноти цієї компанії будь-який учасник може опублікувати коротку публічну примітку, яку читають усі інші. Він входить в одноразовий обліковий запис і відкриває гостьову книгу форуму, щоб побачити, як вона обробляє те, що пишуть люди.
-
Примітки відображаються так, як написані
Гостьова книга обіцяє те, чого більшість сайтів ретельно уникає: вона відображає кожну примітку точно так, як її написано, разом з HTML. Поле, яке перетворює все, що ви введете, на справжню розмітку, — саме те, що Боб сподівався знайти.
-
Опублікуйте звичайну примітку
Спершу Боб поводиться, як будь-який інший учасник, і публікує звичайну примітку, щоб побачити, як гостьова книга її обробляє. Примітка з'являється на стіні точно так, як її написано: простий текст, нічого незвичного. Функція працює так, як задумано.
-
Перейдіть до скрипта
Поле відображає HTML, тож Боб підсовує йому скрипт замість речення. Його пробний пейлоад — тег зображення з адресою src, за якою нічого не завантажується, і обробником onerror , що читає сесійний cookie відвідувача. Зображення не завантажується, обробник виконується, і браузер показує спливне вікно з тим, що вказано в примітці. Тут воно виводить дані сесії — доказ того, що примітка може виконувати код у сесії відвідувача.
-
Примітка виконується в сесії
Ось воно: примітка виконалася сама й показала у спливному вікні активний сесійний cookie відвідувача, без жодного натиснутого посилання й відкритого файлу. Сьогодні це нешкідливий вивід, завтра — непомітне надсилання на сервер Боба. Примітка може прочитати цей cookie лише тому, що в сесійного cookie немає атрибута HttpOnly ; якби атрибут був, скрипт усе одно міг би діяти від імені відвідувача, але не міг би прочитати cookie. Боб довів, що стіна виконує все, що містить примітка. Тепер він створює справжню зброю.
-
Підкиньте підроблену форму входу
Боб замінює пробний пейлоад приміткою, яка перетворює сторінку на вікно входу із написом Session expired («Сесія закінчилася»), а її обробник надсилає все, що введуть, на його власний сервер. Для кожного учасника, який завантажує стіну, це виглядає так, ніби форум просто попросив увійти знову. Облікові дані потрапляють одразу до Боба.
-
Пастку заряджено
Підроблена форма входу тепер — найновіша примітка на стіні, і виглядає точно як прохання форуму увійти знову. Її обробник надсилає все, що в неї введуть, просто на сервер Боба. Він підкинув її один раз; кожен учасник, який їй повірить і ввійде, віддає свій пароль.
-
Аліса відкриває стіну
Ви відповідаєте за код рендерингу гостьової книги. Сьогодні вранці ви дивитеся, що нового в спільноті, як і будь-який інший адміністратор на початку дня: відкриваєте браузер і переходите на стіну. Ви не натискали на посилання й нічого не запускали. Ви лише завантажуєте сторінку, якою керуєте.
-
Спрацьовує під час завантаження
Сторінка щойно завершила завантаження, а спливне вікно вже виводить ваш сесійний cookie. Ви нічого не вводили й нічого не натискали. Одна з приміток Боба виконалася в ту мить, коли стіна відобразилася, у вашій адміністраторській сесії. У його бойовій версії цей самий обробник надіслав би вашу сесію просто йому.
-
А нижче — підроблена форма входу
Прокрутіть стіну, і нижче є друга підкинута примітка: вікно входу із написом Session expired («Сесія закінчилася»), яке схоже на власне вікно форуму. Будь-який учасник, який довіряє цьому вікну й входить, віддає свій пароль зловмиснику. Це збережені примітки, які виконує браузер кожного відвідувача. Як інженерка, що відповідає за цю сторінку, ви знаєте: виправлення — в коді рендерингу.
Охоплення стандартів безпеки
OWASP Top 10
- A05:2025 Injection
- A03:2021 Injection
CWE
- CWE-79 Improper Neutralization of Input During Web Page Generation
CIS Controls
- CIS 16 Application Software Security
NIST CSF
- PR.AT-02 Individuals in specialized roles are provided with awareness and training so that they possess the knowledge and skills to perform relevant tasks with cybersecurity risks in mind
- PR.PS Platform Security