Если вы пишете на JavaScript, то наверняка слышали, что безопасность — это важно. Но что это значит на практике? В этой статье мы разберем, как защитить ваше приложение от типичных атак, не углубляясь в дебри криптографии. Вы узнаете, какие ошибки чаще всего допускают разработчики, и как их избежать. Будет много кода, примеров и немного житейских аналогий.
Почему JavaScript — это лакомый кусок для хакеров
JavaScript — это язык, который работает в браузере у каждого пользователя. Он может обращаться к DOM, отправлять запросы на сервер, хранить данные в localStorage. Если неаккуратно написать код, злоумышленник может перехватить управление. Например, вставить вредоносный скрипт через поле ввода, украсть куки или подменить данные.
Представьте, что ваше приложение — это дом. JavaScript — это окна и двери. Если вы оставите их открытыми, любой прохожий сможет зайти и что-то украсть. Наша задача — закрыть все щели и поставить сигнализацию.
Основные угрозы и как от них защититься
Чаще всего разработчики сталкиваются с такими проблемами:
- XSS (межсайтовый скриптинг) — когда злоумышленник внедряет свой скрипт в страницу.
- CSRF (подделка межсайтовых запросов) — когда от имени пользователя отправляются нежелательные запросы.
- Утечка данных — когда чувствительная информация попадает в неправильные руки.
- Инъекции — когда код выполняется непреднамеренно.
Давайте разберем каждую угрозу и способы защиты.
Защита от XSS
XSS возникает, когда вы вставляете пользовательский ввод прямо в HTML без обработки. Например:
// Плохо: вставляем ввод напрямую
const userInput = '
';
document.getElementById('output').innerHTML = userInput;
В этом случае браузер выполнит код внутри тега img. Чтобы избежать этого, нужно экранировать ввод или использовать textContent вместо innerHTML:
// Хорошо: используем textContent
document.getElementById('output').textContent = userInput;
Если вам все же нужно вставить HTML, используйте библиотеки для санитизации, например, DOMPurify.
Защита от CSRF
CSRF — это когда злоумышленник отправляет запрос от имени пользователя, используя его куки. Например, если пользователь залогинен в банке, а на другом сайте есть форма, которая отправляет запрос на перевод денег. Чтобы защититься, используйте CSRF-токены.
Токен — это случайная строка, которую сервер отправляет клиенту и проверяет при каждом запросе. Вот как это может выглядеть:
// На клиенте отправляем токен с каждым запросом
fetch('/transfer', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'CSRF-Token': csrfToken
},
body: JSON.stringify({ amount: 100 })
});
Сервер должен проверить токен и отклонить запрос, если он не совпадает.
Защита от утечек данных
Часто данные утекают из-за того, что мы храним их не там, где нужно. Например, не стоит хранить пароли в localStorage. Для этих целей есть специальные механизмы — куки с флагом HttpOnly, которые недоступны для JavaScript. Это значит, что даже если злоумышленник внедрит скрипт, он не сможет прочитать куки.
Также следует избегать передачи чувствительных данных в URL-параметрах. Лучше использовать POST-запросы.
Инъекции
Инъекции в JavaScript обычно связаны с eval() или new Function(). Эти функции выполняют строки как код, и если строка содержит пользовательский ввод, это опасно.
// Плохо: используем eval
const userCode = 'alert(1)';
eval(userCode);
Вместо этого используйте безопасные методы, например, JSON.parse для разбора данных.
Безопасность на уровне зависимостей
Вы используете npm-пакеты? Тогда вы знаете, что они могут содержать уязвимости. Проверяйте свои зависимости с помощью npm audit:
npm audit fix
Это покажет, какие пакеты имеют известные проблемы, и предложит обновления.
| Инструмент | Назначение |
|---|---|
| npm audit | Проверка уязвимостей в зависимостях |
| Snyk | Мониторинг безопасности в реальном времени |
| OWASP Dependency-Check | Поиск известных CVE в библиотеках |
Практические советы по написанию безопасного кода
- Используйте строгий режим ('use strict') — он предотвращает некоторые ошибки.
- Обрабатывайте ошибки с помощью try/catch, но не выводите детали в консоль.
- Не используйте глобальные переменные — они могут быть переопределены.
- Проверяйте ввод на стороне сервера, а не только на клиенте.
- Используйте HTTPS, чтобы шифровать данные при передаче.
Что в итоге
Безопасность — это не одноразовое действие, а постоянный процесс. Начните с простых шагов: экранируйте ввод, используйте токены, проверяйте зависимости. Это уже значительно снизит риски.
Помните: ваш код — это крепость. Чем больше слоев защиты, тем сложнее злоумышленнику проникнуть внутрь. И не забывайте про обновления — они закрывают известные дыры.
Если вы хотите углубиться в тему, изучите OWASP Top 10 — это список самых критичных уязвимостей веб-приложений. Но даже без этого вы уже знаете достаточно, чтобы писать безопасный код на JavaScript.



