Java Error Examples

As with every language, Java programming comes with its own unique set of common errors and vulnerabilities. Klocwork can detect a large number of  Java errors in the following categories:

  • Resource management (See detailed example)
  • Concurrency violations (See detailed example)
  • Web application vulnerabilities (See detailed example)
  • Uses of un-validated user input
  • Device-specific coding practices
  • JSP interactions
  • Invalid object references
  • Improper collection usage

Concurrency

Concurrent programming, or the practice of dividing up a program’s execution context into two or more threads, is more common with multicore and multi-CPU hardware environments. Regardless of the programming language, there are several basic requirements that source code analysis must identify and address in a concurrent context.

Two of the most important concurrent programming requirements:

  • The ability to spot deadlock or livelock situations
  • The ability to spot race conditions

Deadlocks and livelocks refer to situations in which programs use locking semantics to guard sections of code against two or more threads of execution attempting access simultaneously. Typically, this involves modifying global data, but is by no means limited to that context. Without these capabilities, developers are left to guess for themselves how their programs will operate at runtime.

Example: Concurrency

Consider the following example:


GeSHi Error: GeSHi could not find the language javas (using path /home/sdcsyste/public_html/wp-content/plugins/codecolorer/lib/geshi/) (code 2)

Here, several different locking scenarios are shown, any of which can cause blocking situations, including:

  • Explicitly blocking one thread while holding a process-wide lock
  • Lock contention through potentially inconsistent acquisition semantics

Significant debug time can also be spent chasing almost impossible-to-replicate behavior caused by the race condition. This condition occurs when two or more threads each has an equal chance to modify data in each other’s’ context. A simple example is static data in a re-entrant class, such as a servlet running within a J2EE container. Modifying class data on one thread that might be read or differently modified at the same time by another thread will lead to unexpected behavior.

Resource leaks

Like memory leaks, resource leaks can be crippling to an application and, over time, will lead to denial-of-service scenarios. The family of resource leaks to be most concerned with are those that tie into either operating system handles or descriptors, or to framework memory that requires explicit release semantics.

Klocwork supports a wide variety of resource semantics, from basic types like file descriptors and streams to framework-specific semantics for environments such as Google’s Web Toolkit, Struts, Java Mail, J2ME, ImageIO, Hibernate, and many more.

A very common mistake is to assume that the runtime garbage collector (GC) will look after resources in the same way that it looks after memory references. However, while the memory associated with the object itself is collected by the GC, the resources associated with that object may not be cleaned up.

Example: Resource leaks

Consider the following example:

1
2
3
4
5
6
7
8
9
public void foo(String name) throws IOException {
Reader r = new InputStreamReader(new FileInputStream(name));
char ch;

while ((ch = r.read()) != -1) {
if(ch == ' ')
return;
}
}

There are at least two types of resource that are collected under the input stream object in the example above:

  • Memory associated with the stream object itself, and with managing state within the stream
  • An operating system file descriptor or handle that relates to the underlying file within the file system

The GC will take care of the first aspect while leaving the underlying descriptor open, thus consuming valuable system resources over time and eventually resulting in a denial-of-service scenario.

Web application vulnerabilities

With many potential pitfalls inherent in creating web applications, this has quickly become one of the most popular areas to investigate automated approaches to debugging. Klocwork static code analysis detects vulnerabilities like:

  • SQL injection
  • Process or file injection
  • Code injection
  • Cross-site scripting (XSS)
  • Request forging

Each of these types of failure requires specific checks and analysis. However, many of the attack vectors exposed by such weaknesses can be generalized to the propagation of tainted data around an under-defensive design. That is, taking input from a user or another process and using that data without rigorous validation of its format, its range, or whatever else might make sense for the data type in question.

Example: Web application vulnerabilities

In a servlet context, for example, consider the following snippet:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public void doGet(HttpServletRequest req, HttpServletResponse res)
{
String name = req.getParameter("username");
String pwd = req.getParameter("password");

// SQL Injection
int id = validateUser(username, password);

// XSS
String retstr = "User : " + name + " has ID: " + id;
res.getOutputStream().write(retstr.getBytes());
}

private int validateUser(String user, String pwd)
throws Exception
{
Statement stmt = myConnection.createStatement();
ResultSet rs;

rs = stmt.executeQuery("select id from users where
user='"
+ user + "' and key='" + pwd + "'");
return rs.next() ? rs.getInt(1) : -1;
}

This example exhibits several different kinds of common errors. Putting aside the obvious resource leakage and management issues, these include:

  • SQL injection via the use of an unfiltered incoming URL parameter as both username and password
  • Cross-site scripting, or request mirroring, by including the unfiltered incoming URL parameter in our response to the user

A malicious user could provide suitably marked-up URL parameters that would cause many problems. Likewise, applications that fail to validate strings that end up being used as file names are also open to file or process injection.

Other languages

For examples of the types of defects Klocwork can detect in other languages please see the C/C++ error examples and C# error examples pages.