楼主: Sky-Tiger

Java vs. .NET Security

[复制链接]
论坛徽章:
350
2006年度最佳版主
日期:2007-01-24 12:56:49NBA大富翁
日期:2008-04-21 22:57:29地主之星
日期:2008-11-17 19:37:352008年度最佳版主
日期:2009-03-26 09:33:53股神
日期:2009-04-01 10:05:56NBA季后赛大富翁
日期:2009-06-16 11:48:01NBA季后赛大富翁
日期:2009-06-16 11:48:01ITPUB年度最佳版主
日期:2011-04-08 18:37:09ITPUB年度最佳版主
日期:2011-12-28 15:24:18ITPUB年度最佳技术原创精华奖
日期:2012-03-13 17:12:05
31#
 楼主| 发表于 2009-2-11 20:56 | 只看该作者
Code Protection: Non-Cryptographic
Once a piece of software's origin and integrity have been established, non-cryptographic approaches may be used to ensure that the code can not be used in an unintended manner. In particular, this implies that the platform's package- and class-protection mechanisms cannot be subverted by illegally joining those packages or using class derivation to gain access to protected or internal members. These types of protection are generally used to supplement CAS and aimed at preventing unauthorized execution or source code exposure.

Reflection mechanisms on both platforms allow for easy programmatic access to code details and very late binding of arbitrary code, or even utilize code generation capabilities -- see, for instance,.NET technology samples, or the Java Reflection tutorial. One common example of such a threat would be a spyware application, which secretly opens installed applications and inspects/executes their functionality in addition to its officially advertised function. To prevent such code abuse, granting reflection permissions (System.Security.Permissions.ReflectionPermission in .NET, java.lang.reflect.ReflectPermission in Java) in CAS policy should be done sparingly and only to highly trusted code, in order to restrict capabilities for unauthorized code inspection and execution.

In .NET, application modules are called assemblies, and located at runtime by a so-called probing algorithm. By default, this algorithm searches for dependent assemblies only in the main assembly's directory, its subdirectories, and the Global Assembly Cache (GAC). Such a design is used to guard against possible attempts to access code outside of the assembly's "home." Note that it does not prevent loading and executing external assemblies via reflection, so CAS permissions should be applied as well.

Types in .NET are organized into namespaces. One may extend an already established namespace in his own assemblies, but will not gain any additional information by doing so, since the keyword internal is applied at the assembly, and not namespace, level. Strong names are used as a cryptographically strong measure against replacement of the existing types.

If the designer wants to completely prohibit inheritance from a class or method overloading, the class or method may be declared sealed. As an additional means of protection against source browsing, the C# language defines a #line hidden directive to protect against stepping into the code with a debugger. This directive instructs the compiler to avoid generating debugging information for the affected area of code.

During execution of a Java application, class loaders are responsible for checking at loading/verification time that the loaded class is not going to violate any package protection rules (i.e., does not try to join a sealed or protected package). Particular attention is paid to the integrity of system classes in java.* packages — starting with version 1.3, the class-loading delegation model ensures that these are always loaded by the null, or primordial class loader (see "Secure Class Loading" for details).

The Java platform defines the following options for protecting packages from joining:

Sealed JAR files

These are used to prevent other classes from "joining" a package inside of that JAR, and thus obtaining access to the protected members. A package, com.MyCompany.MyPackage.*, may be sealed by adding a Sealed entry for that package to the JAR manifest file before signing it:

Name: com/MyCompany/MyPackage/
Sealed: true
Configuration restrictions for joining packages

These can be used to control which classes can be added to a restricted package by adding them to the java.security file. Note that none of Sun-supplied class loaders performs this check (due to historical reasons), which means that this protection is only effective with a custom class loader installed:

# List of comma-separated packages that start
# with or equal this string will cause a security
# exception to be thrown when passed to
# checkPackageDefinition unless the corresponding
# RuntimePermission ("defineClassInPackage."+package)
# has been granted.

#

# by default, no packages are restricted for
# definition, and none of the class loaders
# supplied with the JDK call checkPackageDefinition.

package.definition=com.MyCompany.MyPackage.private
Configuration restrictions for accessing packages

If SecurityManager is installed, it checks the package-access policies defined in java.security file. A package can have restricted access so that only classes with appropriate permissions can access it. For instance, all sun.* packages are restricted in the default installation:

# List of comma-separated packages that start
# with or equal this string will cause a security
# exception to be thrown when passed to
# checkPackageAccess unless the corresponding
# RuntimePermission ("accessClassInPackage."+package)
# has been granted.

package.access=sun.
A sample Java application, demonstrating declarative access control to packages, can be obtained here.

Note: Configuration options in Java add a convenient method for declarative code protection, which gives it a slight edge over .NET in this category.

使用道具 举报

回复
论坛徽章:
350
2006年度最佳版主
日期:2007-01-24 12:56:49NBA大富翁
日期:2008-04-21 22:57:29地主之星
日期:2008-11-17 19:37:352008年度最佳版主
日期:2009-03-26 09:33:53股神
日期:2009-04-01 10:05:56NBA季后赛大富翁
日期:2009-06-16 11:48:01NBA季后赛大富翁
日期:2009-06-16 11:48:01ITPUB年度最佳版主
日期:2011-04-08 18:37:09ITPUB年度最佳版主
日期:2011-12-28 15:24:18ITPUB年度最佳技术原创精华奖
日期:2012-03-13 17:12:05
32#
 楼主| 发表于 2009-2-11 20:57 | 只看该作者
Code Access Security: Permissions
Code-access permissions represent authorization to access a protected resource or perform a dangerous operation, and form a foundation of CAS. They have to be explicitly requested from the caller either by the system or by application code, and their presence or absence determines the appropriate course of action.




Both Java and .NET supply an ample choice of permissions for a variety of system operations. The runtime systems carry out appropriate checks when a resource is accessed or an operation is requested. Additionally, both platforms provide the ability to augment those standard permission sets with custom permissions for protection of application-specific resources. Once developed, custom permissions have to be explicitly checked for (demanded) by the application's code, because the platform's libraries are not going to check for them.

.NET defines a richer selection here, providing permissions for role-based checks (to be covered in the "User Access Security" section of Part 4) and evidence-based checks. An interesting feature of the latter is the family of Identity permissions, which are used to identify an assembly by one of its traits -- for instance, its strong name (StrongNameIdentityPermission). Also, some of its permissions reflect close binding between the .NET platform and the underlying Windows OS (EventLogPermission, RegistryPermission). IsolatedStoragePermission is unique to .NET, and it allows low-trust code (Internet controls, for instance) to save and load a persistent state without revealing details of a computer's file and directory structure. Refer to MSDN documentation for the list of .NET Code Access and Identity permissions.

Adding a custom code access permission requires several steps. Note that if a custom permission is not designed for code access, it will not trigger a stack walk. The steps are:

Optionally, inherit from CodeAccessPermission (to trigger a stack walk).
Implement IPermission and IUnrestrictedPermission.
Optionally, implement ISerializable.
Implement XML encoding and decoding.
Optionally, add declarative security support through an Attribute class.
Add the new permission to CAS Policy by assigning it to a code group.
Make the permission's assembly trusted by .NET framework.
A sample of custom code-access permission can be found in the demo application. Also, check MSDN for additional examples of building and registering a custom permission with declarative support.

.NET permissions are grouped into NamedPermissionSets. The platform includes the following non-modifiable built-in sets: Nothing, Execution, FullTrust, Internet, LocalIntranet, SkipVerification. The FullTrust set is a special case, as it declares that this code does not have any restrictions and passes any permission check, even for custom permissions. By default, all local code (found in the local computer directories) is granted this privilege.

The above fixed permission sets can be demanded instead of regular permissions:

[assembly:PermissionSetAttribute(
         SecurityAction.RequestMinimum,
         Name="LocalIntranet")]
In addition to those, custom permission sets may be defined, and a built-in Everything set can be modified. However, imperative code-access checks cannot be applied to varying permission sets (i.e., custom ones and Everything). This restriction is present because they may represent different permissions at different times, and .NET does not support dynamic policies, as it would require re-evaluation of the granted permissions.

Permissions, defined in Java, cover all important system features: file access, socket, display, reflection, security policy, etc. While the list is not as exhaustive as in .NET, it is complete enough to protect the underlying system from the ill-behaving code. See the JDK documentation for the complete list, and the Java permissions guide for more detailed discussions of their meaning and associated risks.

Developing a custom permission in Java is not a complicated process at all. The following steps are required:

Extend java.security.Permission or java.security.BasicPermission.
Add new permission to the JVM's policy by creating a grant entry.
Obviously, the custom permission's class or JAR file must be in the CLASSPATH (or in one of the standard JVM directories), so that JVM can locate it.

Below is a simple example of defining a custom permission. More examples can be found in the demo application or in the Java tutorial:

//permission class
public class CustomResPermission extends Permission {
  public CustomResPermission (String name,
                            String action) {
  super(name,action);
  }
}

//library class
public class AccessCustomResource {
  public String getCustomRes() {
    SecurityManager mgr =
         System.getSecurityManager();
    if (mgr == null) {
          //shouldn't run without security!!!
          throw new SecurityException();
    } else {
          //see if read access to the resource
          //was granted
          mgr.checkPermission(
        new CustomResPermission("ResAccess","read"));
    }
   //access the resource here
   String res = "Resource";
   return res;
  }
}

//client class
public class CustomResourceClient {
  public void useCustomRes() {
    AccessCustomResource accessor =
     new AccessCustomResource();
    try {
      //assuming a SecurityManager has been
      //installed earlier
      String res = accessor.getCustomRes();
    } catch(SecurityException ex) {
      //insufficient access rights
    }
  }
}
J2EE reuses Java's permissions mechanism for code-access security. Its specification defines a minimal subset of permissions, the so-called J2EE Security Permissions Set (see section 6.2 of the J2EE.1.4 specification). This is the minimal subset of permissions that a J2EE-compliant application might expect from a J2EE container (i.e., the application does not attempt to call functions requiring other permissions). Of course, it is up to individual vendors to extend it, and most commercially available J2EE application servers allow for much more extensive application security sets.

Note: .NET defines a richer sets-based permission structure than Java. At the same time, .NET permissions reveal their binding to the Windows OS.

使用道具 举报

回复
论坛徽章:
350
2006年度最佳版主
日期:2007-01-24 12:56:49NBA大富翁
日期:2008-04-21 22:57:29地主之星
日期:2008-11-17 19:37:352008年度最佳版主
日期:2009-03-26 09:33:53股神
日期:2009-04-01 10:05:56NBA季后赛大富翁
日期:2009-06-16 11:48:01NBA季后赛大富翁
日期:2009-06-16 11:48:01ITPUB年度最佳版主
日期:2011-04-08 18:37:09ITPUB年度最佳版主
日期:2011-12-28 15:24:18ITPUB年度最佳技术原创精华奖
日期:2012-03-13 17:12:05
33#
 楼主| 发表于 2009-2-11 20:57 | 只看该作者
Code Access Security: Policies
Code Access Security is evidence-based. Each application carries some evidence about its origin: location, signer, etc. This evidence can be discovered either by examining the application itself, or by a trusted entity: a class loader or a trusted host. Note that some forms of evidence are weaker than others, and, correspondingly, should be less trusted -- for instance, URL evidence, which can be susceptible to a number of attacks. Publisher evidence, on the other hand, is PKI-based and very robust, and it is not a likely target of an attack, unless the publisher's key has been compromised. A policy, maintained by a system administrator, groups applications based on their evidence, and assigns appropriate permissions to each group of applications.

Evidence for the .NET platform consists of various assembly properties. The set of assembly evidences, which CLR can obtain, defines its group memberships. Usually, each evidence corresponds to a unique MembershipCondition, which are represented by .NET classes. See MSDN for the complete listing of standard conditions. They all represent types of evidence acceptable by CLR. For completeness, here is the list of the standard evidences for the initial release: AppDirectory, Hash, Publisher, Site, Strong Name, URL, and Zone.

.NET's policy is hierarchical: it groups all applications into so-called Code Groups. An application is placed into a group by matching its Membership Condition (one per code group) with the evidence about the application's assembly. Those conditions are either derived from the evidence or custom-defined. Each group is assigned one of the pre-defined (standard or custom) NamedPermissionSet. Since an assembly can possess more than one type of evidence, it can be a member of multiple code groups. In this case, its total permission set will be a union of the sets from all groups (of a particular level) for which this assembly qualifies. Figure 3 depicts code-group hierarchy in the default machine policy (also see MSDN):


Figure 3. NET Default Code Groups
Custom groups may be added under any existing group (there is always a single root). Properly choosing the parent is an important task, because due to its hierarchical nature, the policy is navigated top-down, and the search never reaches a descendent node if its parents' MembershipCondition was not satisfied. In Figure 3 above, the Microsoft and ECMA nodes are not evaluated at all for non-local assemblies.

090205gregor_t1.gif (22.22 KB, 下载次数: 6)

090205gregor_t1.gif

使用道具 举报

回复
论坛徽章:
350
2006年度最佳版主
日期:2007-01-24 12:56:49NBA大富翁
日期:2008-04-21 22:57:29地主之星
日期:2008-11-17 19:37:352008年度最佳版主
日期:2009-03-26 09:33:53股神
日期:2009-04-01 10:05:56NBA季后赛大富翁
日期:2009-06-16 11:48:01NBA季后赛大富翁
日期:2009-06-16 11:48:01ITPUB年度最佳版主
日期:2011-04-08 18:37:09ITPUB年度最佳版主
日期:2011-12-28 15:24:18ITPUB年度最佳技术原创精华奖
日期:2012-03-13 17:12:05
34#
 楼主| 发表于 2009-2-11 20:57 | 只看该作者
Custom groups may be added under any existing group (there is always a single root). Properly choosing the parent is an important task, because due to its hierarchical nature, the policy is navigated top-down, and the search never reaches a descendent node if its parents' MembershipCondition was not satisfied. In Figure 3 above, the Microsoft and ECMA nodes are not evaluated at all for non-local assemblies.

Built-in nodes can be modified or even deleted, but this should be done with care, as this may lead to the system's destabilization. Zones, identifying code, are defined by Windows and managed from Internet Explorer, which allows adding to or removing whole sites or directories from the groups. All code in non-local groups have special access rights back to the originating site, and assemblies from the intranet zone can also access their originating directory shares.

To add a custom code group using an existing NamedPermissionSet with an associated MembershipCondition, one only needs to run the caspol.exe tool. Note that this tool operates on groups' ordinal numbers rather than names:

caspol -addgroup 1.3 -site
   www.MySite.com LocalIntranet
Actually, .NET has three independent policies, called Levels: Enterprise, Machine, and User. As a rule, a majority of the configuration process takes place on the Machine level — the other two levels grant FullTrust to everybody by default. An application can be a member of several groups on each level, depending on its evidence. As a minimum, all assemblies are member of the AllCode root group.

Policy traversal is performed in the following order: Enterprise, Machine, and then User, and from the top down. On each level, granted permission sets are determined as follows:

Level Set = Set1 U Set2 U ... U SetN
where 1..N - code groups matching assembly's evidence. System configuration determines whether union or intersection operation is used on the sets.

The final set of permissions is calculated as follows:

Final Set = Enterprise X Machine X User
Effectively, this is the least common denominator of all involved sets. However, the traversal order can be altered by using Exclusive and LevelFinal policy attributes. The former allows stopping intra-level traversal for an assembly; the latter, inter-level traversal. For instance, this can be used to ensure, on the Enterprise level, that a particular assembly always has enough rights to execute.

使用道具 举报

回复
论坛徽章:
350
2006年度最佳版主
日期:2007-01-24 12:56:49NBA大富翁
日期:2008-04-21 22:57:29地主之星
日期:2008-11-17 19:37:352008年度最佳版主
日期:2009-03-26 09:33:53股神
日期:2009-04-01 10:05:56NBA季后赛大富翁
日期:2009-06-16 11:48:01NBA季后赛大富翁
日期:2009-06-16 11:48:01ITPUB年度最佳版主
日期:2011-04-08 18:37:09ITPUB年度最佳版主
日期:2011-12-28 15:24:18ITPUB年度最佳技术原创精华奖
日期:2012-03-13 17:12:05
35#
 楼主| 发表于 2009-2-11 20:58 | 只看该作者
This demo application demonstrates the tasks involved in granting custom permissions in the policy and executing code that requires those permissions.

Each policy maintains a special list of assemblies, called trusted assemblies -- they have FullTrust for that policy level. Those assemblies are either part of CLR, or are specified in the CLR configuration entries, so CLR will try to use them. They all must have strong names, and have to be placed into the Global Assembly Cache (GAC) and explicitly added to the policy (GAC can be found in the %WINDIR%\assembly directory):

gacutil /i MyGreatAssembly.dll

caspol -user -addfulltrust MyGreatAssembly.dll
Figure 4 shows the Machine-level trusted assemblies:


Figure 4. NET Trusted Assemblies
For Java, two types of code evidence are accepted by the JVM -- codebase (URL, either web or local), from where it is accessed, and signer (effectively, the publisher of the code). Both evidences are optional: if omitted, all code is implied. Again, publisher evidence is more reliable, as it less prone to attacks. However, up until JDK 1.2.1, there was a bug in the SecurityManager's implementation that allowed replacing classes in a signed JAR file and then continuing to execute it, thus effectively stealing the signer's permissions.

Policy links together permissions and evidence by assigning proper rights to code, grouped by similar criteria. A JVM can use multiple policy files; two are defined in the default java.security:

policy.url.1=file:${java.home}/lib/security/java.policy

policy.url.2=file:${user.home}/.java.policy

090205gregor_t1.gif (15.17 KB, 下载次数: 4)

090205gregor_t1.gif

使用道具 举报

回复
论坛徽章:
350
2006年度最佳版主
日期:2007-01-24 12:56:49NBA大富翁
日期:2008-04-21 22:57:29地主之星
日期:2008-11-17 19:37:352008年度最佳版主
日期:2009-03-26 09:33:53股神
日期:2009-04-01 10:05:56NBA季后赛大富翁
日期:2009-06-16 11:48:01NBA季后赛大富翁
日期:2009-06-16 11:48:01ITPUB年度最佳版主
日期:2011-04-08 18:37:09ITPUB年度最佳版主
日期:2011-12-28 15:24:18ITPUB年度最佳技术原创精华奖
日期:2012-03-13 17:12:05
36#
 楼主| 发表于 2009-2-11 20:58 | 只看该作者
Policy links together permissions and evidence by assigning proper rights to code, grouped by similar criteria. A JVM can use multiple policy files; two are defined in the default java.security:

policy.url.1=file:${java.home}/lib/security/java.policy

policy.url.2=file:${user.home}/.java.policy
This structure allows creating multi-level policy sets: network, machine, user. The resulting policy is computed as follows: Policy = Policy.1 U Policy.2 U ... U Policy.N JVM uses an extremely flexible approach to providing policy: the default setting can be overwritten by specifying a command-line parameter to the JVM:

//adds MyPolicyFile to the list of policies

java -Djava.security.policy=MyPolicyFile.txt

// replaces the existing policy with MyPolicyFile

java -Djava.security.policy==MyPolicyFile.txt
Java policy has a flat structure: it is a series of grant statements, optionally followed by evidence, and a list of granted permissions. A piece of code may satisfy more than one clause's condition — the final set of granted permissions is a union of all matches:

grant [signedBy "signer1", ..., "signerN"] [codeBase "URL"] {

        permission <PermissionClassName> "TargetName", "Action"
            [signedBy "signer1", ..., "signerN"];
        ...

}
This demo application defines a custom permission in the policy and executes applications requiring that permission.

Even locally installed classes are granted different trust levels, depending on their location:

Boot classpath: $JAVA_HOME/lib, $JAVA_HOME/classes

These classes automatically have the full trust and no security restrictions. Boot classpath can be changed both for compilation and runtime, using command-line parameters: -bootclasspath and -Xbootclasspath, respectively.

Extensions: $JAVA_HOME/lib/ext

Any code (JAR or class files) in that directory is given full trust in the default java.policy:

grant codeBase "file:{java.home}/lib/ext/*" {
        permission java.security.AllPermission;
}
Standard classpath: $CLASSPATH ("." by default)

By default, have only few permissions to establish certain network connections and read environment properties. Again, the SecurityManager has to be installed (either from command line using the -Djava.security.manager switch, or by calling System.setSecurityManager) in order to execute those permissions.

Policy-based security causes problems for applets. It's unlikely that a web site's users will be editing their policy files before accessing a site. Java does not allow runtime modification to the policy, so the code writers (especially applets) simply cannot obtain the required execution permissions. IE and Netscape have incompatible (with Sun's JVM, too!) approaches to handling applet security. JavaSoft's Java plug-in is supposed to solve this problem by providing a common JRE, instead of the browser-provided VM.

If the applet code needs to step outside of the sandbox, the policy file has to be edited anyway, unless it is an RSA-signed applet. Those applets will either be given full trust (with user's blessing, or course), or if policy has an entry for the signer, it will be used. The following clause in the policy file will always prevent granting full trust to any RSA-signed applet:

grant {
  permission java.lang.RuntimePermission "usePolicy";
}
Note: Policy in .NET has a much more sophisticated structure than in Java, and it also works with many more types of evidences. Java defines very flexible approach to adding and overriding default policies -- something that .NET lacks completely.

使用道具 举报

回复
论坛徽章:
350
2006年度最佳版主
日期:2007-01-24 12:56:49NBA大富翁
日期:2008-04-21 22:57:29地主之星
日期:2008-11-17 19:37:352008年度最佳版主
日期:2009-03-26 09:33:53股神
日期:2009-04-01 10:05:56NBA季后赛大富翁
日期:2009-06-16 11:48:01NBA季后赛大富翁
日期:2009-06-16 11:48:01ITPUB年度最佳版主
日期:2011-04-08 18:37:09ITPUB年度最佳版主
日期:2011-12-28 15:24:18ITPUB年度最佳技术原创精华奖
日期:2012-03-13 17:12:05
37#
 楼主| 发表于 2009-2-11 20:58 | 只看该作者
Code Access Security: Access Checks
Code access checks are performed explicitly; the code (either an application, or a system library acting on its behalf) calls the appropriate Security Manager to verify that the application has the required permissions to perform an operation. This check results in an operation known as a stack walk: the Runtime verifies that each caller up the call tree has the required permissions to execute the requested operation. This operation is aimed to protect against a luring attack, where a privileged component is misled by a caller into executing dangerous operations on its behalf. When a stack walk is performed prior to executing an operation, the system can detect that the caller is not allowed to do what it is requesting, and abort the execution with an exception.




Privileged code may be used to deal with luring attacks without compromising overall system security, and yet provide useful functionality. Normally, the most restrictive set of permissions for all of the code on the current thread stack determines the effective permission set. To bypass this restriction, a special permission can be assigned to a small portion of code to perform a reduced set of restricted actions on behalf of under-trusted callers. All of the clients can now access the protected resource in a safe manner using that privileged component, without compromising security. For instance, an application may be using fonts, which requires opening font files in protected system areas. Only trusted code has to be given permissions for file I/O, but any caller, even without this permission, can safely access the component itself and use fonts.

Finally, one has to keep in mind that code access security mechanisms of both platforms sit on top of the corresponding OS access controls, which are usually role or identity-based. So, for example, even if Java/.NET's access control allows a particular component to read all of the files on the system drive, the requests might still be denied at the OS level.

A .NET assembly has a choice of using either imperative or declarative checks (demands) for individual permissions. Declarative (attribute) checks have the added benefit of being stored in metadata, and thus are available for analyzing and reporting by .NET tools like permview.exe. In either case, the check results in a stack walk. Declarative checks can be used from an assembly down to an individual properties level.

//this declaration demands FullTrust
//from the caller of this assembly

[assembly:PermissionSetAttribute(
  SecurityAction.RequestMinimum,
  Name = "FullTrust")]


//An example of a declarative permission
//demand on a method

[CustomPermissionAttribute(SecurityAction.Demand,
  Unrestricted = true)]
public static string ReadData()
{ //Read from a custom resource. }


//Performing the same check imperatively

public static void ReadData()
{
  CustomPermission MyPermission = new
    CustomPermission(PermissionState.Unrestricted);
  MyPermission.Demand();
  //Read from a custom resource.
}

使用道具 举报

回复
论坛徽章:
350
2006年度最佳版主
日期:2007-01-24 12:56:49NBA大富翁
日期:2008-04-21 22:57:29地主之星
日期:2008-11-17 19:37:352008年度最佳版主
日期:2009-03-26 09:33:53股神
日期:2009-04-01 10:05:56NBA季后赛大富翁
日期:2009-06-16 11:48:01NBA季后赛大富翁
日期:2009-06-16 11:48:01ITPUB年度最佳版主
日期:2011-04-08 18:37:09ITPUB年度最佳版主
日期:2011-12-28 15:24:18ITPUB年度最佳技术原创精华奖
日期:2012-03-13 17:12:05
38#
 楼主| 发表于 2009-2-11 20:58 | 只看该作者
In addition to ordinary code access checks, an application can declaratively specify LinkDemand or InheritanceDemand actions, which allow a type to require that anybody trying to reference it or inherit from it possess particular permission(s). The former applies to the immediate requestor only, while the latter applies to all inheritance chain. Presence of those demands in the managed code triggers a check for the appropriate permission(s) at JIT time.

LinkDemand has a special application with strong-named assemblies in .NET, because such assemblies may have a higher level of trust from the user. To avoid their unintended malicious usage, .NET places an implicit LinkDemand for their callers to have been granted FullTrust; otherwise, a SecurityException is thrown during JIT compilation, when an under-privileged assembly tries to reference the strong-named assembly. The following implicit declarations are inserted by CLR:

[PermissionSet(SecurityAction.LinkDemand,
   Name="FullTrust")]

[PermissionSet(SecurityAction.InheritanceDemand,
   Name="FullTrust")]
Consequently, if a strong-named assembly is intended for use by partially trusted assemblies (i.e., from code without FullTrust), it has to be marked by a special attribute -- [assembly:AllowPartiallyTrustedCallers], which effectively removes implicit LinkDemand checks for FullTrust. All other assembly/class/method level security checks are still in place and enforceable, so it is possible that a caller may still not possess enough privileges to utilize a strong-named assembly decorated with this attribute.

.NET assemblies have an option to specify their security requirements at the assembly load time. Here, in addition to individual permissions, they can operate on one of the built-in non-modifiable PermissionSets. There are three options for those requirements: RequestMinimum, RequestOptional, and RequestRefuse.

If the Minimum requirement cannot be satisfied, the assembly will not load at all. Optional permissions may enable certain features. Application of the RequestOptional modifier limits the permission set granted to the assembly to only optional and minimal permissions (see the formula in the following paragraph). RequestRefuse explicitly deprives the assembly of certain permissions (in case they were granted) in order to minimize chances that an assembly can be tricked into doing something harmful.

//Requesting minimum assembly permissions
//The request is placed on the assembly level.

using System.Security.Permissions;
[assembly:SecurityPermissionAttribute(
   SecurityAction.RequestMinimum,
   Flags = SecurityPermissionFlag.UnmanagedCode)]
namespace MyNamespace
{
        ...
}
CLR determines the final set of assembly permissions using the granted permissions, as specified in .NET CAS policy, plus the load-time modifiers described earlier. The formula applied is (P - Policy-derived permissions): G = M + (O<<P) - R, where M and O default to P, and R to Nothing.

Applications on .NET platform may affect the stack-walking process by executing special operations on individual permissions or permission sets: Assert, Deny, PermitOnly. The application itself should be granted the affected permissions, as well as the SecurityPermission that grants the rights to make assertions.

使用道具 举报

回复
论坛徽章:
350
2006年度最佳版主
日期:2007-01-24 12:56:49NBA大富翁
日期:2008-04-21 22:57:29地主之星
日期:2008-11-17 19:37:352008年度最佳版主
日期:2009-03-26 09:33:53股神
日期:2009-04-01 10:05:56NBA季后赛大富翁
日期:2009-06-16 11:48:01NBA季后赛大富翁
日期:2009-06-16 11:48:01ITPUB年度最佳版主
日期:2011-04-08 18:37:09ITPUB年度最佳版主
日期:2011-12-28 15:24:18ITPUB年度最佳技术原创精华奖
日期:2012-03-13 17:12:05
39#
 楼主| 发表于 2009-2-11 20:59 | 只看该作者
The Assert option explicitly succeeds the stack walk (for the given PermissionSet or any subset of it, as determined by the Intersect function), even if the upstream callers do not have the required permissions (it fails if sets intersections are not empty). Deny and PermitOnly effectively restrict the available permission sets for the downstream callers.

This demo application demonstrates the effects of applying stack-walk modifications. Figure 5 represents an overview of the Code Access Security permission grants and checks in .NET:


Figure 5. NET CAS Operation
In Java, permissions are normally checked by the SecurityManager (or installed derivative), by using the checkPermission function. It defines a helper for each major group of permissions, such as checkWrite for the write action of FilePermission. All checks are imperative; there are no declarative code access checks in Java language. Each JVM can have at most one SecurityManager (or derivative) installed -- once set, they cannot be replaced, for security reasons. Browsers always start SecurityManager, so any Internet Java application executes with enabled security. Locally started JVMs have to install a SecurityManager before exercising the first sensitive operation; this can also be done programmatically:

System.setSecurityManager(new SecurityManager());
or using a command-line option:

java -Djava.security.manager MyClass
In Java 2, when determining application permissions, SecurityManager delegates the call to java.security.AccessController, which obtains current snapshot of AccessControllerContext to determine which permissions are present. SecurityManager's operations may be influenced by the java.security.DomainController implementation, if one exists. It instructs an existing SecurityManager to perform additional operations before security checks, thus allowing security system extensibility without re-implementing its core classes. JAAS uses this functionality to add principal-based security checks to the original code-based Java security (see section "User Access Security" in Part 4).

090205gregor_t1.gif (6.73 KB, 下载次数: 11)

090205gregor_t1.gif

使用道具 举报

回复
论坛徽章:
350
2006年度最佳版主
日期:2007-01-24 12:56:49NBA大富翁
日期:2008-04-21 22:57:29地主之星
日期:2008-11-17 19:37:352008年度最佳版主
日期:2009-03-26 09:33:53股神
日期:2009-04-01 10:05:56NBA季后赛大富翁
日期:2009-06-16 11:48:01NBA季后赛大富翁
日期:2009-06-16 11:48:01ITPUB年度最佳版主
日期:2011-04-08 18:37:09ITPUB年度最佳版主
日期:2011-12-28 15:24:18ITPUB年度最佳技术原创精华奖
日期:2012-03-13 17:12:05
40#
 楼主| 发表于 2009-2-11 20:59 | 只看该作者
When making access control decisions, the checkPermission method stops checking if it reaches a caller that was marked as "privileged" via a doPrivileged call without a context argument. If that caller's domain has the specified permission, no further checking is done and checkPermission returns quietly, indicating that the requested access is allowed. If that domain does not have the specified permission, an exception is thrown, as usual.

Writing privileged code in Java is achieved by implementing the java.security.PrivilegedAction or PrivilegedExceptionAction interfaces. This approach is somewhat limiting, as it does not allow specifying the exact permissions to be asserted, while still requiring the callers to possess others -- it is an "all or nothing" proposition.

public class PrivilegedClass implements PrivilegedAction {
    public Object run() {
        //perform privileged operation
        ...
        return null;
    }
}
Suppose the current thread traversed m callers, in the order of caller 1 to caller 2 to caller M, which invoked the checkPermission method. This method determines whether access is granted or denied based on the following algorithm:

i = m;
while (i > 0) {

  if (caller i's domain
      does not have the permission)
          throw AccessControlException

  else if (caller i is marked as privileged) {
          if (a context was specified
              in the call to doPrivileged)
             context.checkPermission(permission)
          return;
  }
  i = i - 1;
}

// Next, check the context inherited when
// the thread was created. Whenever a new thread
// is created, the AccessControlContext at that
// time is stored and associated with the new
// thread, as the "inherited" context.

inheritedContext.checkPermission(permission);
A complete application demonstrating privileged code in Java can be found here.

Note: .NET arms developers with an impressive arsenal of various features for access checks, easily surpassing Java in this respect.

Conclusions
In this article, code protection and Code Access Security features of Java and .NET platforms were reviewed. While code protection came out more or less even, CAS features in .NET are significantly better than the ones Java can offer, with a single exception -- flexibility. Java, as it is often the case, offers ease and configurability in policy handling that .NET cannot match.

The final article of this series, Part 4, is going to cover authentication and User Access Security (UAS) on both platforms, as well as provide overall conclusions to the series.

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 未成年人举报专区 
京ICP备16024965号-8  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表