Specify marshaling for P/Invoke string arguments
TypeName |
SpecifyMarshalingForPInvokeStringArguments |
CheckId |
CA2101 |
Category |
Microsoft.Globalization |
Breaking Change |
NonBreaking |
Cause
A platform invoke member allows partially trusted callers, has a string parameter, and does not explicitly marshal the string.
Rule Description
When converting from Unicode to ANSI, it is possible that not all Unicode characters can be represented in a specific ANSI code page. Best-fit mapping tries to solve this problem by substituting a character for the character that cannot be represented. Using this feature can cause a potential security vulnerability because you cannot control the character that is chosen. For example, malicious code could intentionally create a Unicode string that contains characters not found in a particular code page, which are converted to file system special characters such as '..' or '/'. Note also that security checks for special characters frequently occur before the string is converted to ANSI.
Best-fit mapping is the default for the unmanaged conversion, WChar to MByte. Unless you explicitly disable best-fit mapping, your code might contain an exploitable security vulnerability because of this issue.
How to Fix Violations
To fix a violation of this rule, explicitly marshal string data types.
When to Suppress Warnings
Do not suppress a warning from this rule.
Example
The following example shows a method that violates this rule, and then shows how to fix the violation.
using System;
using System.Runtime.InteropServices;
[assembly: System.Security.AllowPartiallyTrustedCallers()]
namespace SecurityLibrary
{
class NativeMethods
{
// Violates rule: SpecifyMarshalingForPInvokeStringArguments.
[DllImport("advapi32.dll", CharSet=CharSet.Auto)]
internal static extern int RegCreateKey(IntPtr key, String subKey, out IntPtr result);
// Satisfies rule: SpecifyMarshalingForPInvokeStringArguments.
[DllImport("advapi32.dll", CharSet = CharSet.Unicode)]
internal static extern int RegCreateKey2(IntPtr key, String subKey, out IntPtr result);
}
}