miércoles, 20 de octubre de 2010

Bypass the browser sandbox with a Java Applet

This is an aproach we followed some months ago to bypass the browser sandbox and to be honest this solution (for our porpouses) was simply terrific. We want to share it because there's not a lot of documentation in the net about communicating your applet, browser and OS.

First a brief about how browsers "sandbox" work. All the browsers (at least the secure ones) have a tier that is called the "sand box", this "sand box" prevents executing harmfull code in a webpage, for example, this denies any operation in ports, hard drive, monitor, sound card, etc. This "sand box" is an important safe in all browsers because no one wants to enter a webpage and allow some nasty code to format our harddrive, but in the same way this limits the posibilities of the developers of writing code that interacts with the hardware of the user.

Our requirement was reading a string displayed in a webpage and when the user clicks a button send the string via serial COM. The possible approaches that we figured out are:

1. Using an ActiveX Control:

Pros:

There's already a control that does this work.

Cons:

This code will work only in Internet Explorer.
This is a payed solution.
Theres no security control in ActiveX.
We hate ActiveX!

2. Use an stand alone application and comunicate with the browser using a common database.

Pros:

Easy to implement. We know how to comunicate a web page using php,jsp,etc to a database and we know how to communicate a stand alone to a database.
Is free.
Crossplatform.

Cons:

You will have three diferent systems to mantain. A common and accesible database, some server pages and a stand alone.
You will have to provide a lot of configuration information to your customer. A database conection, how to install your standalone, etc.
You will need to implement a polling algorithm in the standalone that reads every X time the database for changes. This is really really nasty.

3. Using a Java Applet!

Pros:

You can embed the applet in the page and the user does not have to install anything. When he enters the page the applet installs automatically.
The applet can be signed to provide a high level of security.
You only need to mantain one component, the Applet!
Crossplatform.
Is free.

Cons:

Lately the people is stopping using applets. The applet boom has passed and now is really strange to find new implementations using this technology.
You need to install the JRE in the client terminal.

Extra

4. Using Google native code HTML5 libraries. This is really an extra because is not ready for production.

So whats the deal? Well, you need to write an applet that sends data to the serial COM (or that sends music to your sound card, or that erase completly the harddrive, etc....). This is easy well documented, we used RXTX java library without problems. Next you need to paste it in your webpage and using javascript read the required information from the HTML controls.

Let's see a practical examples.

WebPage example code:

We can achieve the goal of communicate javascript code with the applet code to send the string characters to the COM port. To do that we need to put this code in our HTML document:



<script src="http://www.java.com/js/deployJava.js"></script>
<script>
var parameter = "Some data you want to pass to applet at init time";
var attributes = { id: 'app', MAYSCRIPT: 'true', code:'<full qualified name of the applet class ie. mx.ssf.project.MyApplet.class>', archive:'<path to look at for the .jat file>', width:430, height:490} ;
var parameters = {nameOfParameterOnTheApplet: parameter} ;
deployJava.runApplet(attributes, parameters, '1.6');
</script>

Ok, let's try to explain what's going on in the above sniped of code.

The line

<script src="http://www.java.com/js/deployJava.js"></script>

imports a tiny javascript library file, the deployJava.js. This library contains all the code needed to integrate and deploy the applet in the web page that you want. This is a very comfortable
way to deploy the applet, you only need add this file and call the corresponding methods or functions that the library gives you, and it's done. If you look well, the file is on the Java.com site
so you don't need to download it.

Next, the block of code:

<script>
var parameter = "Some data you want to pass to applet at init time";
var attributes = { id: 'app', MAYSCRIPT: 'true', code:'<full qualified name of the applet class ie. mx.ssf.project.MyApplet.class>', archive:'<path to look at for the .jat file>', width:430, height:490} ;
var parameters = {nameOfParameterOnTheApplet: parameter} ;
deployJava.runApplet(attributes, parameters, '1.6');
</script>

Determines the way the Applet will be deployed. The first line declare a local javascript variable that we can use to send some data to the applet from the beginning like a parameter.

In the next line, we declare the attributes for the applet. For example, the id of the applet that can referenced through the javascript script, the full qualified name for the class
of the applet and the path for the .jar file that contains the bytecode to tell the Java plugin where to find that class. It's important to notice the attribute "MAYSCRIPT: true",
this attribute it's the responsible for the communication between javascript and the applet, if this attribute is not declared, such communication can't exists.

The next line, defines an array of parameters to be passed to the applet. Notice that we use the javascript variable (var parameter) in this array declaration. It's imperative that we declare
a parameter name to be used inside the applet. In this exameple that name is "nameOfParameterOnTheApplet".

At the end, we simply call the runApplet function that it's declared in the deployJava.js file passing the attributes and parameters arrays and the version of the java run time environment that we want to use to launch the Java Applet.

This demostrates how easy it's the implementation and deployment of a java applet.


Calling to an Applet method from JavaScript.

Now, I'm going to show how to call to an applet method from a javascript scrip using the example above.

Suppose that we want to send to the COM port some string that is calculated in some maner in the HTML page. To acomplish this, first it's needed a javascript function like this:


<script language="javascript">
function reimprimir(){
var ticket = document.forms[0].ticketArea.value;
var applet = document.getElementById('app');
applet.print(ticket);
}
</script>


This function can be called from a javascript event taking the value of a text area control of the form. The reference to the applet is obtained via getElementById function using the id defined as an attribute of the applet like showed earlier in this example. Once we have the reference to the applet, we simply call the applet method like
if we were programming in the java language. The applet method "print" it's defined to receive a String value, that value is the string we have in the text area component of the form. When
the applet method it's called, the logic it's executed as expected.

Applet Code:

There is nothing especial in the applet code. It can do everything that is allowed by the Java Run Time Enviroment policy. Only one thing it's required to skip the browser sandbox. We need to sign the resulting
.jar file to the client browser can trust in our application.To do that, we need to do the following:

In a command line console, perform:

$ keytool -genkey -alias


Remember, the alias name can be anything you want :)

$ jarsigner -keystore -storepass -keypass


The alias-name is the same that we used in the earlier. The .keystore file usually is created in the "home" directory. (We assume a Linux operating system).

With that done, the only step left is include the signed jar file in the Web application project to start using it.

When the user enters your web page a popup will request the JRE plugin installation in an automated way, after that the applet will load and will ask the user for permission (this permission can be permanent based in the virtual machine configuration) and finally the displayed information in the page will start flowing via COM port. Sweet.

No hay comentarios:

Publicar un comentario