Common vulnerabilities in Java and how to fix them

Injection

Command injection is also a type of injection issue. Injection happens when an application cannot properly distinguish between untrusted user data and code. When injection happens in system OS commands, it leads to command injection. But injection vulnerabilities manifest in other ways too.

SQL Injection

In an SQL injection attack, for example, the attacker injects data to manipulate SQL commands. When the application does not validate user input properly, attackers can insert characters special to the SQL language to mess with the query’s logic, thereby executing arbitrary SQL code. Learn more about how these SQL injection attacks work here.

SQL injections allow attacker code to change the structure of your application’s SQL queries to steal data, modify data, or potentially execute arbitrary commands in the underlying operating system. The best way to prevent SQL injections is to use parameterized statements, which makes SQL injection virtually impossible. Learn about how to use parameterized statements in Java in this article.

NoSQL Injection

Databases don’t always use SQL. NoSQL databases, or Not Only SQL databases, are those that don’t use the SQL language. NoSQL injection refers to attacks that inject data into the logic of these database languages. NoSQL injections can be just as serious as SQL injections: they can lead to authentication bypass and remote code execution.

Modern NoSQL databases, such as MongoDB, Couchbase, Cassandra and HBase, are all vulnerable to injection attacks. NoSQL query syntax is database-specific, and queries are often written in the programming language of the application. For the same reason, methods of preventing NoSQL injection in each database are also database-specific. You can learn how to prevent NoSQL injection in MongoDB, Couchbase, Cassandra and HBase here.

LDAP Injection

The Lightweight Directory Access Protocol (LDAP) is a way of querying a directory service about the system’s users and devices. For instance, it’s used to query Microsoft’s Active Directory. When an application uses untrusted input in LDAP queries, attackers can submit crafted inputs that causes malicious effects. Using LDAP injection, attackers can bypass authentication and mess with the data stored in the directory. You can use parameterized queries to prevent LDAP injection. Find out how LDAP injections work and how to prevent them.

Log Injection

You probably conduct system logging to monitor for malicious activities going on in your network. But have you ever considered that your log file entries could be lying to you? Log files, like other system files, could be tampered with by malicious actors. Attackers often modify log files to cover up their tracks during an attack. Log injection is one of the ways attackers can change your log files. It happens when the attacker tricks the application into writing fake entries in your log files.

In Java, log injection often happens when the application does not sanitize new line characters “\n” in input written to logs. Attackers can make use of the new line character to insert new entries into application logs. Another way attackers can exploit user input in logs is that they can inject malicious HTML into log entries to attempt to trigger an XSS on the browser of the admin who views the logs.

To prevent log injection attacks, you need a way to distinguish between real log entries, and fake log entries injected by the attacker. One way to do this is by prefixing each log entry with extra meta-data like a timestamp, process ID, and hostname. You should also treat the contents of log files as untrusted input and validate it before accessing or operating on it.

Mail Injection

Many web applications send emails to users based on their actions. For instance, if you subscribed to a feed on a news outlet, the website might send you a confirmation with the name of the feed.

Mail injection happens when the application employs user input to determine which addresses to send emails to. This can allow spammers to use your server to send bulk emails to users or enable scammers to conduct social engineering campaigns via your email address. Learn how attackers can achieve mail injection and how you can prevent it here.

Template Injection

Template engines are a type of software used to determine the appearance of a web page. These web templates, written in template languages such as Jinja, provide developers with a way to specify how a page should be rendered by combining application data with web templates. Together, web templates and template engines allow developers to separate server-side application logic from client-side presentation code during web development.

Template injection refers to injection into web templates. Depending on the permissions of the compromised application, attackers might be able to use the template injection vulnerability to read sensitive files, execute code, or escalate their privileges on the system. Learn how template injection work and how to prevent them in this post.

Expression Language Injection

Expression language (EL) refers to program expressions written into Java Server Pages (JSP) that is executed as code. When untrusted user input is passed into these expressions, attackers might be able to insert malicious code which is then executed by the expression language interpreter. This leads to remote code execution. Learn about how this attack works here.

To prevent EL injection, you should avoid passing untrusted user input into expressions evaluated by the EL interpreter. If you do need to pass data into EL expressions, validate the data using an allowlist, or encode the data to make sure that it is not interpreted as code.

Regex Injection

A regular expression, or regex, is a special string that describes a search pattern in text. Sometimes, applications let users provide their own regex patterns for the server to execute or build a regex with user input. A regex injection attack, or a regular expression denial of service attack (ReDoS), happens when an attacker provides a regex engine with a pattern that takes a long time to evaluate. You can find examples of these patterns in my post here.

Thankfully, regex injection can be reliably prevented by not generating regex patterns from user input, and by constructing well-designed regex patterns whose required computing time does not grow exponentially as the text string grows. You can find some examples of these preemptive measures here.

XPath Injection

XPATH is a query language used for XML documents. Think SQL for XML. XPATH is used to query and perform operations on data stored in XML documents. For example, XPATH can be used to retrieve salary information of employees stored in an XML document. It can also be used to perform numeric operations or comparisons on that data.

XPATH injection is an attack that injects into XPATH expressions in order to alter the outcome of the query. Like SQL injection, it can be used to bypass business logic, escalate user privilege, and leak sensitive data. Since applications often use XML to communicate sensitive data across systems and web services, these are the places that are the most vulnerable to XPATH injections. Similar to SQL injection, you can prevent XPATh injection by using parameterized queries.

Header Injection

Header injection happens when HTTP response headers are dynamically constructed from untrusted input. Depending on which response header the vulnerability affects, header injection can lead to cross-site scripting, open redirect, and session fixation.

For instance, if the Location header can be controlled by a URL parameter, attackers can cause an open redirect by specifying their malicious site in the parameter. Attackers might even be able to execute malicious scripts on the victim’s browser, or force victims to download malware by sending completely controlled HTTP responses to the victim via header injection. More about how these attacks work here.

You can prevent header injections by avoiding writing user input into response headers, stripping new-line characters from user input (new line characters are used to create new HTTP response headers), and using a allowlist to validate header values.

Session Injection and Insecure Cookies

Session injection is a type of header injection. If an attacker can manipulate the contents of their session cookie, or steal someone else’s cookies, they can trick the application into thinking that they are someone else. There are three main ways that an attacker can obtain someone else’s session: session hijacking, session tampering, and session spoofing.

Session hijacking refers to the attacker stealing someone else session cookie and use it as their own. Attackers often steal session cookies with XSS or MITM (man-in-the-middle) attacks. Session tampering refer to when attackers can change their session cookie to change how the server interprets their identity. This happens when session state is communicated in the cookie and the cookie is not properly signed or encrypted. Finally, attackers can “spoof” sessions when session IDs are predictable. If that’s the case, attackers can forge valid session cookies and log in as someone else. Preventing these session management pitfalls requires multiple layers of defense.

Host Header Poisoning

Web servers often host multiple different websites on the same IP address. After an HTTP request arrives at an IP address, the server will forward the request to the host specified in the Host header. Although Host headers are typically set by a user’s browser, it’s still user-provided input and thus should not be trusted.

If a web application does not validate the Host header before using it to construct addresses, attackers can launch a range of attacks, like XSS, server-side request forgery (SSRF), and web cache poisoning attacks via the Host header. For instance, if the application uses the Host header to determine the location of scripts, the attacker could submit a malicious Host header to make the application execute a malicious script:

String scriptURL = "https://" + properties.getProperty("host") + "/script.js";

Learn more about how Host header attacks work here.