bannerbannerbanner
Безопасность веб-приложений. Исчерпывающий гид для начинающих разработчиков

Таня Янка
Безопасность веб-приложений. Исчерпывающий гид для начинающих разработчиков

Безопасность через неясность

Концепция безопасности через неясность подразумевает, что если какой-то фрагмент системы скрыт, то он находится в «большей безопасности», поскольку не попадает в поле зрения потенциальных злоумышленников. Наиболее распространенная реализация этой концепции: компании – разработчики программного обеспечения скрывают свой исходный код, а не выкладывают его в открытый доступ (с целью защиты интеллектуальной собственности и в качестве меры безопасности). Некоторые доходят до обфускации своего кода, изменяя его таким образом, чтобы его было гораздо сложнее или вообще невозможно понять тому, кто попытается провести обратную разработку продукта.

ПРИМЕЧАНИЕ. Обфускация – это усложнение чего-то для понимания или чтения. Распространенной тактикой является кодирование всего исходного кода в ASCII, Base64 или Hex, но ее довольно легко видят профессиональные реверс-инженеры. Некоторые компании дважды или трижды шифруют свой код. Другая тактика – применение операции XOR (команды ассемблера) или создание собственной схемы кодирования и добавление ее программным путем. Также можно купить продукты, выполняющие более сложную обфускацию.

Другим примером «безопасности через неясность» является использование беспроводного маршрутизатора, скрывающего имя SSID/Wi-Fi (то есть при подключении к сети необходимо вручную указать ее имя), или размещение веб-сервера без доменного имени в надежде, что никто его не найдет. Существуют инструменты для обхода данных мер, но риск атаки на беспроводной маршрутизатор или веб-сервер снижается.

Существует обратная концепция – «безопасность через открытость», которая подразумевает, что за программным обеспечением с открытым исходным кодом наблюдает больше глаз, а значит, эти глаза найдут уязвимости в безопасности и сообщат о них. На практике исследователи безопасности редко просматривают открытый код и сообщают об ошибках бесплатно. В проектах с открытым исходным кодом разработчики не всегда устраняют выявленные недостатки безопасности, а если уязвимости найдены, нашедший может решить продать их на черном рынке (преступникам, собственному либо иностранному правительству и т. д.), вместо того чтобы сообщить о них владельцу репозитория кода надежным способом.

Хотя сам по себе подход «безопасность через неясность» вряд ли является превосходным методом защиты, он, безусловно, полезен в качестве одного из уровней стратегии обеспечения безопасности – «защиты в глубину».

Уменьшение поверхности атаки

Атаке подвержен каждый элемент программного обеспечения: любая функция, вход, страница или кнопка. Чем меньше приложение, тем меньше поверхность атаки. Четыре страницы с 10 функциями представляют гораздо меньшую поверхность атаки, чем 20 страниц со 100 функциями. Каждый элемент приложения, который может быть подвержен действию злоумышленника, считается поверхностью атаки.

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

СОВЕТ. Устаревшее программное обеспечение часто имеет очень большой объем неиспользуемой функциональности. Удаление ненужных функций – отличный способ уменьшить поверхность атаки.

Как вы помните, у Алисы и Боба есть медицинские имплантаты: устройство для измерения инсулина у Алисы и кардиостимулятор у Боба. Оба являются «смарт-устройствами», то есть к ним можно подключиться через смартфон. Устройство Алисы работает через Bluetooth, а кардиостимулятор Боба – через Wi-Fi. Одним из самых очевидных способов уменьшить поверхность атаки было бы не приобретать «смарт-версии» таких устройств. Однако в данном случае делать это уже поздно. Тем не менее Алиса могла бы отключить «видимость» Bluetooth у своего прибора для измерения инсулина, а Боб – скрыть SSID своего кардиостимулятора.

Жесткое кодирование

Жесткое кодирование означает программирование значений в коде вместо получения их естественным путем (от пользователя, из базы данных, API и т. д.). Например, если в разработанном вами приложении-калькуляторе пользователь вводит 4 + 4, нажимает Enter и на экране появляется 8, вы, скорее всего, решите, что калькулятор работает. Однако если пользователь вводит 5 + 5 и нажимает Enter, а на экране все равно отображается 8, это может говорить о возникновении ситуации жесткого кодирования.

Почему жесткое кодирование является потенциальной проблемой безопасности? Причина двоякая: вы не можете доверять выходным данным приложения, а значения, которые были жестко закодированы, часто имеют конфиденциальный характер (пароли, ключи от API, хеши и т. д.). Любой, кто зайдет в исходный код, будет иметь доступ к этим жестко закодированным значениям. Жесткое кодирование в исходном коде секретов, требующих постоянной сохранности, – далеко не безопасное решение.

Жесткое кодирование обычно считается симптомом плохой разработки программного обеспечения (есть и исключения). Если вы столкнулись с ним в одном месте приложения, следует проверить все приложение на его наличие, поскольку маловероятно, что найденный вами экземпляр – единственный.

«Никогда не доверяй, всегда проверяй»

Если вы вынесете из этой книги только один урок, то он должен быть следующим: никогда не доверяйте ничему за пределами вашего собственного приложения. Если приложение обращается к API, убедитесь, что это правильный API и что у него есть полномочия на то, что он пытается делать. Если приложение принимает данные из любого источника, выполняйте проверку данных (необходимо убедиться, что полученные данные правильные. Если же это не так, блокируйте их). Даже данные из вашей собственной базы могут содержать вредоносный ввод или другие средства заражения. Если пользователь пытается получить доступ к той части приложения, которая требует специального разрешения, перепроверяйте, есть ли у него разрешение на каждую используемую им страницу или функцию. Если пользователь прошел аутентификацию (доказал, что он тот, за кого себя выдает) и переходит между страницами, необходимо все время удостоверяться, что это тот же самый пользователь (это называется управлением сессиями). Нельзя полагать, что одной проверки достаточно. Нужно постоянно проверять и перепроверять.

ПРИМЕЧАНИЕ. Мы проверяем данные из нашей базы, поскольку они могут содержать хранимый межсайтовый скриптинг (Cross-Site Scripting, XSS) или другие значения, способные навредить программе. Хранимый XSS появляется в тех случаях, когда программа не выполняет надлежащую проверку вводных данных и случайно сохраняет XSS-атаку в своей базе. Когда пользователь в приложении выполняет действие, вызывающее вредоносный скрипт, начинается атака в браузере жертвы. Пользователь не в состоянии защититься от этой атаки, и, как правило, она считается критической опасностью, если обнаруживается во время тестирования безопасности.

Довольно часто разработчики забывают об этом уроке и полагаются на доверие из-за сложившихся условий. Например, к выпущенному вами интернет-приложению применяются чрезвычайно строгие меры безопасности. Внутри вашей сети (в обход брандмауэра) веб-приложение постоянно вызывает API (#1), который затем вызывает другой API (#2), изменяющий данные в соответствующей базе. Часто разработчики не утруждают себя аутентификацией (подтверждением личности) в первом API или проверкой API (#1) на наличие у приложения права на вызов той части API, к которой оно обращается. А если они и выполняют такую проверку, то часто применяют меры безопасности только для API #1, но не для API #2. В результате кто или что угодно в вашей сети может вызвать API #2, включая злоумышленников, которых там быть не должно, внутренние угрозы или даже случайных пользователей (рис. 1.7).

Рис. 1.7. Пример вызова API приложением и при необходимости аутентификации


Вот несколько примеров.

• Веб-сайт заражен хранимым межсайтовым скриптингом, и злоумышленник использует его для хранения атаки в базе данных. Если веб-приложение проверяет данные, поступающие из базы данных, запуск сохраненной атаки будет безуспешным.

• Веб-сайт взимает плату за доступ к определенным данным, получаемым от API. Если пользователь знает, что API открыт для доступа в интернете, и не проверяет разрешение на его использование (аутентификация и авторизация), он может вызвать API напрямую и получить данные без оплаты (что было бы злонамеренным использованием сайта), то есть совершить кражу.

• Обычный пользователь приложения расстроен и многократно стучит по клавиатуре, случайно вводя гораздо больше данных, чем следовало. Если приложение правильно проверяет вводимые данные, оно отклонит их, так как количество символов превышает допустимый предел. Однако, если приложение не проверит эти данные, возможно, они перегрузят переменные или будут переданы в базу данных, следствием чего станет сбой. Без проверки соответствия получаемых данных ожиданиям (число в числовом поле, дата в поле даты, соответствующее количество вводимых символов и т. д.) приложение может перейти в неизвестное состояние со множеством ошибок безопасности. Приложение ни в коем случае не должно переходить в неизвестное состояние.

Удобство и безопасность

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

 

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

Вот примеры удобства и безопасности.

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

• Вместо установки правил сложности (обязательное использование специальных символов, цифр, строчных и прописных букв и т. д.) научить пользователей создавать парольные фразы (предложение или фразу, которую легко запомнить и набрать). Парольная фраза увеличит энтропию, которая затруднит злоумышленникам взлом, но в то же время упростит обеспечение защиты пользователям.

• Научить пользователей применять менеджеры паролей, а не ожидать, что они создадут и запомнят 100+ уникальных паролей для всех своих учетных записей.

А вот примеры обхода мер безопасности пользователями.

• Вход в охраняемое здание вместе с другим человеком (человек, который идет вплотную за другим, входящим в здание, может не проводить картой, чтобы попасть внутрь).

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

• Использование прокси-сервиса для посещения веб-сайтов, которые заблокированы рабочей сетью.

• Фотосъемка экрана с целью получения изображения, защищенного авторским правом, или конфиденциальных данных.

• Использование одного и того же пароля раз за разом, но с увеличением последней цифры для удобства запоминания. Если ваша компания заставляет пользователей сбрасывать пароль каждые 90 дней, велика вероятность того, что в вашей организации есть немало паролей, соответствующих формату ТекущееВремяГода_ТекущийГод.

Факторы аутентификации

Аутентификация – это предоставление компьютеру доказательства того, что вы – действительно настоящий, подлинный вы. «Фактор» аутентификации – метод доказательства компьютеру того, кто вы есть. В настоящее время существует только три фактора: что-то, что у вас есть, что-то, что является частью вас, и что-то, что вы знаете.

• То, что у вас есть, может быть телефоном, компьютером, ключом или рабочим бейджем. То, что должны иметь только вы.

• То, что является частью вас, может быть отпечатком пальца, радужной оболочкой глаза, походкой или ДНК. Ваша уникальная физическая особенность.

• То, что вы знаете, может быть паролем, парольной фразой, графическим ключом или комбинацией нескольких частей информации (часто называемых контрольными вопросами, например девичья фамилия матери, дата рождения и номер социального страхования). Идея фактора заключается в том, что эту информацию должны знать только вы.

Мы используем только один «фактор» аутентификации, когда входим в учетную запись в интернете посредством имени пользователя и пароля. Однако лучшим решением касательно безопасности является использование двух и более факторов. Взлом учетных записей или кража данных часто происходит из-за использования только одного фактора аутентификации. Использование более одного фактора обычно называют многофакторной аутентификацией (multi-factor authentication, MFA), двухфакторной аутентификацией (two-factor authentication, 2FA) или двухэтапным входом в систему. Мы будем использовать аббревиатуру MFA.

СОВЕТ. Контрольные вопросы уже устарели. Ответы на большинство из них легко найти в интернете, выполнив сбор данных из открытых источников (OSINT, Open source intelligence – Разведка на основе открытых источников). Не используйте в своем программном обеспечении контрольные вопросы в качестве фактора аутентификации: злоумышленники слишком легко их обходят.

Учетные записи пользователей, использующих второй фактор аутентификации, защищены от взлома, производимого посредством украденных учетных данных (имени пользователя и пароля). Злоумышленник не сможет войти в систему, не пройдя второй фактор. Если кто-то пытается взломать систему или учетную запись с MFA методом грубой силы (используя сценарий быстрого автоматического перебора всех возможных вариантов), то, даже получив пароль, он не сможет войти в систему. Использование второго фактора значительно затрудняет взлом учетных записей в интернете.

Вот примеры MFA.

• Многофакторный: ввод имени пользователя и пароля, а затем использование второго устройства или физического ключа для получения кода аутентификации. Имя пользователя и пароль – первый фактор (то, что вы знаете), а использование второго устройства – второй фактор (то, что вы имеете).

• Не многофакторный: имя пользователя и пароль. Это два примера одного и того же фактора: они оба являются чем-то, что вы знаете. Многофакторная аутентификация подразумевает использование нескольких различных типов факторов аутентификации.

• Не многофакторный: использование имени пользователя и пароля, а затем ответ на контрольный вопрос. Два элемента одного фактора: что-то известное вам.

• Многофакторный: имя пользователя, пароль и отпечаток большого пальца.

ПРИМЕЧАНИЕ. Многие специалисты в области информационной безопасности расходятся во мнении, является ли использование телефона для получения SMS (текстового сообщения) с пин-кодом «хорошей» реализацией MFA, поскольку известны недостатки протокола SMS и некоторых его реализаций. Я считаю, что лучше иметь «достаточно хороший второй фактор», чем только один. Однако по возможности просите пользователей применять в качестве второго фактора приложение для аутентификации, а не SMS-сообщения.

Упражнения

Цель данных упражнений – помочь понять концепции, изложенные в этой главе. Запишите ответы и посмотрите, какие вопросы вызвали затруднения: возможно, вам стоит перечитать главу. Такие упражнения будут в конце каждой главы. Незнакомый термин можно посмотреть в глоссарии в конце книги, что также позволяет облегчить понимание материала.

Если у вас есть коллега или профессиональный наставник, с которым вы можете обсудить ответы, это будет лучшим способом выяснить, правы вы или нет и почему. Некоторые из вопросов не являются логическими выражениями (не требуют ответов «истина/ложь»), а просто заставляют вас задуматься над проблемой.


1. Боб установил в настройках Wi-Fi на кардиостимуляторе запрет на передачу имени своего Wi-Fi. Как называется эта стратегия обеспечения безопасности?

2. Назовите пример значения, которое может быть жестко закодировано, и объясните почему. (Почему программист сделал бы это?)

3. Является ли капча удобной мерой безопасности? Почему?

4. Приведите один пример хорошей реализации удобства и безопасности.

5. Необходимо ли подтверждать данные, полученные при использовании параметров URL? Почему?

6. Если на работе сотрудник узнает коммерческую тайну, а затем продаст ее конкуренту, какую часть (или какие части) триады CIA он нарушит?

7. Вы купили смарт-холодильник и подсоединили его к домашней сети. К нему подключился злоумышленник и в настройках повысил температуру, в результате чего ваше молоко испортилось. Какую часть (или какие части) триады CIA он нарушил?

8. Если злоумышленник взломает ваш умный термостат и отключит отопление, какую часть (или какие части) триады CIA он нарушит?

9. Считается ли инсайдерской угрозой добавленная программистом «пасхалка» (дополнительный код, выполняющий незарегистрированные функции, в качестве «сюрприза» для пользователей, о котором неизвестно руководству и команде безопасности)? Почему?

10. Какие меры предосторожности можно предпринять при подключении к общественному Wi-Fi, чтобы обеспечить «глубокую защиту»?

11. Если вы живете в квартире с несколькими соседями и у каждого из вас есть ключ от двери, считается ли один из таких ключей «фактором аутентификации»?

Глава 2
Требования безопасности

Независимо от используемой методологии разработки (Waterfall, Agile, DevOps), языка, платформы или аудитории требования к любому приложению, к любому новому проекту должны быть определены. Без плана нельзя создать что-то стоящее.

Если вы изучали информатику или компьютерную инженерию, то схема, изображенная на рис. 2.1, скорее всего, уже отпечаталась в вашем сознании. Это известный жизненный цикл разработки системы, который состоит из пяти фаз: требования, проектирование, кодирование, тестирование и релиз. Мы будем периодически возвращаться к данной схеме, чтобы объяснить, когда каждый упоминаемый нами вид деятельности может или должен происходить. Эта глава будет посвящена этапу требований.


Рис. 2.1. Жизненный цикл разработки системы

СОВЕТ. Жизненный цикл разработки системы называется также жизненным циклом программного обеспечения (ПО). Можно заметить, что во втором определении основное внимание уделено программному обеспечению, а не системе. Два этих определения взаимозаменяемы.

На первом собрании по проекту (часто называемом «установочной встречей») должен присутствовать человек из службы безопасности, который будет принимать участие в проекте с самого начала разработки. Даже не занимаясь проектом полный рабочий день, он должен быть полноценным членом команды и постоянно оказывать активную помощь в своевременном решении всех вопросов и проблем, касающихся обеспечения безопасности. Назначение сотрудника службы безопасности в проектную команду иногда называют моделью партнерства, а самого человека – «встроенным в матрицу команды». Независимо от того, как его называют, данный сотрудник должен представлять интересы службы безопасности (то есть триады CIA) на протяжении всей разработки проекта.

ПРИМЕЧАНИЕ. Точное происхождение термина «Модель партнерства» неизвестно. Впервые я узнала о нем от команды Netflix, занимающейся вопросами безопасности. Выражение «встроенный в матрицу команды» я впервые услышала в секретариате Казначейства Канады, и оно также имеет неизвестное происхождение.

В этой главе предполагается, что у вас есть базовое понимание работы IТ-проектов и процессов разработки программного обеспечения.

СОВЕТ. Определить разумные сроки ожидания ответа от службы безопасности можно с помощью соглашения об уровне поддержки (SLA, Support Level Agreement) между службой безопасности и другими командами. Часто во время работы над проектом взаимодействие с представителями службы безопасности становится практически невозможным. При наличии SLA этой проблемы можно избежать. Для достижения наилучших результатов следует установить скромные начальные цели и постепенно увеличивать их масштаб.

1  2  3  4  5  6  7  8  9  10  11  12  13  14  15  16  17  18  19  20  21  22  23  24  25  26 
Рейтинг@Mail.ru