Take the 2-minute tour ×
Information Security Stack Exchange is a question and answer site for Information security professionals. It's 100% free, no registration required.

I'm playing with some generally well written and parsed java code, but there are some oddities thrown up by my code scanning tool.

I know a null pointer dereference can crash a program, but assuming the code is written to catch and manage all exceptions, does anyone know of a real attack that could use this issue?

Code snippets gratefully received :-)

share|improve this question
    
OHH EMM GEEE. Was just busting my head over this on Thursday, was gonna ask it here, but never got around to it... You rock! –  AviD Mar 5 '11 at 18:24
    
@AviD - well, you know. It came up :-) –  Rory Alsop Mar 5 '11 at 18:53

4 Answers 4

up vote 11 down vote accepted

If you try to use pointer that is null, Java will throw a NullPointerException. Since this is a RuntimeException, you don't have to catch it, but you can. So for example

String iAmNull = null;
iAmNull.trim();

will throw a NullPointException and exit the program. If however you catch it

try {
    String iAmNull = null;<br>
    iAmNull.trim();<br>
} catch (NullPointerException e) {
    log.warn("Null pointer in method x")
}

it will continue to run and simply log the error (if you have set up a logger of course). Alternatively, it is also possible to catch Exception e.

Attacks based on null pointers in Java are theoretically impossible, since the Java Virtual Machine handles all pointers, so it shouldn't be a problem if you have a NullPointer in your code.

share|improve this answer
    
I'd plus 1 but have hit my vote limit today. Good point about it being theoretically impossible. –  Mark Davidson Mar 4 '11 at 12:14
    
I seem to remember reading some research a year or 2 ago, about some possible attack based on null dereference in Java, in certain scenarios. I cannot find it though.... –  AviD Mar 5 '11 at 18:28
1  
This answer is absolutely wrong. There is no theoretical basis for saying that null pointers can never lead to a security flaw. Surely it is possible that a null pointer bug could lead to a security flaw if, e.g., it is part of a logic flaw in security-critical code. –  D.W. Mar 6 '11 at 0:53

Theoretically, any kind of null-pointer dereferencing in Java triggers a NullPointerException, which can be handled within Java just as any other exception. This does not mean that this is good: in practice, it is quite hard to recover from such an exception except by removing the faulty part (i.e. letting the calling thread die, or getting back to a catch-all clause). Following a null pointer is akin to overrunning a buffer: it is still a bug; the difference here between Java and non-protected languages (such as C) is that Java is more graceful about the consequences of that bug: in particular, the exception will propagate back the call stack, releasing monitors (the synchronized keywords) and executing the finally clauses, and only the faulty thread will be affected.

In practice, however, a few issues may arise. How the JVM traps null pointer dereferences is up to the JVM implementation; but what implementations usually do is the following: they just follow the pointer. If the pointer is null, then this leads to a memory access in the first page of memory, which is access-forbidden by the OS. The OS catches the occurrence (through the MMU) and informs the application in a relatively brutal way (on Unix-like systems, this is a SIGSEGV signal). The JVM receives the information, and transforms it into a NullPointerException.

The conversion from signal to exception is a complex thing because the JVM only receives the offending opcode address, which is somewhere either in the bytecode interpreter, or in the JIT-produced binary code. The JVM must locate the method and the thread stack. This has some fine interactions with how the OS put things in memory in the first place. Such code is quite stable nowadays, on mainstream platforms. However, on a less common combination (Sun's JDK ported to FreeBSD), I sometimes had null pointer dereferences for which the JVM was unable to locate the caller stack (because the JVM code was tuned for Linux, not for FreeBSD, and was apparently making an assumption on where the stack should be, assumption which was not always fulfilled on FreeBSD). Consequence was immediate JVM termination, in a most ungraceful way.

Another possible gotcha is that the null pointer dereference is caught because the access falls somewhere in a "forbidden" page; namely, the first page of the address space. However, when accessing an instance field, the JVM usually accesses directly the right data element: if the reference is, at native code level, a pointer to address x, and the field is at offset n in the object structure, then the code will read bytes at address x+n (this really depends on how the JVM represents objects internally, but a C-like structure is common). If the class has many fields, then n may be greater than the size of a page, in which case the read access will not fall on the first page, but the second. What happens in that situation depends on the operating system.

The "field at high offset" situation does not arise with arrays, because array accesses are length-checked and the "length" is usually a kind of field which is close to the object header. Also, there is a limit on the number of fields in a Java class (there is an absolute limit to 65535 in the class file format, actually lower than that because each field must have a name and a type, which are also in the class file format and will hit other limits sooner than that). So the problem will not arise on "common" systems, e.g. a Linux running Sun/Oracle VM. This is mostly something that VM implementers must be aware of.

So my advice is to consider NullPointerException as a serious bug, just like a buffer overflow (which is IndexOutOfBoundsException in Java). The VM safety will help you debug your code (stack traces are really handy) and, if you did not debug enough before deploying, it will probably save your skin. But a bug is a bug.

share|improve this answer
1  
Wow - bonus points for that answer!! –  nealmcb Mar 4 '11 at 17:35
1  
while not exactly answering the q this is a very educational answer. +1 –  Rory Alsop Mar 4 '11 at 22:57
1  
Wow, fantastic detailage. So, bottom line - are there non-standard combinations of systems where this is exploitable in some form? Or is it still theoretical (though important)? –  AviD Mar 5 '11 at 18:34

CWE-476: NULL Pointer Dereference - states that code execution is possible in very rare circumstances and environments is possible. However this is not specific to Java. I've check all the exploit websites I can think of to see if any have exploits for Java based on a null pointer deference and haven't been able to find any.

But while looking around I came across this page on the Cert site - EXC15-J. Do not catch NullPointerException. They state that catching the NullPointerException is suboptimal at best and that in lieu of adding checks to avoid the exception is significantly slower. So depending on your application that may be something you want to consider.

share|improve this answer
    
There was a vulnerability in the C code of flash where a null was used as an array reference. A number of other mistakes meant that it could be used to write mapped memory at a large offset. –  Tom Hawtin - tackline Mar 4 '11 at 13:42
2  
@Tom yes, but that's because C has an unmanaged memory model. In Java you don't have direct access to the memory, and the runtime catches attempts to use Null as a reference (or any other invalid reference) –  user185 Mar 4 '11 at 14:26

Dereferencing any null in Java code will cause an NPE. Unlike C, there is no way to add an offset to land in mapped memory. The NPE will either be caught by a catch or passed through to the thread's uncaught exception handler.

A cause of actual vulnerabilities in Java is accepting nulls where they shouldn't be. Skipping code for null variables is in fact more dangerous than carrying on and NPEing. For instance, ClassLoader references are capabilities, but the most important class loader (the boot class loader) is typically indicated by null (some Java APIs add extra security checks if a supplied class loader reference is null).

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.