CA2138: Transparent methods must not call methods with the SuppressUnmanagedCodeSecurity attribute

Item Value
RuleId CA2138
Category Microsoft.Security
Breaking change Breaking

Cause

A security transparent method calls a method that is marked with the SuppressUnmanagedCodeSecurityAttribute attribute.

Note

This rule has been deprecated. For more information, see Deprecated rules.

Rule description

This rule fires on any transparent method that calls directly into native code, for example, by using a P/Invoke (platform invoke) call. P/Invoke and COM interop methods that are marked with the SuppressUnmanagedCodeSecurityAttribute attribute result in a LinkDemand being done against the calling method. Because security transparent code cannot satisfy LinkDemands, the code also cannot call methods that are marked with the SuppressUnmanagedCodeSecurity attribute, or methods of class that is marked with SuppressUnmanagedCodeSecurity attribute. The method will fail, or the demand will be converted to a full demand.

Violations of this rule lead to a MethodAccessException in the Level 2 security transparency model, and a full demand for UnmanagedCode in the Level 1 transparency model.

How to fix violations

To fix a violation of this rule, remove the SuppressUnmanagedCodeSecurityAttribute attribute and mark the method with the SecurityCriticalAttribute or the SecuritySafeCriticalAttribute attribute.

When to suppress warnings

Do not suppress a warning from this rule.

Example

using System;
using System.Runtime.InteropServices;
using System.Security;


namespace TransparencyWarningsDemo
{

    public class CallSuppressUnmanagedCodeSecurityClass
    {
        [SuppressUnmanagedCodeSecurity]
        [DllImport("kernel32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool Beep(uint dwFreq, uint dwDuration);

        public void CallNativeMethod()
        {
            // CA2138 violation - transparent method calling a method marked with SuppressUnmanagedCodeSecurity
            // (this is also a CA2149 violation as well, since this is a P/Invoke and not an interface call).
            Beep(10000, 1);
        }
    }

}