19 смертных грехов, угрожающих безопасности программ
Шрифт:
□ Обеспечьте безопасный механизм смены пароля человеком, который знает пароль.
Не рекомендуется
□ Усложните процедуру переустановки пароля по телефону сотрудником службы поддержки.
□ Не поставляйте систему с учетными записями и паролями по умолчанию. Вместо этого реализуйте процедуру инициализации, которая позволит задать пароль для записи по умолчанию в ходе инсталляции или при первом запуске приложения.
□ Не храните пароли в открытом виде на сервере.
□ Не «зашивайте» пароли в текст программы.
□ Не протоколируйте неправильно введенные пароли.
□ Не допускайте коротких паролей.
Стоит
□ Об использовании алгоритма типа PBKDF2, который увеличивает время вычисления односторонней свертки.
□ О многофакторной аутентификации.
□ Об использовании протоколов с нулевым знанием, которые снижают шансы противника на проведение успешной атаки с полным перебором.
□ О протоколах с одноразовым паролем для доступа из не заслуживающих доверия систем.
□ О программной проверке качества пароля.
□ О том, чтобы посоветовать пользователю, как выбрать хороший пароль.
□ О реализации автоматизированных способов переустановки пароля, в частности путем отправки временного пароля по почте в случае правильного ответа на «личный вопрос».
Грех 12. Пренебрежение безопасным хранением и защитой данных
В чем состоит грех
Мы часто больше печемся о защите данных во время передачи, а не тогда, когда они уже оказались на диске. Но ведь информация куда больше времени проводит именно на диске, а не в сети. Есть ряд аспектов, которые нужно принимать во внимание при рассмотрении вопроса о безопасности хранения данных: права, необходимые для доступа к данным, шифрование данных и опасности, угрожающие хранящимся секретам.
Вариантом безопасного хранения данных является хранение секретов в тексте программы, хотя термин «хранение» здесь применим очень относительно! Из всех грехов этот раздражает нас больше прочих, поскольку это просто глупо. Многие программисты хранят такие секретные данные, как криптографические ключи и пароли, в самой программе, полагая, что пользователи их не узнают потому, мол, что реинжениринг выполнить очень трудно. И не надейтесь – злоумышленник может дизассемблировать любой код, чтобы завладеть секретными данными.
Подверженные греху языки
Еще одна универсальная беда. Допустить ошибки при доступе к данным и встроить секретные данные в код можно на любом языке.
Как происходит грехопадение
Наверное, вы уже поняли, что грех распадается на два основных компонента, назовем их «грешками». Грешок № 1 – это слабый механизм контроля доступа. Грешок № 2 – хранение секретных данных в коде программы. Рассмотрим их по очереди.
Слабый контроль доступа к секретным данным
При решении задачи организации контроля доступа нужно принимать во внимание значительные различия между платформами. В современных версиях операционной системы Windows имеются богатые, но сложные списки управления доступом (ACL). Причем у этой сложности есть две стороны. Если вы понимаете, как правильно пользоваться ACL, то сможете решить трудные проблемы, которые в более простых системах не решаются. Если же вы не разбираетесь в этом вопросе, то сложность ACL может повергнуть в недоумение, и – что гораздо хуже – вы можете наделать серьезных ошибок, в результате которых данные не будут в должной мере защищены.
Хотя ACL традиционно доступны на многих UNIX–системах, совместимых со стандартом POSIX, но в основе системы управления доступом там лежит понятие о триаде «владелец–группа–мир». В отличие от маски управления доступом в Windows, которая содержит сложный набор прав, в UNIX используются только три бита (не
Еще одно отличие между системами на базе Windows и UNIX заключается в том, что в UNIX–системах все объекты рассматриваются как файлы: сокеты, устройства и т. д. В Windows же есть очень много разных объектов, и для каждого имеются свои биты управления доступом. Мы не будем вдаваться в технические детали того, какие биты относятся к мьютексам, событиям, потокам, процессам, маркерам процессов, службам, драйверам, участкам отображаемой памяти, ключам реестра, файлам, протоколам событий и каталогам. Как всегда, желая создать объект со специализированными правами, читайте документацию. Но есть и хорошая новость: в большинстве случаев права, которыми операционная система наделяет объекты, – это как раз то, что вам нужно.
ACL и ограничение прав
Система на базе парадигмы «владелец–группа–мир» при решении вопроса о том, разрешить ли доступ к файлу, в первую очередь анализирует действующий идентификатор пользователя (effective user id – EUID) того процесса, который создал файл. Права, предоставляемые группе, зависят от того, использует ли ОС действующий идентификатор группы процесса или идентификатор группы того каталога, в котором создан файл. Наконец, если создатель файла или привилегированный пользователь разрешит, то к файлу может иметь доступ кто угодно (мир). Когда процесс пытается открыть файл, сначала проверяется, является ли запустивший его пользователь владельцем этого файла, затем – принадлежит ли он группе, связанной с этим файлом, и в последнюю очередь – предоставлен ли доступ всему миру. Очевидное следствие такого подхода заключается в том, что пользователи должны быть правильно распределены по группам, а если системный администратор управляет группами некорректно, то многим файлам могут быть назначены избыточные права, разрешающие доступ кому угодно.
Хотя в Windows существует несколько типов записей управления доступом (access control entries – АСЕ), все они обладают тремя общими характеристиками:
□ идентификатор пользователя или группы;
□ маска управления доступом, описывающая, что именно контролирует данная запись (чтение, запись и т. д.);
□ бит, определяющий, разрешает данная запись доступ или запрещает его.
Парадигму «владелец–группа–мир» можно считать частным случаем ACL с тремя разными записями и ограниченным набором управляющих битов. При проверке ACL система смотрит, соответствует ли хранящийся в нем идентификатор пользователя или группы идентификатору пользователя или группы, записанному в маркере процесса. Затем применяется запись управления доступом, и запрошенный вид доступа сравнивается с тем, что хранится в этой записи. Если соответствие есть и запись разрешает доступ, то проверяется, соответствуют ли флаги запрошенного доступа флагам разрешенного доступа. Если да, то проверка пройдена. Если в исследуемой записи подняты не все необходимые биты, то система переходит к следующей записи и так до тех пор, пока не будут подтверждены все права или АСЕ не закончатся. Если система встретит АСЕ, запрещающую доступ, которая соответствует запрошенному доступу и указанному в маркере пользователю или группе (все равно, активированным или нет), то она отказывает в доступе и других АСЕ не просматривает. Как видите, порядок АСЕ важен, поэтому лучше пользоваться таким API, который возвращает АСЕ в правильном порядке.