Securing your local servlets in Lotus Notes

At this point, everyone knows about the Lotus Notes client and the embedded HTTP stack, or at least most know. If you do not know, here is a little primer: there is an embedded HTTP stack in the Lotus Notes client. 🙂

Just kidding!

The http stack allows for developers to create servlets, host HTML or even run pre-compiled JSP’s. You can learn more about the stack on the Lotus Expeditor Wiki.

Ok, so how can I prevent “other” operating system applications from calling into my servlet?

First off, the Lotus Notes client does a good job in not making it easy to figure out the port number of the embedded server. So the first layer of security is a random port number on each launch of the client. So you might see URL’s that look similar to this:

http://localhost:1436/proxy/viewer.html

The port 1436 is dynamic and switches every time the Notes client starts. But that really is not good enough. A good hacker can most likely figure this out as the number is stored in memory. You may have also read how I can attach any browser on my machine to my servlet to help debug the Attachment Viewer sidebar plugin by enabling the debug option. This allows me to use the debug tools in Chrome and FireFox to assist with debugging my JavaScript and Dojo code.

The problem is, any application outside of Notes can do this if they figure out the port! That means anything your servlet “serves” up can be subjected to attack. So here is what I did to prevent this in the next version of the Attachment Viewer.

I used cookies to protect the servlet so only embedded browsers in the Notes Client can interact with the proxy servlet. While this is not 100% secure yet (stay tuned for the next post), it is a good way to prevent other operating system applications from getting into the Notes client. I simply generated both a unique key and value and set the cookie using the SWT browser API. Here is the code to create the key and value:

static String getNewKey(Object obj){
   return "AT" + (System.currentTimeMillis() * 3) + obj.hashCode();
}
static String getNewValue(Object obj){
   return "AT" + (System.currentTimeMillis() * 2) + obj.hashCode();
}

The object is the Attachment Viewer ViewPart and you can see we get the current time in milliseconds and multiply them by different values. This insures the name and value will be random every time the Notes client launches. Next we have to set the cookie in the browser before we launch the URL:

private void initURL(int port, String host) {
     currentCookieKey = Security.getNewKey(this);
     currentCookieValue = Security.getNewValue(this);
     String url = "http://" + host + ":" + port + "/proxy";
     Browser.setCookie(currentCookieKey + "=" + currentCookieValue, url);

     browser.setUrl(url + "/viewer.html");
 }

So you can see we get a new key and value, store them into some memory where the proxy servlet can do a check against it when a request comes in. You will also notice that the setCookie is a static method, meaning all browser instances will inherit this cookie and can potentially access the servlet. We could even go further and assign an expiration to the cookie if we wanted.

Now in the servlet code, in our doGet() method, we verify the cookie and error out if it is not what we expect:

if (isValidRequest(req) == false){
     OutputStream os = resp.getOutputStream();
     StringBuffer buffer = new StringBuffer();

     buffer.append("<h1>Invalid security token, access to proxy not granted.</h1>");
     os.write(buffer.toString().getBytes());
     os.close();
     return;
 }

In the end, when you attempt to connect to the servlet using FireFox or Chrome you would see something like this:

Click image to see full the image

One thought on “Securing your local servlets in Lotus Notes

  1. Pingback: Bob Balfe: Securing your local servlets in Lotus Notes

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s