Поделиться через


Неуправляемый код

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

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

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

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

  • Функциональность. Обеспечивает ли неуправляемый API безопасную функциональность, которая не позволяет вызывающим объектам осуществлять потенциально небезопасные операции? Управление доступом для кода использует разрешения для доступа к ресурсам, поэтому следует проверить, использует ли API файлы, пользовательский интерфейс, потоки или что-либо еще, позволяющее получить доступ к защищенной информации. Если это происходит, управляемый код, который является кодом оболочки для рассматриваемого API, должен требовать необходимые разрешения для разрешения доступа к API. Кроме того, доступ к памяти должен быть типобезопасным, хотя и отсутствует защита с использованием разрешений.

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

См. также

Основные понятия

Правила написания безопасного кода