Enum SecurityAction
#[repr(u16)]pub enum SecurityAction {
Show 18 variants
Deny = 1,
Demand = 2,
Assert = 3,
NonCasDemand = 4,
LinkDemand = 5,
InheritanceDemand = 6,
RequestMinimum = 7,
RequestOptional = 8,
RequestRefuse = 9,
PrejitGrant = 10,
PrejitDeny = 11,
NonCasLinkDemand = 12,
NonCasInheritance = 13,
LinkDemandChoice = 14,
InheritanceDemandChoice = 15,
DemandChoice = 16,
PermitOnly = 17,
Unknown(u16),
}Expand description
Security actions that control when and how permissions are enforced in .NET assemblies.
Security actions define the enforcement semantics for declarative security attributes.
Each action specifies when the CLR should check permissions and what happens when
permission checks fail. These correspond directly to the SecurityAction enumeration
in the .NET Framework and ECMA-335 specifications.
§Action Categories
§Runtime Actions
Actions that are checked during code execution:
Demand: Check all callers in the call stackAssert: Skip permission checks for the asserted permissionDeny: Block access to the specified resourcePermitOnly: Allow only the specified permissions
§Link-Time Actions
Actions that are checked during JIT compilation:
LinkDemand: Check the immediate caller onlyInheritanceDemand: Check classes that inherit or override
§Assembly Request Actions (Legacy)
Actions used for assembly-level permission requests (obsolete in modern .NET):
RequestMinimum: Minimum required permissionsRequestOptional: Optional permissions to grantRequestRefuse: Permissions to refuse
§Examples
use dotscope::metadata::security::SecurityAction;
// Check if an action is runtime-enforced
fn is_runtime_action(action: SecurityAction) -> bool {
matches!(action,
SecurityAction::Demand |
SecurityAction::Assert |
SecurityAction::Deny |
SecurityAction::PermitOnly
)
}
// Check if an action is security-sensitive
fn is_security_sensitive(action: SecurityAction) -> bool {
matches!(action,
SecurityAction::Assert | // Can bypass security
SecurityAction::Deny | // Can block access
SecurityAction::PermitOnly // Can restrict permissions
)
}§.NET Framework Evolution
- .NET 1.0-3.5: All actions supported with full CAS enforcement
- .NET 4.0: Security transparency model, some actions deprecated
- .NET Core/5+: Most actions become no-ops, kept for compatibility
§ECMA-335 References
- Partition II, Section 23.1.16: Security action enumeration values
- Partition II, Section 22.11:
DeclSecuritytable structure - Partition I, Section 10: Security model overview
§Binary Representation
Security actions are stored as 16-bit unsigned integers in .NET metadata. The numeric values are defined by ECMA-335 and must remain stable for compatibility.
Variants§
Deny = 1
Denies access to the specified resources, overriding any grants.
When a Deny action is encountered, the CLR will refuse any demands for the specified permissions, regardless of whether the code has been granted those permissions. This is used to restrict access even when code would normally have the required permissions.
§Security Implications
- Overrides permission grants, creating a “security hole” prevention mechanism
- Useful for restricting untrusted code or creating security boundaries
- Can prevent code from accessing sensitive resources even if granted permission
§Example Usage
[FileIOPermission(SecurityAction.Deny, Read = @"C:\Sensitive")]
public void RestrictedMethod() {
// This method cannot read from C:\Sensitive even if normally allowed
}Demand = 2
Demands that all callers in the call chain have the specified permission.
This action causes the CLR to perform a stack walk, checking that every caller
in the call chain has been granted the specified permission. If any caller
lacks the permission, a SecurityException is thrown.
§Security Implications
- Most common security action for runtime permission checks
- Ensures all code in the call stack is trusted for the operation
- Can impact performance due to stack walking
§Example Usage
[FileIOPermission(SecurityAction.Demand, Read = @"C:\Data")]
public void ReadSensitiveFile() {
// All callers must have read permission for C:\Data
}Assert = 3
Asserts that the specified permission should be granted without further checks.
When code asserts a permission, subsequent demands for that permission will succeed without performing a stack walk beyond the asserting frame. This effectively “shields” callers from needing the asserted permission.
§Security Implications
- Bypasses normal security checks, creating potential security risks
- Should only be used by highly trusted code
- Can create privilege escalation if misused
- Requires
SecurityPermissionwithAssertionflag to use
§Example Usage
[FileIOPermission(SecurityAction.Assert, Read = @"C:\SystemData")]
public void TrustedSystemOperation() {
// This method can read system data regardless of caller permissions
}NonCasDemand = 4
Demands that the current assembly has been granted the specified permission.
This action checks that the currently executing assembly has the required permission, but does not perform a stack walk to check callers. It is used for permissions that are not part of the Code Access Security (CAS) system.
§Security Implications
- Only checks the immediate assembly, not the entire call stack
- Used for permissions outside the traditional CAS model
- Less expensive than full stack walking demands
§Example Usage
[MyCustomPermission(SecurityAction.NonCasDemand, Value = "required")]
public void NonCasSecuredMethod() {
// Only this assembly needs the custom permission
}LinkDemand = 5
Demands that the immediate caller has been granted the specified permission.
Link demands are checked at JIT compilation time rather than runtime. They verify that the immediate caller (not the entire call stack) has the required permission. This provides security with better performance than runtime demands.
§Security Implications
- Checked at JIT time, not runtime, for better performance
- Only checks immediate caller, potentially less secure than full stack walk
- Can be bypassed by reflection in some scenarios
§Example Usage
[FileIOPermission(SecurityAction.LinkDemand, Unrestricted = true)]
public void FileOperationMethod() {
// Immediate caller must have unrestricted file access
}InheritanceDemand = 6
Demands that classes inheriting from or overriding this method have the specified permission.
This action ensures that any code that derives from a class or overrides a method has the required permission. It is checked when the derived class is loaded or when the override is JIT compiled.
§Security Implications
- Protects against malicious inheritance or method overriding
- Checked at class loading or method compilation time
- Ensures derived classes maintain security requirements
§Example Usage
[SecurityPermission(SecurityAction.InheritanceDemand, ControlPrincipal = true)]
public virtual void SecuritySensitiveMethod() {
// Classes inheriting this must have ControlPrincipal permission
}RequestMinimum = 7
Specifies the minimum permissions required for the assembly to run (legacy).
This action was used in early .NET versions to specify the minimum set of permissions that an assembly required to function. It is now obsolete and ignored in modern .NET implementations, but remains for compatibility with older assemblies.
§Legacy Status
- Obsolete in .NET Framework 4.0 and later
- Ignored by modern .NET runtimes
- Maintained for compatibility with older assemblies
§Example Usage (Legacy)
[assembly: FileIOPermission(SecurityAction.RequestMinimum, Unrestricted = true)]
// Assembly requests minimum file I/O permissionsRequestOptional = 8
Specifies optional permissions that would be beneficial for the assembly (legacy).
This action was used to specify permissions that an assembly could use if available,
but could function without. Like RequestMinimum, it is now obsolete and ignored
in modern .NET implementations.
§Legacy Status
- Obsolete in .NET Framework 4.0 and later
- Ignored by modern .NET runtimes
- Assembly would receive these permissions if security policy allowed
§Example Usage (Legacy)
[assembly: RegistryPermission(SecurityAction.RequestOptional, Unrestricted = true)]
// Assembly would like registry access if possibleRequestRefuse = 9
Specifies permissions that the assembly explicitly refuses (legacy).
This action was used to specify permissions that an assembly explicitly did not want to be granted, even if security policy would normally grant them. This provided a way for assemblies to limit their own privileges.
§Legacy Status
- Obsolete in .NET Framework 4.0 and later
- Ignored by modern .NET runtimes
- Was used for defense-in-depth security practices
§Example Usage (Legacy)
[assembly: FileIOPermission(SecurityAction.RequestRefuse, Unrestricted = true)]
// Assembly explicitly refuses all file I/O permissionsPrejitGrant = 10
Reserved for pre-JIT compilation grants (implementation-specific).
This action is used internally by the .NET runtime during ahead-of-time (AOT) compilation scenarios. It is not intended for use in user code and represents permissions that should be granted during pre-compilation.
§Implementation Details
- Used internally by runtime pre-compilation systems
- Not for use in application code
- Related to Native Image Generator (ngen.exe) and similar tools
PrejitDeny = 11
Reserved for pre-JIT compilation denials (implementation-specific).
This action is used internally by the .NET runtime during ahead-of-time (AOT) compilation scenarios. It represents permissions that should be denied during pre-compilation.
§Implementation Details
- Used internally by runtime pre-compilation systems
- Not for use in application code
- Related to Native Image Generator (ngen.exe) and similar tools
NonCasLinkDemand = 12
Link-time demand for non-CAS permissions.
Similar to LinkDemand, but for permissions that are not part of the traditional
Code Access Security system. This provides JIT-time checking for custom permission
types while maintaining the performance benefits of link-time verification.
§Security Implications
- JIT-time checking for better performance
- Only checks immediate caller
- Used for custom permission types outside CAS
§Example Usage
[MyCustomPermission(SecurityAction.NonCasLinkDemand, Level = "High")]
public void CustomSecuredMethod() {
// Immediate caller needs custom permission at JIT time
}NonCasInheritance = 13
Inheritance demand for non-CAS permissions.
Similar to InheritanceDemand, but for permissions that are not part of the
traditional Code Access Security system. This ensures that classes inheriting
from or overriding this code have the required custom permissions.
§Security Implications
- Protects inheritance chains with custom permissions
- Checked at class loading or method compilation time
- Used for custom permission types outside CAS
§Example Usage
[MyCustomPermission(SecurityAction.NonCasInheritance, Level = "High")]
public virtual void InheritanceProtectedMethod() {
// Derived classes need custom permission
}LinkDemandChoice = 14
Choice-based link demand for transparent code in .NET 4.0 security model.
This action is part of the .NET 4.0 security transparency model, where it allows transparent code to specify link demands. The “choice” aspect relates to the transparency model’s approach to security decisions.
§.NET 4.0 Security Transparency
- Used in security-transparent assemblies
- Part of the simplified security model introduced in .NET 4.0
- Allows transparent code to participate in security decisions
§Example Usage
[FileIOPermission(SecurityAction.LinkDemandChoice, Unrestricted = true)]
public void TransparentLinkDemand() {
// Transparent code can specify link demands
}InheritanceDemandChoice = 15
Choice-based inheritance demand for transparent code in .NET 4.0 security model.
This action allows security-transparent code to specify inheritance demands as part of the .NET 4.0 security transparency model. It provides a way for transparent code to control inheritance security requirements.
§.NET 4.0 Security Transparency
- Used in security-transparent assemblies
- Allows transparent code to control inheritance security
- Part of the simplified security model
§Example Usage
[SecurityPermission(SecurityAction.InheritanceDemandChoice, ControlPrincipal = true)]
public virtual void TransparentInheritanceDemand() {
// Transparent code can specify inheritance demands
}DemandChoice = 16
Choice-based demand for transparent code in .NET 4.0 security model.
This action allows security-transparent code to specify runtime demands as part of the .NET 4.0 security transparency model. It enables transparent code to participate in runtime security decisions with explicit choice semantics.
§.NET 4.0 Security Transparency
- Used in security-transparent assemblies
- Allows transparent code to make runtime security demands
- Part of the choice-based security model
§Example Usage
[FileIOPermission(SecurityAction.DemandChoice, Read = @"C:\Data")]
public void TransparentDemand() {
// Transparent code can specify runtime demands
}PermitOnly = 17
Restricts code to only the specified permissions, denying all others.
When a PermitOnly action is encountered, the CLR restricts the code to only
the permissions specified, effectively denying all other permissions even if
they were previously granted. This creates a privilege restriction mechanism.
§Security Implications
- Reduces the effective permission set of code
- Useful for creating security boundaries within trusted code
- Can prevent code from using permissions it was granted
- Complements
Denyby allowing only specific permissions
§Example Usage
[FileIOPermission(SecurityAction.PermitOnly, Read = @"C:\SafeData")]
public void RestrictedFileOperation() {
// This method can only read from C:\SafeData, no other file operations
}Unknown(u16)
Unknown security action.
Trait Implementations§
§impl Clone for SecurityAction
impl Clone for SecurityAction
§fn clone(&self) -> SecurityAction
fn clone(&self) -> SecurityAction
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreimpl Copy for SecurityAction
§impl Debug for SecurityAction
impl Debug for SecurityAction
§impl Display for SecurityAction
impl Display for SecurityAction
impl Eq for SecurityAction
§impl From<SecurityAction> for u16
impl From<SecurityAction> for u16
§fn from(action: SecurityAction) -> Self
fn from(action: SecurityAction) -> Self
§impl From<u16> for SecurityAction
impl From<u16> for SecurityAction
§impl PartialEq for SecurityAction
impl PartialEq for SecurityAction
impl StructuralPartialEq for SecurityAction
Auto Trait Implementations§
impl Freeze for SecurityAction
impl RefUnwindSafe for SecurityAction
impl Send for SecurityAction
impl Sync for SecurityAction
impl Unpin for SecurityAction
impl UnsafeUnpin for SecurityAction
impl UnwindSafe for SecurityAction
Blanket Implementations§
impl<T> Boilerplate for T
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Downcast for T
impl<T> Downcast for T
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.impl<T> ErasedDestructor for Twhere
T: 'static,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<F, T> IntoSample<T> for Fwhere
T: FromSample<F>,
impl<F, T> IntoSample<T> for Fwhere
T: FromSample<F>,
fn into_sample(self) -> T
Source§impl<T> Pointable for T
impl<T> Pointable for T
Source§impl<T> PolicyExt for Twhere
T: ?Sized,
impl<T> PolicyExt for Twhere
T: ?Sized,
impl<T> Read<Exclusive, BecauseExclusive> for Twhere
T: ?Sized,
impl<T> Scalar for T
Source§impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
Source§fn to_subset(&self) -> Option<SS>
fn to_subset(&self) -> Option<SS>
self from the equivalent element of its
superset. Read moreSource§fn is_in_subset(&self) -> bool
fn is_in_subset(&self) -> bool
self is actually part of its subset T (and can be converted to it).Source§fn to_subset_unchecked(&self) -> SS
fn to_subset_unchecked(&self) -> SS
self.to_subset but without any property checks. Always succeeds.Source§fn from_subset(element: &SS) -> SP
fn from_subset(element: &SS) -> SP
self to the equivalent element of its superset.Source§impl<T> ToCompactString for Twhere
T: Display,
impl<T> ToCompactString for Twhere
T: Display,
Source§fn try_to_compact_string(&self) -> Result<CompactString, ToCompactStringError>
fn try_to_compact_string(&self) -> Result<CompactString, ToCompactStringError>
ToCompactString::to_compact_string() Read moreSource§fn to_compact_string(&self) -> CompactString
fn to_compact_string(&self) -> CompactString
CompactString. Read more