1.1.1. ContributorsMy thanks to the following for their assistance with this article:Alan Danziger, Mark Curphey, Alan Faber, Elias Levy, Tony Northrup

1.2. OverviewA number of general comparative articles have been written discussing the pros and cons ofthese two competing technological platforms. The intention of this paper is to discuss J2EE and.Net at a high level from a security perspective, examining the tools and methodologies theplatforms use to provide secure development and deployment environments.

This introduction section covers a brief, incomplete discussion of key features of both platforms.It will not discuss areas that are not analogous between platforms. For more information on both,see the references section of this document.

Note that .Net is a product platform, whereas J2EE is a standard specification, which isimplemented to varying degrees of fidelity by a number of vendors. For this reason, directcomparisons may be difficult in certain areas without going into vendor specifics.

For the purposes of this article no real distinction is made between .Net and the .Net Framework,which forms one part of the .Net strategy.

While Microsoft is pushing .Net as their strategy for Web Services, this document will not discussthe two platforms from the point of view of Web Services, nor does it describe COM+, as this isnot part of the .Net Framework.

1.3. What is .NET made of?The .Net initiative, a significant undertaking by Microsoft, is an attempt to tie togetherapplications, development languages, operating systems and data stores into a unified,distributed enterprise platform.

The .Net Framework is a reworking of Windows DNA, Microsoft’s previous enterprisedevelopment platform, consisting of the CLR(Common Language Runtime), base classes andpresentation through ASP.Net. .Net is tightly integrated into the Windows OS environment (with.Net support integrated into all of Microsoft’s enterprise applications), but the portability presentedby the CLR/CLS (Common Language Specification)/CTS (Common Type Specification)combination means that if Microsoft wanted, .Net could be implemented on other platforms.

1.3.1. C#C# is an object-oriented language, derived from C++, and syntactically similar (with someexceptions) to the Java language. C# is a “brand new” language, and may suffer fromteething troubles as a result. While it is not a part of the .Net framework, it is a part of the.Net strategy, and mirrors Java’s function within J2EE.

1.3.2. Common Language Runtime (CLR)All .Net components are compiled into an interim language called Intermediate Language(IL), which is then executed in the runtime environment provided by the CLR. A growingnumber of compilers for languages such as C#, Visual Basic.Net, C++, etc. are availablefor use with .Net, giving programmers the ability to work in .Net using familiar languages.The CLR is part of the core of the .Net Framework, providing a secure executionenvironment through the principles of what Microsoft describes as managed code and codeaccess security. The CLR also provides housekeeping functionality through garbagecollection.

1.3.3. ASP. NetASP.Net is an onward progression from ASP (Active Server Pages). Differences from ASPinclude programmatical changes and the fact that ASP.Net pages are now compiled andexecuted in a CLR.

1.3.4. ADO.NetADO.Net is the successor to Microsoft’s ActiveX Data Objects (ADO). Whereas ADOprovided two-dimensional access to data, through the use of rows and columns, ADO.Netdescribes data as objects and utilises XML for transmitting data between application tiers.

1.3.5. AssembliesAn assembly is a collection of code used as the building block of a .Net frameworkdeployment. Assemblies are designed to include security information (in terms ofpermissions requested and strong name), versioning information (which enables multipleversions of software to co-exist on a single system, theoretically eliminating DLL conflicts),code and supporting resources. Assemblies can be built using the Visual Studio.Net IDEand the Assembly Generation Tool.

1.4. What is J2EE made of?J2EE is Sun’s reference standard for enterprise development, first introduced in December 1999,and now at version 1.3. Core elements of J2EE are described in this section.

1.4.1. Java languageJava is an object-oriented language derived from C++, with features that simplify codingsuch as memory management through garbage collection, no pointers, etc. Java isdesigned to be “Write once, run anywhere”, this goal being achieved through the use ofportable bytecode.1.4.2. JVM/JREThe JRE (Java Runtime Environment) consists of the Java Virtual Machine, a just-in-timecompiler and some foundation classes. Java classes are compiled into platform-independent bytecode that is executed in the JVM.1.4.3. JSPs and ServletsJava Server Pages (JSPs) are analogous to ASP technology, providing the capability tobuild dynamic web pages composed of HTML with embedded dynamic components, e.g.references to Beans.Servlets are described as applets that run on the web server, and are used where CGIwould traditionally have been employed to build dynamic web applications.1.4.4. EJBEnterprise Java Beans (EJB) are used to build distributed applications by providing thecommunications and execution framework for distributed components. Critical servicesprovided by an EJB container include transaction management, security, resourcemanagement and persistence.1.4.5. JDBCJava Database Connectivity (JDBC) is an API for connecting to relational databases,manipulating their contents, and processing the output of issued SQL statements.Numerous database vendors have developed drivers based on the JDBC API.

2. Security ModelsEnterprise development requires that security targets be met for the development anddeployment of code. Development platforms and runtime environments must provide forauthentication and authorisation, data integrity, audit trails, non-repudiation and privacy of data.

The responsibilities for these tasks are spread across multiple platform elements in a typical n-tierapplication architecture. This section will attempt to discuss the approaches taken by .Net andJ2EE, focussing mainly on the runtime environments.

2.1. .NET Framework security architectureThe CLR and base classes are responsible in large part for security functions within the .Netframework. The CLR uses a number of criteria to determine the security permissions of code tobe executed, and obtains some security information from XML configuration files.

The base classes control access to resources such as the file system by determining thepermissions of the caller.

.Net’s two primary security functions are described in the following sections.2.1.1. Code access securityCode access security is a core part of the CLR’s security function. Code access securitydetermines the level of trust assigned to a piece of code based on its origins, publisher andother factors. Some key concepts used to define code access security are describedbelow.

2.1.1.1. Evidence-based security.Net uses the concept of “Evidence-based security”, to describe the process by whichassemblies are examined by the CLR at runtime. The CLR queries assemblies using thefollowing primary criteria:• Where did this code originate?• Who created this assembly?

The first question can be broken out into “Which URL did the assembly originate from?”and “Which zone did the assembly originate from?”. Microsoft uses the concept of zonesto describe security environments like the Internet, local networks or intranets, the localmachine, etc.Evidence can also be in the form of a digital certificate signed by the publisher of theassembly or the strong name (a unique identifier, consisting of a text name, digitalsignature, and a public key) of the assembly.

The second question is reasonably straightforward – “What information is available on thecreator of this assembly?”.

The evidence gathered is included as part of an assembly’s metadata. Metadata caninclude information on types, relationships with other assemblies, security permissionsrequested as well as a description of the assembly. Metadata is examined by the CLR atvarious points, including by the verifier, which ensures that types are correct prior tocompilation of IL to native code. The verifier is also responsible for ensuring that themetadata associated with an assembly is valid.

The CLR examines the metadata to establish an identity for the assembly and determinesthe permissions allocated to the assembly based on the security policy.

2.1.1.2. PermissionsPermissions within the CLR are the building blocks of access control. A code accesspermission in this context is the right of a piece of code to access a particular resource orperform a particular operation. When assemblies are built, the permissions that it requiresto run can be included as part of its description.

At runtime the assembly requests these permissions, and those permissions that itrequests are either granted or denied by the CLR. An assembly will never be given greaterpermissions than the current security policy allows, but may be given lesser permissionsthan it requests.

Examples of permissions are SecurityPermission (the permission to view or modify thesecurity policy), UIPermission (the right to create sub-windows and make use of theclipboard) and the RegistryPermission class (which gives access to Windows Registrydetails).

Permissions can be grouped into permission sets for ease of administration. Thesepermission sets are then associated with code groups, which are described in the nextsection. Examples of permission sets are Nothing (no permissions at all, so code cannotexecute), Internet (the permissions assigned to untrusted code) and Everything (the set ofpermissions that grants all standard permissions, with the exception of avoiding codeverification).

At runtime, the CLR performs what is known as a stack walk to determine whether thecalling assembly has permission to access a particular resource, checking requestedpermissions against granted permissions for each caller on the stack.

If an assembly’s request for access to a resource is denied, a SecurityException is thrown.

2.1.1.3. Security PolicyThe security policy is administered using the Code Access Security Policy Tool(Caspol.exe) or the .Net Framework configuration tool. Administrators set the policy forassemblies and application domains, the CLR uses the evidence described above toidentify an assembly, and then uses the security policy to determine the permissions theassembly has at runtime.

The policy identifies code by organising code into groups that categorise based on theevidentiary information described, such as the zone from which the code is loaded. If noother information is available, the default policy for the zone from which the code wasobtained will be used to determine the permissions that an assembly has.

2.1.2. Role-based securityUser membership in a role within a .Net application helps to determine the access that theuser has to perform particular operations and access resources. For example, in the caseof a financial application, a Broker role might have permission to initiate, authorise andcancel trades on behalf of an individual or financial institution.

Role-based security describes the means by which the .Net framework identifies,authenticates and authorises an individual user from any of a number of authoritativesources. When a user is identified, their authenticated identity (and role membership) isdenoted by the term principal. A principal can be a member of one or more roles; forexample, an individual could be a member of a Broker and an Executive role.

Role-based security employs a permission structure similar to that of code access security,with permissions managed through the PrincipalPermission object.

Authentication and authorisation sources for users can be through Windows machinesecurity, domain security or some custom authentication source.2.1.3. Programmatic security.Net uses the IsInRole method to determine whether a user belongs to a particular role.For example, to determine if a user has membership of a Broker role, the following couldbe used :If User.IsInRole(“Broker”)‘ Permit requested functionElse‘ Bounce back to loginEnd If

The classes responsible for the determination of principal identity are stored in theSystem.Security.Principal namespace.2.2. J2EE security architectureThe J2EE security architecture is defined as part of the platform specification document. It detailssecurity management roles, and specifies goals of the security architecture, but does not specifysecurity policy or implementation details (such as the use of a particular security technology tomeet the described goals).

2.2.1. Code management through the JVM and the class file verifier, the classloader and the Security ManagerBasic Java security employs the concept of a “sandbox” to limit the abilities of untrustedcode to cause damage to the system on which it runs. Historically, an untrusted piece ofcode such as an applet would be disallowed from accessing local disk, opening networkconnections, etc. With the introduction of certificate support through the Java Plug-In, theorigin and author of a signed applet could be established definitively, enabling fine-grainedpermissions to be assigned to individual applets based on the security policy. This meansthat applets are no longer confined to the default sandbox.

As described in the coming paragraphs, the sandbox is implemented through the JVM andits class verifier, but also through the class loader and the Security Manager/ACL manager.

The JVM’s class file verifier examines classes for basic class file structure upon loading.While bytecodes produced by Sun’s compiler should be relatively free of errors (typeerrors, for example), it is possible for an attacker to manually create malicious bytecode.The class file verifier examines each loaded class file in four passes; from the most basiccheck, where the physical attributes of the file are checked (size, magic number, length ofattributes) to checking the constant pool to ensure that method and field references havecorrect attributes, to parsing the instructions for each method. Note that, by default, theonly trusted classes are the base classes. All other classes, including those loaded fromthe application classpath are considered untrusted and must be verified.

2.2.1.2. The Class Loader architectureThere are two types of class loader – the primordial class loader, which is a part of theJVM, and class loader objects, which are used to load non-essential classes.There can only be one primordial class loader, which is used to bootstrap the JVM byloading the base classes, sometimes using native OS-dependent means.There can be many instances of class loader objects in the JVM, which can be instantiatedon the fly, and used to load objects from sources such as the network, local disk, or datastores. Controlling the creation of class loader objects is therefore important due to thefunction of the class loader.

Class loaders are responsible for locating classes requested by the JVM for loading intothe runtime environment. Part of their responsibility is to prevent unauthorised or untrustedcode from replacing trusted code that makes up the base classes. As an example, a classloader should prevent the replacement of the Security Manager class. The attemptedreplacement of a base class by a maliciously coded class is referred to as class spoofing.

All class loaders, with the exception of the primordial class loader, are loaded by otherclass loaders, which become the loaded class loader’s parent. Thus, the loading of classloaders describes a tree structure with the primordial class loader at the root and classesas the leaf nodes (obviously class loaders are themselves classes).

If a class loader loads a class, all subsequent requests for related classes are directedthrough that class loader. For example, if a class loader ”A” loads a class “Building”, and“Building” makes calls to methods in a class called “Cubicle”, the JVM will use class loader“A” to load “Cubicle” and any other classes that are referred to by “Building”.

Class loaders prevent class spoofing by passing requests back up the tree through theirparent class loader until the class loader that loaded the requested class is reached. In thecase of the Security Manager class, the primordial class loader is responsible, andconsequently the malicious class described above will not be loaded. Classes are loadedonly once, and the base classes are only loaded from the local disk using the systemclasspath.

Class loaders also provide security by managing namespaces. A class that is loaded by aparticular class loader can only reference other classes in the same namespace, i.e.,loaded by the same class loader or its parents.

2.2.1.3. The Security Manager and Access ControllerThe Security Manager was responsible for examining and implementing the security policy,which is specified by policy files. The security policy, as with .Net, determines thepermissions that code has at runtime.

In more recent versions of Java, the decisions on whether to grant permissions based onsecurity policy are delegated to the Access Controller. When a class makes a request forpermissions, it is received by the Security Manager which passes the request to theAccess Controller.

In a similar fashion to the way that .Net groups permissions into permission sets, which itthen associates with code groups, permissions in the Java world are grouped intoprotection domains, associated with code sources. In other words, groups of permissionsare associated with groups of classes, the classes being grouped by their origin.

Signed Java code is assigned permissions based on the system policy as applied to thecode’s protection domain. Depending on the permissions associated with the source of thecode, the applet may have full access to system resources, or may be restricted to a smallsubset.Java applications, by default, have no associated security manager, and therefore have fullaccess to system resources.

2.2.2. Platform RolesThe J2EE platform specification describes Organisational or Platform Roles that can beused to divide up responsibilities in a J2EE development and deployment cycle. The Rolesdescribed in the platform specification are Product Provider, Application ComponentProvider, Application Assembler, Deployer and Systems Administrator. These Roles arenot absolutes – the responsibilities of the various roles could be divided differently to fit acompany’s development and deployment methodologies.

Of these roles, most have clear security implications. The Product Provider andApplication Component Provider roles are responsible for developing secure code, theAssembler is responsible for defining method permissions and security roles, the Deployerverifies the security view of the deployed application and assigns principals to roles, andthe Systems Administrator administers principals and ensures that the local securityenvironment is correct for the J2EE platform.

2.2.3. Security Roles and the Deployment DescriptorThe deployment descriptor is an XML file that ships with each EJB1, and describesdeclaratively many of the aspects of the EJB’s function and makeup, and its relationshipwith other beans.

One of the elements in the descriptor is the <security-role-ref> element. This element typeis used by the bean developer to define all of the security roles used in the EJB code.Security role names are associated with links, which are then called elsewhere in thedescriptor.

The <security-role> element is used to call roles described in the <security-role-ref>elements. For example:...<security-role-ref><role-name>root</role-name><role-link>super-user</role-link></security-role-ref>..<security-role><description>This is the security-role for the role “root”, defined above</description><role-name>super-user</role-name></security-role>

1Deployment descriptors can also be used with other Java components (e.g. Apache SOAP deploymentdecriptors) but every EJB is required to have a deployment descriptor.The description field in the <security-role> descriptor element is optional.

Membership of a role confers a set of permissions for the duration of the role membership.Principals can be in several roles at the same time, e.g. employee and manager.

Method permissions are also described in the deployment descriptor.

2.2.4. Programmatic securityRole membership can be determined programmatically in the J2EE environment using theisUserInRole and getUserPrincipal methods of the HTTPServletRequest object for the webcontainer.

As part of the bean-container contract, the container provides the EJBContext object. Thecorresponding EJBContext methods are isCallerInRole and getCallerPrincipal.getCallerPrincipal returns the principal associated with the security context, while,predictably enough, isCallerInRole is a boolean method used to determine whether thecaller belongs to a specified security role.

2.3. Cryptography support

2.3.1. .NETThe .Net base classes provide support for encryption, key generation, hashing andmessage authentication. Supported algorithms include DES, SHA, AES(Rijndael), RC2,etc.The .Net Framework provides a number of tools for certificate management andmanipulation.makecert.exe can be used to create X.509 certificates for testing purposes, certmgr.exe(Certificate Manager) is used to manage X.509 certificates, trust lists and revocation lists,and secutil.exe can be used to extract public key information for a certificate from anassembly.

2.3.2. J2EEJCE (Java Cryptography Extension) is a collection of packages that provides support forencryption, key exchange and MAC algorithms. JCE is an optional package for J2SDK1.3, but has been integrated into v1.4. While the J2SDK includes some cryptographyfunctions, the JCE separates out much of the functionality due to US Government exportrestrictions. The JCE uses the concept of CSPs (Cryptographic Service Providers) to plugin different encryption algorithm implementations.

Another set of add-on encryption packages for J2SDK 1.3 that are being integrated intov1.4 is JSSE, the Java Secure Sockets Extension, providing SSL and TLS functionality toJava developers.

3. ConclusionJ2EE and .Net both provide quite comprehensive security services, though with a different focus.Authentication and authorisation services in .Net are provided through Microsoft OSes andidentification repositories. J2EE, on the other hand, does not specify which methods oridentification stores should be used to perform these functions, leaving these decisions up tovendors and developers. Although its use is not mandated, authentication and authorisationfunctionality is provided by Sun through JAAS (Java Authentication and Authorisation Service),which is based on PAM.

Both platforms use similar concepts for handling user and code access to resources, withpermissions being key to both, and the concept of roles being used to associate permissions withprinicipals in both environments.

While J2EE uses the concept of Organisational Roles to delineate responsibilities at variousstages of the development and deployment process, .Net does not define the hierarchy asclearly.

While .Net provides a solid security model through managed code in the CLR, the ability to rununmanaged code confers the ability to bypass CLR security through direct calls to the underlyingOS APIs. In the Java world, signed, trusted code has unrestricted access to system resources.Java calling out to native (C/C++) code through JNI confers the ability to bypass the JRE’ssecurity as surely as running unmanaged code in the CLR can be used to bypass.Net’s security.

The reliance on Microsoft-specific identification stores such as Passport or Windows domains forauthentication and authorisation purposes means that .Net applications may require end-users tosubscribe to Microsoft’s Passport service. As an example of why this might be a “bad thing”,Microsoft had to temporarily shut down part of its Passport service during November 2001 due toa security issue. Current copyright restrictions prevent non-Microsoft vendors from providingalternatives, forcing .NET application developers to rely upon a single vendor for back-endservices. Concern at this stance in the wider developer and Internet communities has resulted inprojects like DotGNU and Project Liberty. DotGNU is an FSF (Free Software Foundation)initiative to provide an open-source implementation of the .Net framework, and a non-vendorcontrolled Passport alternative (Virtual Identities), which is intended to use encryption whereverpossible to protect user details. Project Liberty is an alliance whose members include Sun, AOL,Vodafone, American Express, HP and RSA, to name but a few, with the stated aim of creating afederated single-sign-on scheme allowing authentication and authorisation from any type ofnetwork connected device.

Java has also had its share of security problems in the past, especially in the area of certainJREs and malicious applets; problems have also been reported in the class loading process, afundamental part of JVM security, as described above.

One of the crucial challenges for both Microsoft and J2EE vendors when developing theirrespective platforms is securely handling code obtained from multiple sources, outside of thelocal machine. The code verification functions of the JVM are quite mature at this stage andmistakes made in the past have been learned from. The CLR model is similar, but theimplementation is relatively untested. It will be interesting to see how the .Net environmentstands the test of time from a security perspective, once .Net deployments become morewidespread.