|
|
Безопасность библиотек классов
Цикл статей
Безопасность библиотек классов
Разработчики библиотеки классов должны понимать, как обеспечить защиту доступа к коду для того, чтобы писать защищенные библиотеки классов. При написании библиотеки классов учитывайте два принципа безопасности: защищайте объекты, применяя права доступа, и пишите полностью надежный код. Степень применения этих принципов будет зависеть от того, какой класс вы создаете. Некоторые классы, такие как класс System.IO.FileStream, представляют объекты, которые необходимо защищать путем применения прав доступа. Реализация этих классов проверяет права доступа пользователей и только зарегистрированным пользователям позволяется осуществлять те операции, на которые они имеют разрешение. Пространство имен System.Security содержит классы, которые могут помочь вам осуществить эти проверки в создаваемых библиотеках классов. Код библиотеки классов часто является полностью надежным или, по крайней мере, высоконадежным. Т.к. код библиотеки классов часто работает с защищенными ресурсами и неуправляемым кодом, любые дефекты кода представляют серьезную угрозу целостности внутренней системы безопасности. Чтобы минимизировать эту угрозу, при написании кода библиотеки классов следуйте рекомендациям, приведенным в данном разделе. Более подробная информация представлена в разделе MSDN Writing Secure Class Libraries.
Применение прав доступа для защиты объектов
Права доступа применяются для обеспечения безопасности определенных ресурсов. Библиотека классов, которая работает с защищенными ресурсами, должна отвечать за осуществление этой защиты. Перед проведением любого действия над защищенным ресурсом, например, уничтожение файла, код библиотеки классов сначала должен проверить, а имеет ли пользователь соответствующие права на уничтожение ресурса. Если пользователь имеет разрешение, действию может быть позволено завершиться. Если пользователь не имеет такого права, действие не будет завершено и должна будет вызвана исключительная ситуация безопасности. Защита обычно применяется в коде как с декларативной, так и с обязательной проверкой соответствующего разрешения.
Очень важным является то, что классы защищают ресурсы не только от прямого доступа, но и от всех возможных видов воздействия. Например, объект, кэширующий файл, несет ответственность за проверку разрешения на чтение файла, даже если реальные данные извлекаются из кэша в памяти и не происходит никакой фактической работы с файлом. Это происходит потому, что эффект от передачи данных пользователя такой же, как и в случае, если он осуществил фактическую операцию чтения.
Полностью надежный код библиотеки классов
Многие библиотеки классов реализовываются, как полностью надежный код, который инкапсулирует функциональные возможности, специфические для конкретной платформы, как управляемые объекты, такие как СОМ или system APIs. Полностью надежный код может привести к ослаблению безопасности всей системы. Однако, если библиотеки классов написаны правильно, с учетом безопасности, размещение мощного груза безопасности в относительно небольшом наборе библиотек классов и основная безопасность времени выполнения дает возможность большему количеству управляемого кода получить преимущества безопасности этих корневых библиотек классов.
В обычном сценарии безопасности библиотеки классов полностью надежный класс раскрывает ресурс, защищенный правом доступа; к ресурсу имеет доступ внутренний код API. Обычным примером такого типа ресурсов является файл. Класс File использует для осуществления файловых операций, таких как удаление, внутренний код API. Для защиты ресурса выполните следующие шаги:
- Пользователь запрашивает удаление файла
c:\test.txt вызывая метод File.Delete.
- Метод Delete создает разрешающий объект, представляющий разрешение на удаление
c:\test.txt.
- Код класса File проверяет всех пользователей в стеке на наличие у них необходимого разрешения; если такого разрешения нет, возникает исключительная ситуация безопасности.
- Класс File объявляет FullTrust, для того чтобы вызвать внутренний код, потому что его пользователи могут не иметь разрешения на это.
- Чтобы осуществить операцию удаления файла, класс File использует внутренний API.
- Класс File возвращается его пользователям, и запрос на удаление файла завершается успешно.
Меры предосторожности для высоконадежного кода
Код в надежной библиотеке классов имеет права, недоступные большинству кодов приложений. Кроме того, сборка может содержать классы, которые не нуждаются в специальных правах, а сами предоставляют эти права, потому что сборка содержит и другие классы, которым они нужны. Такая ситуация может привести к ослаблению безопасности системы. Поэтому необходимо быть особо аккуратным при написании высоко или полностью надежного кода.
Разрабатывайте надежный код таким образом, чтобы его мог вызвать любой код системы, обладающий частичной надежностью, без создания пробелов в системе безопасности. Обычно ресурсы защищаются методом проверки прав пользователей. Если пользователь не обладает соответствующим разрешением, попытка доступа блокируется. Однако как только надежный код предоставляет разрешение, код принимает ответственность за проверку на наличие необходимого права доступа. Обычно предоставление разрешения должно следовать за проверкой пользователя на наличие разрешения, как было описано выше. Кроме того, количество предоставления высоких полномочий должно быть минимальным, для того чтобы сократить риск несанкционированных воздействий.
Полностью надежному коду неявно предоставляются все остальные права. Кроме того, ему позволено нарушать правила безопасности типов и использования объектов. Независимость защиты ресурсов, любой аспект программного интерфейса, который может разрушить безопасность типов или предоставить возможность доступа к данным, обычно недоступным, могут привести к проблемам безопасности.
Производительность
Проверка безопасности приводит к проверке стека на наличие разрешения у всех пользователей. В зависимости от глубины стека эти операции потенциально требуют очень больших затрат производительности. Если одна операция в действительности состоит из некоторого числа действий на нижнем уровне, который требует проверки безопасности, значительно увеличить производительность можно путем разовой проверки всех разрешений пользователя, а потом перед осуществлением определенных действий подтверждать необходимое разрешение. Подтверждение остановит дальнейшее прохождение по стеку, таким образом проверка будет остановлена и будет успешной. Обычно применение этой технологии приводит к увеличению производительности, если есть возможность объединить три и более проверки.
Заключение
- Любая библиотека классов, которая использует защищенные ресурсы, должна гарантировать, что это происходит только при наличии разрешений у всех пользователей.
- Утверждение разрешений должно проводиться только по необходимости, и ему должны предшествовать необходимые проверки разрешений.
- Чтобы повысить производительность, сгруппируйте операции, которые вызовут проверки безопасности, и продумайте использование подтверждения, чтобы ограничить пробег по стеку без снижения безопасности.
- Отдавайте себе отчет в том, как может злонамеренный пользователь использовать класс, чтобы обойти систему безопасности.
- Не принимайте, что код будет вызываться только пользователями с определенными правами.
- Не определяйте интерфейсы, не обеспечивающие безопасность типов, они могут быть использованы для обхода системы безопасности.
- Не открывайте функциональные возможности в классе, это позволит злонамеренному пользователю воспользоваться преимуществами высокой надежности класса.
|