Checker BasicInjection   as of Julia version 2.4 (built on 23 Oct 2017)

belongs to group Basic

Identify simple security injections


The most dangerous software errors are due to the injection of user data into sensitive routines, such as database queries, html output to the client or file system access. These attacks are generally known as injection attacks and there is large literature about the risk that they pose to software exposed to uncontrolled user input. The list available at cwe.mitre.org reports explicit examples of such security issues, for instance SQL-injection, OS-command injection, cross-site scripting and open redirect. The unifying aspect of these errors is that user input can flow, unconstrained, into sensitive routines. Hence Julia provides this checker in order to track explicit information flow in the program, from automatically or manually selected source locations into automatically or manually selected sink locations. In this way, Julia allows one to identify potential security errors of the above categories, with a soundness guarantee derived from the use of abstract interpretation, and with the freedom to bend the analysis to specific needs, through the use of code annotations.

Action: Verify that a security error actually corresponds to unconstrained information flow from source locations into sink locations. If this is the case, add a sanitizing algorithm to clean data before it flows into sinks, or use prepared statements for SQL queries rather than free queries built from string concatenation.

This checker is a simpler and faster version of the Injection checker. In particular, this checker is unsound since it finds the most apparent injection attacks, but might miss some complicated attack. If you need to find all possible attacks, please use the sound Injection checker instead. If you only need to find some attacks in short time or for very large programs, then this checker is the right choice.

Specification of source and sink locations

Please refer to the same topic for the Injection checker. Normally, you needn't specify any source or sink location, since Julia will recognize the most frequent locations automatically (see the list of sources natively recognized by Julia).

Examples


Consider the following program:

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.juliasoft.julia.checkers.injection.SqlTrusted;
import com.juliasoft.julia.checkers.injection.Trusted;

@SuppressWarnings("serial")
public class BasicInjection extends HttpServlet {
  private @SqlTrusted Object sqlTrusted;
  private @Trusted Object trusted;
  public String a = "my friend";

  @Override
  protected final void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
    processRequest(request, response);
  }

  private void test2(@SqlTrusted String s) {}

  private void test3(@Trusted String s) {}

  private void processRequest(HttpServletRequest request, HttpServletResponse response) throws IOException {
    response.setContentType("text/html;charset=UTF-8");

    String user = request.getParameter("user");

    try (PrintWriter out = response.getWriter()) {
      out.println("User : " + user);
      out.println(user);
      out.println("hello");
      out.println("hello " + a);
    }

    if (user != null)
      test2(user);
    test2("User: " + user);
    test2("hello");
    test2("hello " + a);
    test3(user);
    test3("User: " + user);
    test3("hello");
    test3("hello " + a);
    sqlTrusted = user;
    trusted = user;
    sqlTrusted = "User: " + user;
    trusted = "User: " + user;
    sqlTrusted = "hello";
    trusted = "hello";
    sqlTrusted = "hello " + a;
    trusted = "hello " + a;
  }
}

This checker issues the following warnings:

BasicInjection.java:32: [BasicInjection: XSSInjectionWarning] possible XSS-injection from line 29 into the 0th actual parameter of println
BasicInjection.java:33: [BasicInjection: XSSInjectionWarning] possible XSS-injection from line 29 into the 0th actual parameter of println
BasicInjection.java:39: [BasicInjection: SqlInjectionWarning] possible SQL-injection from line 29 into the 0th actual parameter of test2
BasicInjection.java:40: [BasicInjection: SqlInjectionWarning] possible SQL-injection from line 29 into the 0th actual parameter of test2
BasicInjection.java:43: [BasicInjection: GenericInjectionWarning] possible injection of tainted data from line 29 into the 0th actual parameter of test3
BasicInjection.java:44: [BasicInjection: GenericInjectionWarning] possible injection of tainted data from line 29 into the 0th actual parameter of test3
BasicInjection.java:47: [BasicInjection: SqlInjectionIntoFieldWarning] possible SQL-injection from line 29 into field sqlTrusted
BasicInjection.java:48: [BasicInjection: GenericInjectionIntoFieldWarning] possible injection of tainted data from line 29 into field trusted
BasicInjection.java:49: [BasicInjection: SqlInjectionIntoFieldWarning] possible SQL-injection from line 29 into field sqlTrusted
BasicInjection.java:50: [BasicInjection: GenericInjectionIntoFieldWarning] possible injection of tainted data from line 29 into field trusted

Let us discuss the motivation of such warnings. The parameter read at line 29 is considered as user input. This checker tracks its propagation along the statements of the program and finds out that that user input is printed at lines 32 and 33. Instead, the text printed at lines 34 and 35 does not contain user input, although it is not necessarily a hardcoded constant string. Same reasonings apply to the other warnings.

In this example, the programmer should avoid a direct flow from user input to servlet output, since this allows a cross-site scripting (XSS) attack. User input should never be printed to the servlet output, or at least it must be previously sanitized.