MOBILE

Java Mobile Edition Security : Development and Security Testing (part 3) - Code Security & Application Packaging and Distribution

2/15/2011 11:43:45 AM

Code Security

All JME code is written in Java, and Java is a memory managed language that prevents buffer and integer overflows and direct manipulation of memory and the hardware. The virtual machine makes this security magic possible by verifying every instruction before execution and ensuring that all application code handles memory and objects safely. Not having to worry about memory-related security issues is a real boon to developers, but it doesn’t mean that they are free and clear. Application code can still use the network and local storage insecurely, and the virtual machine implementation itself might have problems that attackers could exploit to compromise devices. For example, Adam Gowdiak reported avulnerability in the Kilobyte Virtual Machine’s verifier that an application could use to escape the sandbox (http://secunia.com/advisories/12945/). The risk of a JVM error pales in comparison to the risk of writing every JME application in an unmanaged language such as C.

CLDC Security

The CLDC JSR specifies that JVMs implementing the CLDC configuration must only load and execute valid Java bytecode. In addition, CLDC JVMs do not support all of Java’s language features. Specifically, the CLDC 1.1 JSR says that CLDC must ensure the following:

  • Class files must be properly verified and the Java bytecode well formed. All code branches must follow predictable paths and jump to controlled memory addresses. Code verification ensures that the application is not able to execute illegal instructions.

  • Applications cannot load custom class loaders or classes of their choosing. If attackers could load their own classes, they could pull in application code without the user’s knowledge.

  • The API set exposed to applications is predefined. Therefore, applications cannot use Java reflection to dynamically load classes or access private methods. By forcing a predefined set, device manufacturers and carriers know which platform APIs are exposed and how the application will be able to access the hardware. Device manufacturers and carriers can always add to the protected set if they want to expose device model-specific functionality (for example, the camera or a digital compass).

  • Native functionality is prohibited. Java native invocation (JNI) is a technology used to bridge between native code (such as C/C++) and managed Java code. Native code executes outside of the JVM and cannot be monitored. Therefore, JME applications must be prevented from using JNI and including native extension libraries.

  • Applications cannot extend classes in the java.*, javax.microedition.*, and other manufacturer-specific packages. If malicious applications were allowed to overload sensitive system classes, they might be able to take advantage of polymorphism and force system APIs to execute attacker-supplied code when calling object methods.

  • All classes must come from the same JAR file. This requirement prevents applications from loading and using classes from other applications that may be installed on a device. This restriction may change when libraries are introduced as part of MIDP 3.0.

These restrictions aim to stop applications from running Java code that cannot be managed or accesses the hardware in unexpected way. MIDP relies on this infrastructure to build a higher level application sandbox. To enforce these restrictions, CLDC performs “class file verification” and inspects the Java bytecode to ensure that all variables are initialized, the actual instructions are legitimate, and that only valid types are used.

Pre-verification

To have an impact, the CLDC JVM security rules must actually be enforced when the code is installed and executed on the device. Pre-verification is the process that evaluates application code and creates markings that will be used by the JVM during installation or runtime verification. All Java virtual machines perform some sort of verification process, but only JME performs the verification process at compilation time—hence, the name per-verification. CLDC doesn’t actually require pre-verification to be used, but on mobile devices it is preferred over standard verification, which consumes large amounts of system resources.

Pre-verification works by scanning the application’s bytecode and generating a series of “StackMap” attributes for each code item in an application. The StackMap includes information about the local variable types being used by each basic block of the application. Once the StackMap attributes are generated, they are inserted into the attribute section of each code attribute in the application. When the application is installed onto the device, the JVM performs a linear scan of the application’s bytecode and compares references and object types to the information contained in the StackMap. The device refuses to load the application if any part of the comparison fails.

Storing StackMap entries does marginally increase the size of applications, but enables the verification algorithm to execute in linear time and with predictable resource use—important qualities for mobile devices. The algorithm is resistant to malicious tampering or manufacturing of StackMap entries, and an invalid or incomplete StackMap will cause the application to be rejected when a user loads it onto a device.

Use preverify.exe to perform pre-verification of your applications. Sun’s official reference implementation is included with the SDK and NetBeans, and both will automatically perform pre-verification as part of the build process. The ProGuard obfuscation toolset also includes an alternate implementation of the pre-verifier. To learn more about pre-verification, see Appendix 1 of the CLDC 1.1. specification.

Application Packaging and Distribution

CLDC requires that all JME application code be packaged into Java archive files. JAR is a compressed file format very similar to ZIP. Each application JAR has an associated Java Application Descriptor (JAD). The JAD file is a simple text file with a listing of key/value pairs that describe certain properties of the application (for example, the application’s author and the location of the developer’s website). The combination of the JAR and the JAD is what actually composes a JME application. This differs from standard Java applications, which do not have JAD files and keep their metadata in the JAR file. JME JARs still have metadata, but they can grow to be quite large and be prohibitive to download over slow and costly cellular links. By putting the metadata in the JAD file, which is much smaller than the JAR, mobile devices can present the user with a choice before downloading the entire application.

More on JAD Files

JAD files are an important part of the MIDP application life cycle and contain application signatures, permission listings, and other important security information. Each line in a JAD file consists of an attribute name and attribute value. A sample JAD follows:

MIDlet-1: iSEC Partners Maps, , com.isecpartners.jme.iSECNavigator
MIDlet-Jar-URL:
http://www.isecpartners.com/applications/v1/isecnav.jar
MIDlet-Jar-Size: 6479
MIDlet-Name: iSEC Maps
MIDlet-Permissions: javax.microedition.io.Connector.http
MIDlet-Icon: icon16x16.png
MIDlet-Version: 1.0.2
MIDlet-Vendor: iSEC Partners
MIDlet-Install-Notify:
http://www.isecpartners.com/applications/v1/cust

This JAD file provides the name of the application (iSEC Maps), the vendor (iSEC Partners), and the location of the actual JAR file. After the JAD is downloaded, this information will be shown to the user so they can decide whether or not to install the application. Also note that the JAD is requesting the javax.microedition.io.Connector.http permission by using the MIDlet-Permissions attribute. Phones could use this as part of a permission UI at installation time.

Most JAD attributes are defined in the MIDP JSR and the optional JAD JSRs. Vendors may define additional attributes that are unique to their device. Samsung, for example, defines the MIDlet-Touch-Support option for indicating that your application should be displayed full screen. None, or very few, of the vendor-specific options have an actual impact on security.

The information in the JAD can be duplicated in the application manifest and the JAD must match the manifest exactly. In MIDP 1.0, JAD information took priority over MIDP information. MIDP 2.0 requires the match. Otherwise, the JAD could claim the application has different metadata than it actually does. Other security vulnerabilities related to JAD file parsing have also been reported. For example, Ollie Whitehouse from Symantec discovered that embedding character return characters in a JAD can cause some phones to display incorrect information on the installation screen.

Signatures

Devices uses code signatures to verify the integrity and origin of applications and then use this information to decide how much to trust a given application. Standard Java applications also use signatures for this purpose, but the signature is embedded in the JAR file. JME signatures are attached to the JAD, and the rules are slightly different: Every application can only have one signer, and any changes to the JAR file invalidate the application’s signature.

Two attributes are used to express JAD signatures: MIDlet-Certificate-X-Y and MIDlet-Jar-RSA-SHA1. The MIDlet-Certificate attribute describes the certificate chain. X is the chain number, and Y is the certificate’s position in the chain. A value of 1 for Y denotes the leaf certificate. The MIDlet-Jar-RSA-SHA1 is an RSA-encrypted SHA-1 hash of the JAR file and will be verified against the certificate described in the JAD and the device’s certificate store. Both entries are Base-64 encoded. Here are sample JAD signature nodes:

MIDlet-Certificate-1-1:
MIICGTCCAYKgAwIBAgIESjmCFjANBgkqhkiG9w0BAQUFADBRMQwwCgYDVQQGEwNVU0ExC
zAJBgNVBAgTAkNBMQ8wDQYDVQQKEwZpc2Vjb3UxDTALBgNVBAsTBGlzZWMxFDASBgNVBA
MMC2lzZWNfc2lnbmVyMB4XDTA5MDYxNzIzNTM1OFoXDTA5MTIxNDIzNTM1OFowUTEMMAo
GA1UEBhMDVVNBMQswCQYDVQQIEwJDQTEPMA0GA1UEChMGaXNlY291MQ0wCwYDVQQLEwRp
c2VjMRQwEgYDVQQDDAtpc2VjX3NpZ25lcjCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCg
YEAiTLVnE4/EFFvJORxa0/wFYi8/QZfufiu4QGFdB4jJchKalxDe1UoqorbEDiowcUw7M
AFoVR6yKOeHRZVTuKU4uq4fti/XcmwyML7loHw39Pd097384PK745DGUirDCqf6Dak1Tq
NG9EjicQKXDNaAd98xaEJGpeqpOHhN5K0LokCAwEAATANBgkqhkiG9w0BAQUFAAOBgQA8
IxC1OLw86yt8U2u9ufogaD7comUZyg+USjI0pkdaUVTRY+Xd+QCNh6PJpwItH8ImuioRs
elLJH4Tel7KRrXNchJYuoDF+K4ajpc62dpfpIB0FlPhuXFMD5z0E3Mkd4cfWVUIGvE/ZB
7xVBNtZEmINIQjvtKcZG6v6izO5uxilw==

MIDlet-Jar-RSA-SHA1:
hSd7tIqqIh+Aw08DUYvc2OtoMP5DiMsFZbt0M/cjlkaQfvZaEGy061KlvwSSoNF9kPhLT
G1scZnN5j597d5xGuk+WkOzLhUlKwNtZYEDRPnwsiOw56qhvOw2yNQH2gF+Cj9VR6dWL5
1MvnFk8PJeU5Q2Uey0NeROFlQ6F/i1Shc=

Obtaining a Signing Key

To generate signatures, you will need a certificate and a public/private keypair. These can be purchased from different code-signing Certification Authorities (CA). Despite everyone’s best intentions, getting a signing key that works on all devices and all networks around the world is very difficult. Each carrier has a unique application approval process and rules; often these rules are enforced by requiring code to be signed with a certificate from a particular CA. Sun recently introduced the Java Verified program, which seeks to ease developers’ pain and make the JME ecosystem more consistent with standard CAs and testing procedures. It is not clear yet if it is going to be a success. To find out more information, visit http://javaverified.com/. For a more traditional approach, visit the mobile development website of your target carrier.

Of course, paying for a certificate is no fun if you just want to learn about device security. Therefore, feel free to generate test certificates using the Java SE keytool.exe tool. These self-signed certificates can be used to sign applications and deploy them to emulators. These signatures will not be accepted by real-world devices. Follow these steps to create a key for signing:

  1. Install the Java Runtime Environment (JRE). If you have been running NetBeans or any Java applications, this will already be installed. If not, download the JRE from www.java.com.

  2. Open a command prompt (Start | Run and type cmd.exe).

  3. Change to the JRE bin directory (for example, C:\Program Files\Java\jdk1.6.0_13\jre\bin).

  4. Generate a keypair by running the following command:

    keytool -genkey -keyalg RSA -keysize 1024 -alias SigKey
    -keystore c:\drop\keystore

This command will create a new key with the alias “SigKey” and a new keystore file at c:\drop\keystore. During the key-creation process, you will be asked for some information. Because this is a self-signed certificate, feel free to enter whatever you wish. Also make sure to specify a secure password for the keystore. This password is used to encrypt the keystore and ensure that no one else can access it.

Signing JME Applications

Now that you have a signing key, it is possible to actually sign JME applications. To do so, use the jadtool.exe program that comes with the JME SDK. This tool takes a JAD and a JAR as input, calculates the signature, and then updates the JAD for you. To generate a signature, follow these steps:

1.
Install the JME SDK. These instructions assume that you have installed version 3.0.

2.
Open a command prompt (Start | Run and type cmd.exe).

3.
Change to the JME SDK bin directory (for example, C:\Java_ME_platform_SDK_3.0\bin).

4.
Run the jadtool and add the public key of your signing certificate into MyApp’s JAD file using the following command:

jadtool -addcert -alias SigKey -keystore c:\drop\keystore
-inputjad myapp.jad -outputjad myapp-key.jad

5.
This command refers to the key that was created earlier, so make sure that the key alias and keystore file path match up. After running this command, you can open the generated myapp-key.jad file and see that the MIDlet-Certificate-1-1 attribute has been added.

6.
Now sign the application with this command:

jadtool -addjarsig -alias SigKey -keystore c:\drop\keystore
-inputjad myapp-cert.jad -outputjad myapp-signed.jad
-storepass password -keypass password -jarfile myapp.jar

7.
You will need to substitute the appropriate password values for the storepass and keypass parameters and make sure that the filenames point to your actual application.

Both keystore management and signing can be performed using the NetBeans IDE. To manage keystores, use Tools | Keystore. To control signing, right-click on a project, open the Properties panel, and select the Build\Signing category.

Distribution

How JME applications are distributed varies by device and network. Almost every carrier has some sort of application store that is accessible via the phone. However, there are many other websites that offer JME applications, and unlike with the iPhone, users are not locked in to getting applications from just their carrier. Naturally, this increases the risk of users being tricked into installing malicious applications from questionable sources.

Installation

All MIDP 2.0 devices must support Over-The-Air (OTA) application installation. Of course, the implementation will vary between vendors, but they all follow the same pattern. To install an application OTA, the user visits a website and downloads the JAD file. The device parses the file and displays the application’s information to the user. At this point, the user must be presented with an option of canceling installation. If the user chooses to proceed, the device will download the application’s JAR file from the URL specified in the JAD file and install the application into the local package manager.

Note that both the JAD and JAR files are downloaded using the cleartext and non-integrity-protected HTTP protocol. The use of signatures mitigates the risk that an attacker could modify the application as it is downloaded. Of course, the attacker could just remove the signature, but that would hopefully cause the user to not accept the application’s installation or cause the device to run the application with reduced privileges.

Other  
  •  Java Mobile Edition Security : Configurations, Profiles, and JSRs
  •  Programming the Mobile Web : Performance Optimization
  •  Programming the Mobile Web : Testing and Debugging (part 3) - Client-Side Debugging
  •  Programming the Mobile Web : Testing and Debugging (part 2) - Server-Side Debugging & Markup Debugging
  •  Programming the Mobile Web : Testing and Debugging (part 1) - Remote Labs
  •  Windows Phone 7 : Working with Controls and Themes - Adding Transition Effects
  •  Windows Phone 7 : Working with Controls and Themes - Understanding Frame and Page Navigation
  •  Windows Phone 7 : Working with Controls and Themes - Panorama and Pivot Controls
  •  Programming the Mobile Web : Widgets and Offline Webapps - Platforms (part 5) - Windows Mobile & BlackBerry
  •  Programming the Mobile Web : Widgets and Offline Webapps - Platforms (part 4) - Windows Mobile & BlackBerry
  •  Programming the Mobile Web : Widgets and Offline Webapps - Platforms (part 3) - webOS & Android
  •  Programming the Mobile Web : Widgets and Offline Webapps - Platforms (part 2) - iPhone, iPod, and iPad
  •  Programming the Mobile Web : Widgets and Offline Webapps - Platforms (part 1) - Symbian/Nokia
  •  Programming the Mobile Web : Widgets and Offline Webapps - Standards
  •  Mobile Application Security : BlackBerry Security - Networking
  •  Mobile Application Security : BlackBerry Security - Local Data Storage
  •  Themes on Windows Phone 7 Devices (part 2) - Changing the Theme & Detecting the Currently Selected Theme
  •  Themes on Windows Phone 7 Devices (part 1) - Applying a Theme
  •  Programming the Mobile Web : Mobile Widget Platforms
  •  Programming the Mobile Web : Geolocation and Maps - Showing a Map
  •  
    Top 10
    Kickstarting A Revolution? (Part 2)
    Multifaceted Tests : Stealing Cookies Using XSS & Creating Overlays Using XSS
    Reactos – The Next Windows? (Part 3)
    Understanding IIS 7.0 Architecture : Non-HTTP Request Processing
    The Ubuntu Server Project (Part 2) - Web access
    Shoot Your Best-Ever Portraits (Part 2) - Natural light setups
    Upgrade Power - Guidelines For PSU Buyers (Part 3) - Corsair Professionial Series HX1050, Topower PowerBird 1100W
    Home Cinema, April-2012 (Part 1) - Sony Bravia KDL-46NX723
    Visual Studio Team System 2008 : Creating new report (part 1) - Report server project
    Major Access Control List Changes in Vista
    Most View
    Instagram Substitutes On Android (Part 1) - Streamzoo, Flickr & PicPlz
    Introducing SharePoint 2010 (part 2)
    Customizing Windows 7’s Desktop (part 2) - Getting Around the Start Menu
    Understanding Exchange Policy Enforcement Security : Implementing Transport Agent Policies on the Edge
    3D Phone – Why Is LG Optimus 3D Max P725 The Best Choice, Still?
    DrayTek Vigor 3200n
    IIS 7.0 : Runtime Web Server Extensibility (part 5) - Using Appcmd to Install and Manage Modules
    The Language of Apple Platforms : Object-Oriented Programming and Objective-C
    Designing and Configuring Unified Messaging in Exchange Server 2010 : Unified Messaging Features
    Programming .NET Security : Using the Code-Access Security Policy Tool (part 2) - Evaluating Security Policy
    Choosing a super-zoom camera (part 1)
    Sharepoint 2007: Personal Sites and Personal Details (Available Only in MOSS)
    IIS 7.0 : Enabling and Configuring FRT - Tracing a Specific Error Code
    Sharkoon T9
    The best of the web (Part 2) - Evernote & ChallengePost
    Corel Painter X : Working with Layers - The Chair
    Integrating Your Application with Windows Phone 7
    Exchange Server 2007: Create Mail-Enabled Contacts and Mail-Enabled Users
    70 Ways To Take Better Photos (Part 2) - Improve your vista shots
    HP Omni 27