[Из песочницы] Безопасное использование языка Go в веб-программировании
Язык программирования Go является довольно молодым языком программирования — разработан компанией Google в 2007 и был официально представлен в 2009 году. Программистам очень понравился данный язык: компилируемый, многопоточный, структурированный и императивный. Его используют такие компании как Microsoft, GitHub, Cloudflare, Heroku, Вконтакте, Mail.Ru. Сразу после релиза языка появились и продолжают создаваться библиотеки и инструменты, помогающие в разработке на Go. Среди этих инструментов также появились и библиотеки для защиты web-приложений. Многие библиотеки, написанные как отдельными разработчиками, так и встроены в стандартный набор библиотек.
Приведем наиболее типичные способы атак на сайты и основные способы их избежать или хотя бы минимизировать данные угрозы:
- Предсказуемое значение идентификатора сессии (Credential/Session Prediction).
- Межсайтовой подделкой запроса (CSRF).
- Межсайтовое выполнение сценариев (Cross-site Scripting, XSS).
- Clickjacking.
- Внедрение операторов SQL (SQL Injection).
Обзор инструментов для защиты от подобных типов атак я и хотел бы сделать.Защищаем правильно сессию и cookie
Сессии — явная цель для хакера, поскольку с их помощью можно получить доступ к веб-серверу без необходимости аутентификации. И получается, что не грамотная реализация сессий может подставить под угрозу весь ваш сервис. Если вы решили использовать на своем веб-сервисе сессии то тут Вам пригодится библиотека gorilla. Сессия Gorilla«s помогает справиться с хранением ваших cookie на сервере, а также просто передавать уникальные токены. Помимо этого, может быть полезна библиотека SecureCookie. Такие безопасные cookies не могут быть подделаны, потому что их значения проверяются с помощью HMAC.
В последнее время также очень часто используется технология JSON WebTokens. В этом вам поможет библиотека jwt-go. Подробнее о JWT in Go можно почитать здесь.CSRF
Теперь рассмотрим борьбу с межсайтовой подделкой запроса или CSRF атаками на сайт. CSRF атака проводится на авторизованного пользователя веб-приложения с помощью уязвимости в данном приложении. Например, злоумышленник может вынудить (с помощью послания письма ссылкой) перейти пользователя на специально подготовленный сайт, осуществляющий некую вредоносную операцию (например, перевод денег на счёт злоумышленника или смену пароля). Для осуществления данной атаки жертва должна быть аутентифицированана на том сервере, куда отправляется запрос. Для предотвращения CSRF атаки — сгенерировать специальный секретный ключ и сохранить в сессию пользователя и на основе этого секретного ключа сформировать по определенному правилу токен. Токен делается так, чтобы, с одной стороны, он был отличен от ключа (в частности, может быть много токенов для одного ключа), с другой — чтобы было легко проверить по токену, сгенерирован ли он на основе данного ключа или нет. В 2015 году исследователь Михаил Фирстов наткнулся на подобную уязвимость на сайте Yota. Недавно нахождение csrf уязвимости на многих сервисах Microsoft принесло 13 000 $ одному британскому исследователю. Это говорит о том, что разработчики до сих пор плохо решают данную проблему и не всегда грамотно.
С этой задачей в Go очень хорошо справляется библиотека NoSurf. Для примера работы библиотеки приведем код программы.
Как видите, на основе контекста запроса формируется токен, который впоследствии вставляется в необходимые нам поля и заголовки.
Исходный код html документа:
При попытке изменить токен в форме запроса сервер отдает ошибку номер 400 BadRequest.
Также я нашел подобную библиотеку GojiCSRF. Она работает из коробки сразу с SecureCookie и генерирует токены длиной 32 байта. Работает только с запросами, которые могут модифицировать данные и не работает с безопасными http методами (GET, HEAD, OPTIONS, TRACE).
Почти то же самое, но только в упрощенном режиме, позволяет генерировать стандартная библиотека Go XSRFtoken. Она имеет всего две функции — это funcGenerate и funcValid, а также возможность задать время жизни токена.
Атака XSS или межсайтинговый скриптинг — это тип атаки на веб-систему, заключающийся во внедрении в выдаваемую веб-системой страницу вредоносного кода. Самый известный пример — это угон пользовательских cookies злоумышленником.
На этот случай написано неплохие, на мой взгляд, библиотеки с созвучными названиями. Это blackfriday и bluemonday. Библиотеки быстро настраиваются и удобно запускаются. Могут работать как вместе, так и раздельно. Привел пример кода простой программы, которая получает строку с консоли, экранирует определенные символы, а некоторые просто затирает. Я взял несколько примеров JS скриптов, которые можно использовать при реализации атаки. Пример работы программы приведен на скриншоте ниже, отфильтрованная последовательность выводится между тегами
Код программы:
Вывод результата работы двух библиотек совместно:
А если вы вдруг по какому-то желанию не хотите использовать сторонние библиотеки, то в Go из коробки есть пара полезных функций содержащихся в пакетe html/template:
•funcHTMLEscape (w io.Writer, b []byte) отправляет в w версию b с заменой потенциально опасных символов на их escape-последовательности.
•funcHTMLEscapeString (s string) string возвращает версию s с заменой потенциально опасных символов на их escape-последовательности.
•funcHTMLEscaper (args …interface{}) string формирует строку из множества аргументов с заменой потенциально опасных символов на escape-последовательности.
Также ваши входные параметры сможет легко «очистить» Sanitizing. На гитхабе этой библиотеки имеется довольно полный тест с входными данными из того же OWASP«a.
ClickjackingСуществует также атака, известная как Clickjacking. Атака «кликджекинг» (англ. Clickjacking) позволяет хакеру выполнить клик на сайте-жертве «от имени посетителя», также известна как подмена пользовательского интерфейса. Тем самым хакер может придумать различные сценарии и, например, перевести с вашего мобильного банка деньги себе на счет всего за пару кликов. Как ни странно, но подобные уязвимости до сих пор находят даже в системах дистанционного банковского обслуживания DBO, хотя, казалось бы, банковские системы должны быть защищены гораздо лучше, чем обычные веб-приложения.
Также для защиты рекомендуется к каждому ответу вашего сервера прикреплять заголовок X-Frame-Options. Сейчас все современные браузеры поддерживают заголовок X-Frame-Options. Он разрешает или запрещает отображение страницы, если она открыта во фрейме. У заголовка может быть три значения:
•SAMEORIGIN — Рендеринг документа, при открытии во фрейме, производится только в том случае, когда верхний (top) документ — с того же домена.
•DENY — Рендеринг документа внутри фрейма запрещён.
•ALLOW-FROM domain — Разрешает рендеринг, если внешний документ с данного домена (не поддерживается в Safari, Firefox).
Пример реализации добавления заголовок ответа в Go.
Secure — небольшая прослойка для удобной настройки безопасных параметров вашего сервиса. Secure умеет работать как с большим количеством фреймворков, так и со стандартным пакетом net/http.
SQL-injectionSQl-injection — один из распространённых способов взлома сайтов и программ, работающих с базами данных, основанный на внедрении в запрос произвольного SQL-кода.
В Go можно использовать параметризованные запросы или как еще называют подготовленные выражения. которые помогают избежать некоторых проблем с SQL-injection.
Также можно использую фильтрацию по регулярному выражению. В данном случае используем рабочую ссылку, содержащую только цифры в id и uid. Пример того как в Go это можно сделать красиво.
Используем экранирование определенных символов. Например, одинарную кавычку.
Вывод программы. Видно, что символ »« заменяется на последовательность символов »'».
Но также не стоит забывать, что при реализации sql-injection у нас не обязательно должна быть кавычка. Переменная vuln1 как раз содержит данную строку и, проходя через функцию EscapeString, совсем не изменяется.
SafeSQL
SafeSQL — это статический анализатор кода для Go, который позволяет находить SQL injections.
ЗаключениеНесмотря на то, что Go довольно новый язык программирования, комьюнити очень быстро разрастается и реализует базовые решения, которые встречаются почти в каждом проекте. В том числе и решения, основанные на безопасности веб-приложения. В статье были рассмотрены способы избежания SQL-injection, CSRF, XSS, Clickjacking. Рассмотренные способы не являются панацеей для полной безопасности веб-приложения. Но помогают решить большинство фундаментальных проблем, связанных с информационной безопасностью.
Использованная литература
https://learn.javascript.ru/csrf
https://nvisium.com/blog/2014/11/26/developing-secure-applications-with/
https://astaxie.gitbooks.io/build-web-application-with-golang/content/en/09.1.html
https://learn.javascript.ru/clickjacking
http://0xdabbad00.com/2015/04/18/go_code_auditing/
http://dghubble.com/blog/posts/json-web-tokens-and-go/