Выбор между проверками Demand и LinkDemand
Обновлен: Ноябрь 2007
Декларативная безопасность предлагает два вида проверки безопасности; эти виды похожи, но сами проверки существенно различаются. Необходимо знать оба вида проверок, так как неправильный выбор может привести к слабой защищенности или потере производительности. Дополнительные сведения см. в разделе Требования безопасности.
Декларативная безопасность предлагает следующие проверки безопасности.
Demand определяет использование проверки стека системы управления доступом для кода. Все вызывающие объекты в стеке должны иметь разрешение или удостоверение. Demand возникает при каждом вызове, так как стек может содержать различные вызывающие объекты. Если метод вызывается повторно, проверка безопасности рассматриваемого вида осуществляется при каждом вызове. Demand является хорошей защитой от отвлекающих атак; код, не имеющий разрешения и пытающийся обойти систему безопасности, будет обнаружен.
LinkDemand осуществляется по требованию на этапе компиляции, и проверяется только непосредственный вызывающий объект. Проверка этого вида не рассматривает тот объект, который осуществляет вызов вызывающего объекта. После завершения такой проверки не возникает дополнительных издержек производительности, связанных с безопасностью, независимо от количества вызовов, которые осуществляет вызывающий объект. Однако рассматриваемая проверка не имеет никакой защиты от отвлекающих атак. При использовании LinkDemand любой код, прошедший проверку и способный ссылаться на ваш код, может разрушить систему безопасности, позволив вредоносному коду осуществлять вызовы с использованием доверенного кода. Таким образом, не следует использовать LinkDemand, если нет уверенности, что все возможные слабые места могут быть полностью защищены.
Дополнительные меры предосторожности, необходимые при использовании LinkDemand, должны программироваться в индивидуальном порядке; система безопасности может предоставить для этого необходимые средства. Любая ошибка приводит к возникновению слабых мест в защите. Любой доверенный код, использующий ваш код, должен нести ответственность за реализацию дополнительных мер защиты, перечисленных ниже.
Ограничение доступа вызывающего кода к классу или сборке.
Использование для вызывающего кода тех же проверок безопасности, что и для вызываемого кода, а также принуждение вызывающих объектов вызываемого кода к таким же действиям. Например, если пишется код, который осуществляет вызов метода, защищенного LinkDemand для SecurityPermission с указанием флага UnmanagedCode, ваш метод также должен использовать LinkDemand (или более строгое требование Demand) для разрешения. Исключением является ситуация, когда код использует метод, защищенный LinkDemand, особым способом, который полагается безопасным с учетом других механизмов обеспечения безопасности (например, требований) в коде. В этом исключительном случае вызывающий объект несет ответственность за понижение степени защиты в базовом коде.
Следует убедиться, что объекты, вызывающие код, не смогут заставить его вызывать защищенный код по их распоряжению. Другими словами, вызывающие объекты не должны иметь возможности принудить доверенный код передать определенные параметры защищенному коду или получить результаты от защищенного кода.
Интерфейсы и LinkDemand
Если виртуальный метод, свойство или событие с проверкой LinkDemand переопределяет метод базового класса, то к методу базового класса тоже должна применяться проверка LinkDemand, чтобы обеспечить эффективность переопределенного метода. Вредоносный код может привести тип обратно к базовому и вызвать метод базового класса. Кроме того, имейте в виду, что проверки LinkDemand могут неявно добавляться к сборкам, у которых нет атрибута AllowPartiallyTrustedCallersAttribute уровня сборки.
При защите реализаций методов с помощью LinkDemand желательно использовать LinkDemand и для методов интерфейса. Используя проверки LinkDemand при работе с интерфейсами, имейте в виду следующее.
Атрибут AllowPartiallyTrustedCallersAttribute применяется также и к интерфейсам.
Можно указывать для интерфейсов проверки LinkDemand, чтобы выборочно запрещать частично доверяемому коду обращение к определенным интерфейсам, например при использовании атрибута AllowPartiallyTrustedCallersAttribute.
Если в сборке определяется интерфейс, не содержащей атрибута AllowPartiallyTrustedCallersAttribute, этот интерфейс можно реализовать для частично доверяемого класса.
Если указать LinkDemand для открытого метода класса, реализующего метод интерфейса, то LinkDemand не сработает при приведении типа к интерфейсу и вызове метода. В этом случае, поскольку осуществляется связывание с интерфейсом, LinkDemand выполняется только для интерфейса.
Для обеспечения безопасности следует принять во внимание следующее.
Явное задание проверки LinkDemand для методов интерфейсов. Убедитесь, что эти проверки LinkDemand обеспечивают ожидаемый уровень защиты. Проверьте, может ли вредоносный код использовать приведение типов, чтобы обойти проверку LinkDemand ранее описанным способом.
Виртуальные методы, для которых используются проверки LinkDemand.
Типы и реализуемые ими интерфейсы. Они должны согласованно использовать проверки LinkDemand.