Контрольные списки разработки средств обеспечения безопасности

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

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

Использование полномочия

Этот контрольный список предназначается, чтобы определить, работает ли Ваш код когда-нибудь с поднятыми полномочиями, и если это делает, как лучше всего сделать так безопасно. Обратите внимание на то, что лучше избегать работать с поднятыми полномочиями если возможный; посмотрите Предотвращение Поднятые Полномочия.

  1. Сократите полномочия, когда это возможно.

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

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

  2. Используйте поднятые полномочия экономно, и только в привилегированных помощниках.

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

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

    Если необходимо выполнить код с поднятыми полномочиями, вот некоторые правила:

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

    • Ваш инструмент помощника должен сделать как можно меньше.

    • Ваш инструмент помощника должен ограничить то, что можно попросить, чтобы он сделал как можно больше.

    • Ваш инструмент помощника должен или отбросить поднятые полномочия или прекратить выполняться как можно скорее.

    Посмотрите Подъемные Полномочия Безопасно и Разрабатывающий Безопасных Помощников и Демонов для получения дополнительной информации.

  3. Использовать launchd если это возможно.

    Если Вы пишете демону или другому процессу, работающему с поднятыми полномочиями, необходимо всегда использовать launchd запустить его. (Для изучения, почему другие механизмы не рекомендуются считайте Ограничения и Риски Других Механизмов.)

    Для получения дополнительной информации о launchd, см. страницы руководства для launchd, launchctl, и launchd.plist, и Руководство по программированию Демонов и Служб. Для получения дополнительной информации об элементах запуска, см. Руководство по программированию Демонов и Служб. Для получения дополнительной информации о ipfw, посмотрите ipfw страница руководства.

  4. Избегайте использования sudo программно.

    Если авторизовано сделать так в sudoers файл, пользователь может использовать sudo выполнить команду как корень. sudo команда предназначается для случайного административного использования пользователем, находящимся в компьютере и вводящим в Терминальное приложение. Его использование в сценариях или вызванный от кода не безопасно.

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

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

  5. Минимизируйте объем кода, который должен быть выполнен с поднятыми полномочиями.

    Спросите себя приблизительно, сколько строк кода должно работать с поднятыми полномочиями. Если этот ответ будет или «всеми» или будет трудным числом для вычислений, то будет очень трудно выполнить анализ безопасности программного обеспечения.

    Если Вы не можете определить, как к фактору Ваше приложение для выделения кода, которому нужны полномочия Вы строго призваны искать помощь со своим проектом сразу. Если Вы - участник ADC, Вы призваны обратиться за помощью от инженеров Apple с факторингом к своему коду и выполнению проверки защиты. Если Вы не участник ADC, посмотрите страницу членства ADC в http://developer .apple.com/programs/.

  6. Никогда не запускайте приложение GUI с поднятыми полномочиями.

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

Данные, конфигурация и временные файлы

Некоторые уязвимости системы обеспечения безопасности связаны с чтением или записью файлов. Этот контрольный список предназначается, чтобы помочь Вам найти любые такие уязвимости в своем коде.

  1. Будьте осторожны при работе с файлами в недоверяемых расположениях.

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

    Точно так же, если Вы пишете временные файлы в публично перезаписываемое место (например, /tmp, /var/tmp, /Library/Caches или другое определенное место с этой характеристикой), атакующий может быть в состоянии изменить Ваши файлы перед следующим разом, когда Вы читаете их.

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

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

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

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

    Это означает:

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

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

    • Удостоверьтесь, что пути к файлам не содержат подстановочные символы, такой как ../ или ~, который атакующий может использовать для переключения текущего каталога на один под управлением атакующего.

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

  3. Загрузите расширения ядра тщательно (или нисколько).

    Расширение ядра является окончательным привилегированным кодом — это имеет доступ к уровням операционной системы, которая не может быть затронута обычным кодом, даже работая как корень. Необходимо быть чрезвычайно осторожными, почему, как, и когда Вы загружаете расширение ядра для принятия мер против того, чтобы быть дурачившимся в загрузку неправильной. Если Вы не достаточно осторожны, возможно загрузить корневой набор. (Корневой набор является вредоносным кодом, который, путем выполнения в ядре, может не только принять управление системы, но может покрыть все доказательство ее собственного существования.)

    Чтобы удостовериться, что атакующий так или иначе не заменил его или ее собственным расширением ядра Ваше, необходимо всегда хранить расширения ядра в безопасных местах. Можно при желании использовать подписывание кода или хеши для дальнейшей проверки их подлинности, но это не устраняет необходимость защитить расширение с надлежащими полномочиями. (Время проверки по сравнению с атаками времени использования все еще возможно.) Обратите внимание на то, что в последних версиях OS X, это частично смягчено загрузочной системой KEXT, отказывающейся загружать любой kext двоичный файл, владелец которого не root или чья группа не wheel.

    В целом необходимо избежать писать расширения ядра (см., Не пускают в Руководстве по программированию Ядра). Однако, если необходимо использовать расширение ядра, используйте средства, встроенные в OS X, чтобы загрузить расширение и убедиться загрузить расширение из отдельного привилегированного процесса.

    Посмотрите Подъемные Полномочия Безопасно для узнавания больше о безопасном использовании корневого доступа. См. Руководство по программированию Ядра для получения дополнительной информации о записи и загрузке расширений ядра. Для справки при записи драйверов устройств посмотрите Основные принципы Набора I/O.

Использование сетевого порта

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

  1. Используйте числа назначенного порта.

    Номера портов 0 до 1 023 резервируются для использования определенными службами, указанными Комитетом по цифровым адресам в интернете (IANA; посмотрите http://www .iana.org/). Во многих системах включая OS X, только выполнение процессов, поскольку корень может связать с этими портами. Не безопасно, однако, предположить, что можно доверять любой связи, прибывающей через эти привилегированные порты. Возможно, что атакующий получил корневой доступ и использовал его для привязки с привилегированным портом. Кроме того, в некоторых системах, корневой доступ не необходим для привязки с этими портами.

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

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

    Посмотрите Ввод Проверки и Межпроцессное взаимодействие для получения дополнительной информации о проверке ввода.

  2. Выберите надлежащий транспортный протокол.

    Протоколы нижнего уровня, такие как UDP, обеспечивают более высокую производительность для некоторых типов трафика, но проще имитировать, чем протоколы более высокого уровня, такие как TCP.

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

  3. Используйте существующие услуги аутентификации, когда будет необходима аутентификация.

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

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

    Единственным утвержденным механизмом авторизации для сетевых приложений является Kerberos; посмотрите Аутентификацию Клиент-сервер. Для получения дополнительной информации о безопасных сетях посмотрите Безопасную Транспортную Ссылку и Руководство по программированию CFNetwork.

  4. Проверьте доступ программно.

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

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

  5. Перестали работать корректно.

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

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

  6. Разработайте свою службу для обработки высокого объема соединения.

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

    Можно использовать ipfwпрограмма брандмауэра к управляющим пакетам и потоку трафика для интернет-демонов. Для получения дополнительной информации о ipfw, посмотрите ipfw страница руководства. Для большего уведомления относительно контакта с атаками «отказ в обслуживании» посмотрите Уилера, Безопасное Программирование для Linux и Unix HOWTO, доступный в http://www .dwheeler.com/secure-programs/.

  7. Разработайте хеш-функции тщательно.

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

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

Журналы аудита

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

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

  1. Аудит пытается соединиться.

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

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

    Посмотрите Уилера, Безопасное Программирование для Linux и Unix HOWTO для некоторого уведомления относительно журналов аудита.

  2. Используйте libbsm контроль библиотеки, если это возможно.

    libbsm контроль библиотеки является частью проекта TrustedBSD, который поочередно является рядом доверенных расширений операционной системы FreeBSD. Apple способствовал этому проекту и включил контрольную библиотеку в Дарвинское ядро операционной системы OS X. (Эта библиотека не доступна в iOS.)

    Можно использовать libbsm контроль библиотеки для реализации контроля программы для входа в систему и попыток авторизации. Эта библиотека дает Вам большой контроль, по которому контролируются события и как обработать атаки «отказ в обслуживании».

    libbsm проект расположен в http://www .opensource.apple.com/darwinsource/Current/bsm/. Для документации службы BSM см. “главу” Тем Контроля в Руководстве по Системному администрированию Sun Microsystems: Службы безопасности расположились в http://docs .sun.com/app/docs/doc/806-4078/6jd6cjs67? a=view.

  3. Если Вы не можете использовать libbsm, будьте осторожны при записи журналов аудита.

    При использовании механизмов аудита кроме libbsm, существует много ловушек, которых необходимо избежать, в зависимости от какого механизма аудита Вы используете:

    • syslog

      До реализации libbsm контролируя библиотеку, функцию стандартной библиотеки для C syslog обычно использовался для записи данных в файл журнала. Если Вы используете syslog, рассмотрите переключение на libbsm, который дает Вам больше опций иметь дело с атаками «отказ в обслуживании». Если Вы хотите остаться с syslog, убедитесь, что Ваш код контроля является стойким к атакам «отказ в обслуживании», как обсуждено на шаге 1.

    • Пользовательский файл журнала

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

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

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

      Наконец, убедитесь, что Ваш пользовательский код журналирования контролируется для уязвимостей системы обеспечения безопасности.

Аутентификация клиент-сервер

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

  1. Не храните, проверяйте или изменяйте пароли сами.

    Это - очень плохая идея сохранить, проверить, или изменить пароли самостоятельно, поскольку очень трудно сделать так надежно, и OS X и iOS предоставляют охраняемые услуги в просто той цели.

    • В OS X можно использовать цепочку для ключей для хранения паролей и Authorization Services, чтобы создать, изменить, удалить, и проверить пароли пользователя (см. Руководство по программированию Keychain Services Programming Guide and Authorization Services).

    • В OS X, если у Вас есть доступ к установке Сервера OS X, можно использовать, Открывать Directory (см., Открывают Directory Programming Guide) сохранить пароли и аутентифицировать пользователей.

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

  2. Никогда не отправляйте пароли по сетевому соединению в форме открытого текста.

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

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

    OS X обеспечивает APIs для соединений защищенной сети; посмотрите Безопасную Транспортную Ссылку и Руководство по программированию CFNetwork для подробных данных.

  3. Используйте аутентификацию сервера в качестве меры антиспуфинга.

    Несмотря на то, что аутентификация сервера является дополнительной в протоколах SSL/TLS, необходимо всегда делать это. Иначе, атакующий мог бы имитировать Ваш сервер, травмируя Ваших пользователей и нанося ущерб Вашей репутации в процессе.

  4. Используйте разумные политики пароля.

    • Надежность пароля

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

    • Истечение срока пароля

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

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

      Посмотрите Истечение срока Пароля, Продуманное Вредный для получения дополнительной информации.

    • Неаутентификация по паролю

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

    • Отключенные учетные записи

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

    • Учетные записи с истекшим сроком

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

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

    • Изменение паролей

      Можно потребовать, чтобы клиентское приложение поддерживало возможность изменить пароли, или можно потребовать, чтобы пользователь изменил пароль с помощью веб-интерфейса на самом сервере.

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

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

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

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

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

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

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

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

    • Ограничения на длину пароля (корректируемый системным администратором)

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

    Чем больше этих политик, которые Вы осуществляете, тем более безопасный Ваш сервер будет. Вместо того, чтобы создавать Вашу собственную базу данных пароля — который трудно сделать надежно — необходимо использовать Сервер Пароля Apple. Посмотрите Открывают Directory Programming Guide для получения дополнительной информации о Сервере Пароля, Ссылке Платформы Службы каталогов для списка функций Служб каталогов и страниц руководства для pwpolicy(8), passwd(1), passwd(5), и getpwent(3) в http://developer .apple.com/documentation/Darwin/Reference/ManPages/index.html для инструментов, чтобы получить доступ к базе данных пароля и установить политики паролей.

  5. Не храните незашифрованные пароли и не переиздавайте пароли.

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

    Например, предположите, что Ваша программа работает на веб-сервере, и Вы используете SSL для передачи с клиентами. Если Вы берете пароль клиента и используете его для журналирования в сервер базы данных, чтобы сделать что-то от имени клиента, нет никакого способа гарантировать, что сервер базы данных сохраняет пароль безопасным и не передает его на другой сервер в форме открытого текста. Поэтому даже при том, что пароль был в безопасном контексте, когда он отправлялся в веб-сервер по SSL, когда веб-сервер переиздает его, это находится в небезопасном контексте.

    Если Вы хотите сэкономить свой клиент проблема войти в систему отдельно каждого сервера, необходимо использовать некоторую forwardable аутентификацию, такую как Kerberos. Для получения дополнительной информации о реализации Apple Kerberos посмотрите http://developer .apple.com/darwin/projects/kerberos/.

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

  6. Поддержка Kerberos.

    Kerberos является единственной службой авторизации, доступной по сети для серверов OS X, и это предлагает возможности единой точки входа. Если Вы пишете сервер для работы OS X, необходимо поддерживать Kerberos. Когда Вы делаете:

    1. Убедитесь, что Вы используете последнюю версию (v5).

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

    Единственная альтернатива Kerberos комбинирует SSL/¦утентихик¦цию TLS с некоторыми другими средними значениями авторизации, такими как список управления доступом.

  7. Ограничьте гостевой доступ соответственно.

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

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

  8. Не реализуйте свою собственную службу каталогов.

    Откройте Directory является сервером каталогов, предоставленным OS X для безопасного хранения паролей и аутентификации пользователя. Важно, чтобы Вы использовали эту службу и не попытались реализовать Ваше собственное, поскольку безопасные серверы каталогов трудно реализовать, и пароли всего каталога могут поставиться под угрозу, если это сделало неправильно. Посмотрите Открывают Directory Programming Guide для получения дополнительной информации.

  9. Куст (нуль) пароли пользователя из памяти после проверки.

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

Целочисленные переполнения и переполнение буфера

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

  1. Используйте значения без знака при вычислении смещений объекта памяти и размеров.

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

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

    Посмотрите Целочисленные переполнения Предотвращения и Потери значимости и Вычисление Буферных Размеров для подробных данных.

  2. Проверьте на целочисленные переполнения (или потери значимости целого числа со знаком) при вычислении смещений объекта памяти и размеров.

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

    Посмотрите Целочисленные переполнения Предотвращения и Потери значимости и Вычисление Буферных Размеров для подробных данных.

  3. Избегите небезопасных обрабатывающих строку функций.

    Функции strcat, strcpy, strncat, strncpy, sprintf, vsprintf, и gets не имейте никаких встроенных проверок на длину строки, и может привести к переполнению буфера.

    Для альтернатив считайте Строковую Обработку.

Криптографическое функциональное использование

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

  1. Используйте генераторы случайных чисел, которым доверяют.

    Не пытайтесь генерировать свои собственные случайные числа.

    Существует несколько способов получить высококачественные случайные числа:

    • В iOS используйте интерфейс программирования Randomization Services.

    • В OS X:

      • Читайте из /dev/random в OS X (см. страницу руководства для random).

      • Используйте read_random функция в заголовочном файле random.h в Apple модуль CSP, который является частью реализации Apple платформы CDSA (доступный в http://developer .apple.com/darwin/projects/security/).

    Обратите внимание на то, что rand не возвращает хорошие случайные числа и не должен использоваться.

  2. Используйте TLS/SSL вместо пользовательских схем.

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

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

    Для узнавания больше о безопасных сетевых протоколах, доступных в OS X и iOS, считайте Данные Передачи Надежно в Руководстве по Криптографическим службам.

  3. Не делайте самокрутки crypto алгоритмы.

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

    Для приобретения знаний о криптографических службах, доступных в OS X и iOS, считайте Руководство по Криптографическим службам.

Установка и загрузка

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

  1. Не устанавливайте компоненты в /Library/StartupItemsили/System/Library/Extensions.

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

    Для получения информации о верных полномочиях для элементов запуска посмотрите Элементы Запуска. (Обратите внимание на то, что в OS X v10.4 и позже, элементы запуска осуждаются; необходимо использовать launchd запустить Ваших демонов вместо этого. См. Руководство по программированию Демонов и Служб для получения дополнительной информации.)

    Для получения информации о полномочиях для расширений ядра посмотрите, что Расширение ядра Программирует Темы. (Обратите внимание на то, что начинающийся в OS X v10.2, OS X проверяет на проблемы полномочий и отказывается загружать расширения, если полномочия не корректны.)

  2. Не используйте сценарии заказной установки.

    Сценарии заказной установки добавляют ненужную сложность и риск, поэтому, если это возможно, необходимо избежать их полностью.

    Если необходимо использовать сценарий заказной установки, Вы должны:

    • Если Ваши выполнения сценария установщика в оболочке, считайте и последуйте совету в Безопасности Сценария оболочки в Shell, Пишущем сценарий Учебника для начинающих.

    • Убедитесь, что Ваш сценарий следует инструкциям в этом контрольном списке, как остальная часть Вашего приложения делает.

      В частности:

      • Не пишите временные файлы в глобально перезаписываемые каталоги.

      • Не выполняйтесь с более высокими полномочиями, чем необходимый.

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

      • Не выполняйтесь с поднятыми полномочиями больше, чем необходимый.

      • Установите разумные полномочия на своем установленном приложении.

        Например, не давайте всем разрешение чтения-записи файлам в комплекте приложений, если только владельцу нужно такое разрешение.

      • Установите маску создания кода файла своего установщика (umask) для ограничения доступа к файлам, которые это создает (см. Операции Файла Обеспечения).

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

    Для уведомления относительно записи кода установки, который должен выполнить привилегированные операции, см. Руководство по программированию Authorization Services. Для получения дополнительной информации о записи сценариев оболочки, считайте Shell, Пишущий сценарий Учебника для начинающих.

  3. Плагины загрузки и библиотеки только от безопасных мест.

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

    Знайте что редактор динамического канала (dyld) мог бы соединиться в плагинах, в зависимости от среды, в которой работает Ваш код. Если Ваш код использует загружаемые пакеты (CFBundle или NSBundle), тогда это динамично загружает код и могло потенциально загрузить пакеты, записанные злонамеренным хакером.

    Посмотрите, что Код Загружает Темы Программирования для получения дополнительной информации о динамично загруженном коде.

Использование внешних инструментов и библиотек

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

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

    Если Вы используете подпрограммы такой как popen или system для отправки команд в оболочку, и Вы используете ввод от пользователя или принятые по сети для построения команды, необходимо знать, что эти подпрограммы не проверяют свой ввод. Следовательно, злонамеренный пользователь может передать метасимволы оболочки — такие как escape-последовательность или другие специальные символы — в параметрах командной строки. Эти метасимволы могли бы заставить следующий текст интерпретироваться как новая команда и выполняться.

    Кроме того, при вызывании функций такой как execlp, execvp, popen, или system то использование PATH переменная окружения для поиска исполнимых программ необходимо всегда указывать полный абсолютный путь к любому инструменту, который Вы хотите выполнить. Если Вы не делаете, злонамеренный атакующий может потенциально заставить Вас выполнять различный инструмент с помощью атаки переменной окружения. Когда возможно, использовать execvP (который берет явный параметр пути поиска), или избегите этих функций в целом.

    Посмотрите Вигу и Макгроу, Создав Безопасное программное обеспечение, Аддисона Уэсли, 2002, и Уилер, Безопасное Программирование для Linux и Unix HOWTO, доступный в http://www .dwheeler.com/secure-programs/, для получения дополнительной информации о проблемах с этими и подобными подпрограммами и для безопасных способов выполнить команды оболочки.

  2. Не передавайте уязвимую информацию о командной строке.

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

    • Канал или стандартный ввод

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

    • Переменные окружения

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

      См. Безопасность Сценария оболочки в Shell, Пишущем сценарий Учебника для начинающих для подробных данных.

    • Общая память

      Названный и сегменты глобально-общей-памяти может быть считан другими процессами. Посмотрите Межпроцессное взаимодействие и Объединяющийся в сеть для получения дополнительной информации о безопасном использовании общей памяти.

    • Временный файл

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

  3. Проверьте все параметры (включая имя).

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

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

Этот контрольный список предназначается, чтобы помочь Вам программировать безопасно в ядре.

  1. Проверьте подлинность основанных на Махе служб.

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

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

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

  2. Проверьте подлинность других служб пространства пользователя.

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

  3. Дескриптор буферизует правильно.

    При копировании данных в и от пространства пользователя, Вы должны:

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

    2. Проверьте на и обработайте неправильно выровненные буферы.

    3. Обнулите все данные клавиатуры при копировании в или от памяти пространства пользователя.

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

  4. Ограничьте ресурсы памяти, которые может запросить пользователь.

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

  5. Санируйте любые сообщения журнала ядра.

    Код ядра часто генерирует сообщения к консоли для отладки целей. Если Ваш код делает это, бойтесь включать любую уязвимую информацию в сообщения.

  6. Не регистрируйте слишком много.

    Служба журналирования ядра имеет ограниченный размер буфера для срыва атакам «отказ в обслуживании» против ядра. Это означает, что, если Ваш код ядра регистрирует слишком часто или слишком много, могут быть отброшены данные.

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

  7. Разработайте хеш-функции тщательно.

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

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