31 Do You Understand Injection Attacks in Java Application Development

31 Do you understand injection attacks in Java application development? - Geek Time #

Security is always one of the main topics in the field of software development. With the rise of new technology trends, the importance of security has become more prominent. For industries such as finance, security can even be considered the lifeline of businesses. Whether it’s mobile devices, regular PCs, mainframes, large-scale distributed systems, or various mainstream operating systems, Java, as one of the foundational platforms for software development, is everywhere. Therefore, it has naturally become one of the primary targets for security attacks.

Today, I want to ask you a question: Do you understand injection attacks in Java application development?

31 Do you understand injection attacks in Java application development #

Injection attack is a very common type of attack. Its basic feature is that the program allows the attacker to inject untrusted dynamic content into the program and execute it, which may completely change the originally anticipated execution process and produce malicious effects.

Here are several major ways of injection attacks. In principle, language features that provide dynamic execution capabilities need to be guarded against the possibility of injection attacks.

Firstly, the most common type is SQL injection attack. A typical scenario is the user login function of a web system, where we need to verify the information in the backend database based on the username and password entered by the user.

Suppose the application logic is that the backend program dynamically generates SQL similar to the following based on the user input, and then lets JDBC execute it.

select * from use_info where username = "input_usr_name" and password = "input_pwd"

However, if the input_pwd I entered is something like the following text,

" or ""="

Then, the concatenated SQL string becomes the following condition, and the existence of OR causes whatever name is input to meet the condition.

select * from use_info where username = "input_usr_name" and password = "" or "" = ""

This is just a simple example, which exploits the deviation between expected input and possible input. In the example above, the expected input is a numerical value, but the actual input is a fragment of SQL statement. Similar scenarios can use different SQL statements injected to achieve various purposes of attack, and even add statements like “;delete xxx”. If the database’s access control is unreasonable, the attack effect can be catastrophic.

Secondly, there is command injection in the operating system. Java language provides API similar to Runtime.exec(…), which can be used to execute specific commands. Suppose we build an application that takes text input as a parameter and execute the following command:

ls -la input_file_name

But if the user input is “input_file_name;rm -rf /*”, there may be a problem. Of course, this is just an example. The Java standard class library has made a lot of improvements, so this kind of programming error may not really result in a successful attack, but it reflects a real scenario.

Thirdly, there is XML injection attack. The Java core class library provides comprehensive XML processing, transformation, and various other APIs. XML itself can contain dynamic content, such as XPATH. If not used properly, it may allow access to malicious content.

There are also protocols such as LDAP that allow dynamic content, which can be exploited to construct injection attacks with specific commands, including XSS (Cross-site Scripting) attacks. Although they are not directly related to Java, they can also occur in dynamic pages such as JSP.

Examination Analysis #

Today’s question is an introductory question in the field of security. I have briefly introduced several common types of injection scenarios as examples. Security itself is a very broad topic, and in interviews, interviewers may test security issues. However, if it is not a specific security expert position, understanding basic security practices is sufficient.

Java engineers do not necessarily have to become security experts, but understanding basic knowledge in the field of security can help identify and mitigate risks in daily development. Today, I will focus on security content related to Java development, hoping to serve as a starting point and give you an overall impression of the security field in Java development.

  • When it comes to Java application security, what are the main security mechanisms involved?
  • What exactly is a security vulnerability? How do we avoid typical attacks like SQL injection mentioned earlier in development?

Knowledge Expansion #

First, let’s take a look at which Java APIs and tools make up the foundation of Java security. I have covered many aspects in the previous columns, which can be roughly categorized into three main parts:

First, the runtime security mechanism. It can be simply understood as restricting the behavior of the Java runtime to prevent unauthorized or unreliable actions. Specifically:

  • During the class loading process, bytecode verification is performed to prevent non-compliant code from affecting JVM operation or loading malicious code.
  • Class loaders themselves can also isolate code from each other. For example, applications cannot obtain instances of the Bootstrap Class-Loader, and different class loaders can act as containers to isolate unnecessary visibility between modules. Currently, Java Applets, RMI, and other features have gradually faded into history, but the class loading and other mechanisms are overall being simplified.
  • By utilizing the SecurityManager mechanism and related components, the runtime behavior of code can be limited. You can customize policy files and define permissions at various levels to restrict the scope and permissions of code. For example, permissions for file system operations or permissions to listen on a specific network port. I have created a simple diagram to illustrate the different levels of runtime security.

As you can see, Java’s security model revolves around the code and covers the entire process from class loading, such as loading Java classes from the network using URLClassLoader, to runtime permission checks of applications.

  • Additionally, in principle, Java’s resource management mechanisms such as GC can also be considered part of runtime security. If the corresponding mechanisms fail, it can lead to JVM errors like OOM, which can be seen as a form of denial of service.

Second, Java provides security framework APIs, which serve as the foundation for building secure communication and other applications. For example:

  • Encryption and decryption APIs.
  • Authorization and authentication APIs.
  • Security-related libraries for communication, such as the basic implementation of HTTPS communication protocol, like TLS 1.3, or auxiliary protocol implementations for certificate revocation status checking (OSCP), and so on.

Note that the implementation of these APIs is vendor-specific. Different JDK vendors often customize their own encryption algorithm implementations.

Third, various security tools integrated into the JDK, for example:

  • keytool, a powerful tool for managing essential keys, certificates, and keystore files used by Java programs.
  • jarsigner is used for signing or verifying JAR files.

In practical application, if security is highly required, it is recommended to enable the SecurityManager by using the following command line option:

-Djava.security.manager

Please note that enabling the SecurityManager can result in a performance decrease of about 10% to 15%. Starting from JDK 9, this performance overhead has been improved.

After understanding the basic Java security mechanism, let’s discuss about security vulnerabilities.

Traditionally, any program flaw that can be used to bypass system security policies is considered a security vulnerability. There can be multiple reasons for this, such as design or implementation flaws, configuration errors, etc. Any negligence can lead to the occurrence of security vulnerabilities. For example, malicious code bypassing the Java sandbox restrictions to gain privileges. If you want to learn more about security vulnerabilities, you can obtain information from Common Vulnerabilities and Exposures (CVE) database and understand the security vulnerability evaluation standards.

However, achieving the goal of an attack does not necessarily require bypassing permission restrictions. For example, launching a Denial-of-Service attack using hash collisions. In common scenarios, an attacker can construct a large number of data with the same hash value and send it to the server in the form of JSON data. The server usually stores this data in a Hashtable or HashMap. Hash collisions can cause serious degradation of the hash table, which might lead to a significant increase in algorithmic complexity (HashMap has been improved with the introduction of treeification mechanism, which I explained in Chapter 9). As a result, a large amount of CPU resources will be consumed.

Attacks like this, which are unrelated to permissions, can be considered as flaws in program implementation, providing attackers with low-cost opportunities for attacks.

There are different perspectives and approaches to address various types of injection attacks. For example, for SQL injection:

  • During the data input stage, bridge the gap between expected input and possible input. Input validation can be performed to restrict what types of input are allowed, such as disallowing special characters like punctuation marks or specific structured input.
  • When accessing the database in a Java application, if you are not using fully dynamic SQL, utilizing PreparedStatement can effectively prevent SQL injection. Whether it is SQL injection or operating system command injection, the program using string concatenation to generate logic execution has potential risks!
  • At the database level, reasonable restrictions on query, modification, and other permissions can help avoid injection of destructive code.

In the field of security, there is a principle: security tends to be “obviously without vulnerabilities,” rather than “without obvious vulnerabilities.” Therefore, to provide a more secure and reliable service, it is best to adopt comprehensive security design and comprehensive preventive measures, rather than patching issues on an ad-hoc basis or relying on luck.

A general recommendation is to use newer versions of JDK and follow the recommended security mechanisms and standards. If you have read JDK release notes, such as 8u141, you will find that JDK updates fix known security vulnerabilities and enhance security mechanisms. However, the reality is that a significant portion of applications are still developed using very old and insecure versions of JDK, and many information processing processes are not properly handled, or transmitted and stored in plain text, which poses potential security risks.

Today, I first introduced typical injection attacks, then summarized the internal security mechanisms of Java, and discussed what security vulnerabilities are and their typical manifestations, as well as how to prevent SQL injection attacks. I hope this information is helpful to you.

Practice Exercise #

Do you have a clear understanding of the topic we discussed today? Today’s discussion question is about Man-In-The-Middle (MITM) attacks. Do you know what they are? What are some common forms of these attacks? How can they be prevented?

Please write your thoughts on this question in the comments section. I will select the most thoughtful comments and send you a learning reward voucher. I welcome you to join me in the discussion.

On July 19th, this Thursday, at 8:30 PM, I will be a guest on Geek Live and host a live sharing session on the topic “Mastering Java Interviews in 1 Hour”. I will talk about everything related to Java interviews. Don’t miss out if you’re interested.

Are your friends also preparing for interviews? You can “ask your friends to read” by sharing today’s question with them. Maybe you can help them out.