Code Access Security


All managed code is subject to code access security permission demands. Many of the issues are only apparent when your code is used in a partial trust environment, when either your code or the calling code is not granted full trust by code access security policy.

For more information about the issues raised in this section, see Chapter 8, "Code Access Security in Practice."

Use the following review points to check that you are using code access security appropriately and safely:

  • Do you support partial-trust callers ?

  • Do you restrict access to public types and members ?

  • Do you use declarative security?

  • Do you call Assert?

  • Do you use permission demands when you should?

  • Do you use link demands?

  • Do you use Deny or PermitOnly?

  • Do you use particularly dangerous permissions?

  • Do you compile with the /unsafe option?

Do You Support Partial-Trust Callers?

If your code supports partial-trust callers, it has even greater potential to be attacked and as a result it is particularly important to perform extensive and thorough code reviews. Review the <trust> level configuration setting in your Web application to see if it runs at a partial-trust level. If it does, the assemblies you develop for the application need to support partial-trust callers.

The following questions help you to identify potentially vulnerable areas:

  • Is your assembly strong named?

    If it is, then default security policy ensures that it cannot be called by partially trusted callers. The Common Language Runtime (CLR) issues an implicit link demand for full trust. If your assembly is not strong named, it can be called by any code unless you take explicit steps to limit the callers, for example by explicitly demanding full trust.

    Note  

    Strong named assemblies called by ASP.NET applications must be installed in the Global Assembly Cache.

  • Do you use APTCA?

    If your strong named assembly contains AllowPartiallyTrustedCallersAttribute , partially trusted callers can call your code. In this situation, check that any resource access or other privileged operation performed by your assembly is authorized and protected with other code access security demands. If you use the .NET Framework class library to access resources, full stack walking demands are automatically issued and will authorize calling code unless your code has used an Assert call to prevent the stack walk.

  • Do you hand out object references?

    Check method returns and ref parameters to see where your code returns object references. Check that your partial-trust code does not hand out references to objects obtained from assemblies that require full-trust callers.

Do You Restrict Access to Public Types and Members?

You can use code access security identity demands to limit access to public types and members. This is a useful way of reducing the attack surface of your assembly.

  • Do you restrict callers by using identity demands?

    If you have classes or structures that you only intend to be used within a specific application by specific assemblies, you can use an identity demand to limit the range of callers. For example, you can use a demand with a StrongNameIdentityPermission to restrict the caller to a specific set of assemblies that have a have been signed with a private key that corresponds to the public key in the demand.

  • Do you use inheritance demands to restrict subclasses?

    If you know that only specific code should inherit from a base class, check that the class uses an inheritance demand with a StrongNameIdentityPermission .

Do You Use Declarative Security Attributes?

Declarative security attributes can be displayed with tools such as Permview.exe. This greatly helps the consumers and administrators of your assemblies to understand the security requirements of your code.

  • Do you request minimum permissions?

    Search for ".RequestMinimum" strings to see if your code uses permission requests to specify its minimum permission requirements. You should do this to clearly document the permission requirements of your assembly.

  • Do you request optional or refuse permissions?

    Search for ".RequestOptional" and ".RequestRefuse" strings. If you use either of these two actions to develop least privileged code, be aware that your code can no longer call strong named assemblies unless they are marked with the AllowPartiallyTrustedCallersAttribute .

  • Do you use imperative security instead of declarative security?

    Sometime imperative checks in code are necessary because you need to apply logic to determine which permission to demand or because you need a runtime variable in the demand. If you do not need specific logic, consider using declarative security to document the permission requirements of your assembly.

  • Do you mix class and member level attributes?

    Do not do this. Member attributes, for example on methods or properties, replace class-level attributes with the same security action and do not combine with them.

Do You Call Assert?

Scan your code for Assert calls. This may turn up instances of Debug.Assert . Look for where your code calls Assert on a CodeAccessPermission object. When you assert a code access permission, you short-circuit the code access security permission demand stack walk, which is a risky practice. What steps does your code take to ensure that malicious callers do not take advantage of the assertion to access a secured resource or privileged operation? Review the following questions:

  • Do you use the demand, assert pattern?

    Check that your code issues a Demand prior to the Assert . Code should demand a more granular permission to authorize callers prior to asserting a broader permission such as the unmanaged code permission.

  • Do you match Assert calls with RevertAssert?

    Check that each call to Assert is matched with a call to RevertAssert . The Assert is implicitly removed when the method that calls Assert returns, but it is good practice to explicitly call RevertAssert , as soon as possible after the Assert call.

  • Do you reduce the assert duration?

    Check that you only assert a permission for the minimum required length of time. For example, if you need to use an Assert call just while you call another method, check that you make a call to RevertAssert immediately after the method call.

Do You Use Permission Demands When You Should?

Your code is always subject to permission demand checks from the .NET Framework class library, but if your code uses explicit permission demands, check that this is done appropriately. Search your code for the ".Demand" string to identity declarative and imperative permission demands, and then review the following questions:

  • Do you cache data?

    If so, check whether or not the code issues an appropriate permission demand prior to accessing the cached data. For example, if the data is obtained from a file, and you want to ensure that the calling code is authorized to access the file from where you populated the cache, demand a FileIOPermission prior to accessing the cached data.

  • Do you expose custom resources or privileged operations?

    If your code exposes a custom resource or privileged operation through unmanaged code, check that it issues an appropriate permission demand, which might be a built-in permission type or a custom permission type depending on the nature of the resource.

  • Do you demand soon enough?

    Check that you issue a permission demand prior to accessing the resource or performing the privileged operation. Do not access the resource and then authorize the caller.

  • Do you issue redundant demands?

    Code that uses the .NET Framework class libraries is subject to permission demands. Your code does not need to issue the same demand. This results in a duplicated and wasteful stack walk.

Do You Use Link Demands?

Link demands, unlike regular demands, only check the immediate caller. They do not perform a full stack walk, and as a result, code that uses link demands is subject to luring attacks. For information on Luring Attacks, see "Link Demands" in Chapter 8, "Code Access Security in Practice."

Search your code for the ".LinkDemand" string to identify where link demands are used. They can only be used declaratively . An example is shown in the following code fragment:

 [StrongNameIdentityPermission(SecurityAction.LinkDemand,                                 PublicKey="00240000048...97e85d098615")] public static void SomeOperation() {} 

For more information about the issues raised in this section, see "Link Demands" in Chapter 8, "Code Access Security in Practice." The following questions help you to review the use of link demands in your code:

  • Why are you using a link demand?

    A defensive approach is to avoid link demands as far as possible. Do not use them just to improve performance and to eliminate full stack walks. Compared to the costs of other Web application performance issues such as network latency and database access, the cost of the stack walk is small. Link demands are only safe if you know and can limit which code can call your code.

  • Do you trust your callers?

    When you use a link demand, you rely on the caller to prevent a luring attack. Link demands are safe only if you know and can limit the exact set of direct callers into your code, and you can trust those callers to authorize their callers.

  • Do you call code that is protected with link demands?

    If so, does your code provide authorization by demanding a security permission from the callers of your code? Can the arguments passed to your methods pass through to the code that you call? If so, can they maliciously influence the code you call?

  • Have you used link demands at the method and class level?

    When you add link demands to a method, it overrides the link demand on the class. Check that the method also includes class-level link demands.

  • Do you use link demands on classes that are not sealed?

    Link demands are not inherited by derived types and are not used when an overridden method is called on the derived type. If you override a method that needs to be protected with a link demand, apply the link demand to the overridden method.

  • Do you use a link demand to protect a structure?

    Link demands do not prevent the construction of a structure by an untrusted caller. This is because default constructors are not automatically generated for structures, and therefore the structure level link demand only applies if you use an explicit constructor.

  • Do you use explicit interfaces?

    Search for the Interface keyword to find out. If so, check if the method implementations are marked with link demands. If they are, check that the interface definitions contain the same link demands. Otherwise, it is possible for a caller to bypass the link demand.

Do You Use Potentially Dangerous Permissions?

Check that the following permission types are only granted to highly trusted code. Most of them do not have their own dedicated permission type, but use the generic SecurityPermission type. You should closely scrutinize code that uses these types to ensure that the risk is minimized. Also, you must have a very good reason to use these permissions.

Table 21.3: Dangerous Permissions

Permission

Description

SecurityPermission.UnmanagedCode

Code can call unmanaged code.

SecurityPermission.SkipVerification

The code in the assembly no longer has to be verified as type safe.

SecurityPermission.ControlEvidence

The code can provide its own evidence for use by security policy evaluation.

SecurityPermission.ControlPolicy

Code can view and alter policy.

SecurityPermission.SerializationFormatter

Code can use serialization.

SecurityPermission.ControlPrincipal

Code can manipulate the principal object used for authorization.

ReflectionPermission.MemberAccess

Code can invoke private members of a type through reflection.

SecurityPermission.ControlAppDomain

Code can create new application domains.

SecurityPermission.ControlDomainPolicy

Code can change domain policy.

Do You Compile With the /unsafe Option?

Use Visual Studio .NET to check the project properties to see whether Allow Unsafe Code Blocks is set to true . This sets the /unsafe compiler flag, which tells the compiler that the code contains unsafe blocks and requests that a minimum SkipVerification permission is placed in the assembly.

If you compiled with /unsafe , review why you need to do so. If the reason is legitimate , take extra care to review the source code for potential vulnerabilities.




Improving Web Application Security. Threats and Countermeasures
Improving Web Application Security: Threats and Countermeasures
ISBN: 0735618429
EAN: 2147483647
Year: 2003
Pages: 613

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net