調用非託管代碼的安全(轉自互聯網)

Unmanaged Code
Some library code will need to call into unmanaged code (for example, native code APIs, such as Win32). Because that means going outside the security perimeter for managed code, due caution is required. If your code is security neutral (see the Security-Neutral Code section of this document), both your code and any code that calls it must have unmanaged code permission (SecurityPermission.UnmanagedCode).

However, it will often be unreasonable to require your caller to have such powerful permissions. In such cases, your trusted code can be the go-between, similar to the managed wrapper or library code described previously. If the underlying unmanaged code functionality is totally safe, it can be directly exposed; otherwise, a suitable permission check (demand) is required first.

When your code calls into unmanaged code but you do not want your callers to have that permission, you must assert your right. An assertion blocks the stack walk at your frame. You must be scrupulously careful that you do not create a security hole in this process. Usually this means that you must demand a suitable permission of your callers and then use only unmanaged code to perform what that permission allows and no more. In some cases (for example, get time of day), unmanaged code can be directly exposed to callers without any security checks. In any case, any code that asserts must take responsibility for security.

Because any managed code that affords a code path into native code is a potential target for malicious code, determining which unmanaged code can be safely used and how it must be used requires extreme care. Generally, no unmanaged code should ever be directly exposed to partially trusted callers (see the following section). There are two primary considerations in evaluating the safety of unmanaged code use in libraries that are callable by partially trusted code:

Functionality. Does the unmanaged API provide safe functionality that does not allow potentially dangerous operations to be performed by calling it? Code access security uses permissions to enforce access to resources, so consider whether the API uses files, user interface, threading, or exposes protected information. If it does, the managed code wrapping it must demand the necessary permissions before allowing it to be entered. Additionally, while not protected by a permission, security requires that memory access be confined to strict type safety.
Parameter checking. A common attack passes unexpected parameters to exposed unmanaged code API methods in an attempt to cause them to operate out of specification. Buffer overruns are one common example of this type of attack (using out of range index or offset values), or any parameters that might exploit a bug in the underlying code. Thus, even if the unmanaged code API is functionally safe for partially trusted callers (after necessary demands), managed code must also check parameter validity exhaustively to ensure that no unintended calls are possible from malicious code using the managed code wrapper layer.
Using SuppressUnmanagedCodeSecurity
There is a performance aspect to asserting and then calling unmanaged code. For every such call, the security system automatically demands unmanaged code permission, resulting in a stack walk each time. If you assert and immediately call unmanaged code, the stack walk can be meaningless: it consists of your assert and your unmanaged code call.

A custom attribute called SuppressUnmanagedCodeSecurity can be applied to unmanaged code entry points to disable the normal security check that demands SecurityPermission.UnmanagedCode. Extreme caution must always be taken when doing this because this action creates an open door into unmanaged code with no runtime security checks. It should be noted that even with SuppressUnmanagedCodeSecurity applied, there is a one-time security check that happens at JIT time to ensure that the immediate caller has permission to call unmanaged code.

If you use the SuppressUnmanagedCodeSecurity attribute, check the following points:

Make the unmanaged code entry point inaccessible outside your code (for example, "internal").
Any place you call into unmanaged code is a potential security hole. Make sure your code is not a portal for malicious code to indirectly call into unmanaged code and avoid a security check. Demand permissions, if appropriate.
Use a naming convention to make it explicit when you are creating a dangerous path into unmanaged code, as described in the next section.
Naming Convention for Unmanaged Code Methods
A useful and highly recommended convention has been established for naming unmanaged code methods. All unmanaged code methods are separated into three categories: safe, native, and unsafe. These keywords can be used as class names within which the various kinds of unmanaged code entry points are defined. In source code these keywords should be added to the class name; for example, Safe.GetTimeOfDay or Native.Xyz or Unsafe.DangerousAPI. Each of these categories should send a strong message to the developers using them as described in the following table.

Keyword Security considerations
safe Completely harmless for any code (even malicious) to call. Can be used just like other managed code. Example: get time of day.
native Security neutral; that is, unmanaged code that requires unmanaged code permission to call. Security is checked, which stops an unauthorized caller.
unsafe Potentially dangerous unmanaged code entry point with security suppressed. Developers should use the greatest caution when using such unsafe code, making sure that other protections are in place to avoid a security vulnerability. Developers must be responsible as this keyword overrides the security system.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章