Security Guide For Java Developers
Security Guide For Java Developers
Security Guide For Java Developers
Java Developers
I
N Overview...................................................................1
D
Java Risk: Insecure Deserialization..........................3
E
API...........................................................................5
X
The Last Word in Java Security...............................10
e w
Over v i
The Java programming language is versatile and powerful.
It can be used in a wide variety of settings to allow developers
to create robust, high-performance applications — from small
devices all the way up to large enterprise systems. Despite
its age, Java remains one of the most popular programming
languages in use today. Developers appreciate its stability,
ease of development, and vast ecosystem of libraries and tools.
When Java came out in the mid-1990s, it promised to revolutionize programming languages at a time
when a lot of business programming was done in C or C++. People who have experienced those
languages in a professional setting know that they can be full of potential problems that at times can be
hard to detect. Java basically removed many of those pitfalls. For example, instead of worrying about
allocating and freeing memory manually, Java does all of that for you. This eliminates a whole class of
vulnerabilities, and as a result, Java has gained a reputation as being more secure than other
programming languages. However, just because Java is considered more secure overall doesn’t mean
that every piece of code written in Java is automatically secure.
This Java security guide will help organizations prepare effective approaches for securely developing in
Java language. The guide highlights specific risks Java developers face and demonstrates what
proactive steps can be taken to protect these applications. This guide will explore the following topics
and top common risks:
Finally, there have been numerous cases where attackers have exploited flaws in the way that Java
implements SSL/TLS encryption to eavesdrop on communications or even inject malicious content into
what appears to be a secure connection.
While these vulnerabilities and attacks may not be unique to Java — indeed, most attack vectors and
patterns can be broadly categorized into similar classifications or taxonomies — the way they are
executed and defended against specifically in Java will differ from other programming languages.
Security risks in Java can be potentially costly for organizations if left unaddressed. Consider the cost of
each of these risks:
• Malware infections: Java-based malware is becoming increasingly prevalent and can easily
infect systems that have not been properly secured. Once infected, these systems may be used to
launch attacks against other computers on the network or to steal sensitive data. Some estimates
put the cost of a malware attack at $2.5 million.
• Denial of service attacks: Unsecured Java applications can be exploited by attackers to launch
denial of service (DoS) attacks, which can cause significant disruptions and cost businesses
dearly in terms of lost productivity and revenue. Some reports indicate that DoS attacks cost
$22,000 for every minute of downtime.
• Data security breaches: Poorly secured Java apps may also provide an easy way for hackers to
gain access to sensitive corporate data stored on the server or in databases connected to the
application. This could lead to serious financial losses as well as reputational damage for the
affected organization. While data breach damages are much harder to put an average to in a way
that is innately classifiable and meaningful, there are some estimates placing the average costs
associated with data breaches at $4.54 million when coupled with ransomware.
Neglecting application security for Java can present very real potential consequences for your company.
User input isn’t the only way an attacker can exploit insecure deserialization. They can also target
serialized objects stored in files or databases. If these objects are not properly validated before being
unserialized, an attacker could modify them in a way that allows them to execute arbitrary code when
loaded by the application. Additionally, if an application log contains serialized objects, an attacker could
tamper with it to insert malicious data that would be executed when viewed later.
Exploiting insecure deserialization usually requires some knowledge of how the targeted application
works and what kind of data it stores internally (e.g., object types and structure). However, tools are
available that automate this process by generating payloads specifically designed to attack common
vulnerabilities like those described above.
To mitigate this risk, it is important to only deserialize data from trusted sources and/or use a platform
that has built-in protections against insecure deserialization vulnerabilities. When data is deserialized, it
is converted back into an object from its serialized form. This process can be exploited if the data comes
from an untrusted source, as malicious code could be executed when the object is reconstituted. Thus,
it is important to only deserialize data that comes from a trusted source. Using a platform with built-in
protections against insecure deserialization vulnerabilities can further mitigate this risk.
In other cases, insufficient authorization and authentication checks may be due simply due to
carelessness or rushing through the implementation phase without thoroughly testing all possible
scenarios. Either way, failing to properly check permissions leaves your application vulnerable to attack.
There are two main ways that you can mitigate this risk:
In Java, password hashing is a process where the user’s password is run through a one-way mathematical
function. The outcome of the function is then stored in the database instead of the actual password.
When a user attempts to log in, their inputted password is run through the same hash function. If the
output of both functions matches, the authentication is successful and access can be granted.
There are many ways to hash passwords, but some common methods include SHA-256 and bcrypt. It’s
important to note that when storing hashed passwords, you should never use plain text or reversible
encryption. Doing so would defeat the purpose of hashing.
For example, a common way to implement authorization checks is through Java’s Access Control Lists
(ACLs). ACLs are used to define which users or groups have access to which resources. They can also be
used to specify the type of access (e.g., read, write, execute) a particular user or group has. By properly
configuring ACLs, you can help ensure that users have access to only those resources they are
authorized for.
Another way you can mitigate the risk of insufficient authorization and authentication in Java is by using
security policies. Security policies typically contain instructions on how your application should handle
various security-related tasks such as authenticating users, authorizing access control decisions, and
encrypting data in transit. With clear security policies that are followed strictly throughout your
development process, everyone involved in building and maintaining your application will know exactly
what needs to be done to maintain security.
DES was broken in the late 1990s by brute force attacks with specialized
hardware. DES has a key size of only 56 bits, which is too small to resist modern
attack methods. AES was designed to be a replacement for DES and uses much
larger key sizes by default (128, 192, or 256 bits). AES is also resistant to known
attacks as of 2019 but may eventually become vulnerable as computers
continue to get more powerful.
It’s important to use strong cryptography when developing Java applications. Weak algorithms can lead
to data being compromised by attackers who can break them. When choosing an algorithm, it’s
important to consider not only its strength today but also its potential future vulnerabilities so that you
can select one that will remain secure for years to come.
For example, let’s say you have a key that you use to encrypt sensitive data. If this key is compromised
(e.g., someone steals it from your database), then all of your data can be accessed by the attacker. This is
why proper key management is so important; if done correctly, it can help to mitigate the risks
associated with data breaches and other security incidents.
One way to generate random numbers in Java is with the java.security.SecureRandom class. This class
uses a strong source of entropy, such as /dev/urandom on Linux systems, so that the output is truly
random and secure. To initialize the SecureRandom object properly, you need to seed it with data from a
reliable source of entropy like /dev/urandom.
Another issue with Java’s cryptographic API is that some methods may be less secure than others or
more suited for a particular use case. For example, there are multiple ways to generate random numbers
in Java and each has its own set of trade-offs:
There are two primary ways that attackers can exploit vulnerable code using reflection:
This type of attack can be difficult to detect and defend against because it
exploits vulnerabilities in the code itself rather than anything on the system level
(such as permissions). As such, it’s important for developers who are writing code
that will use reflection to ensure that all possible inputs are properly validated
before processing them.
Attackers can use reflective invocations from within Classes loaded with
different class loaders, for example, and invoke private methods from within
different classes. Successful attempts to exploit vulnerable Java code using
reflection can lead to attacks that then target other vulnerabilities, such as
insecure deserialization
To prevent SQL injection attacks, it is important to validate and sanitize all user input before inserting it
into a command or query. For example, when building SQL queries, use parameterized queries instead of
concatenating strings together. Additionally, make sure you are using an up-to-date database driver that
supports parameters.
LDAP injections happen when an application inserts unsanitized inputs directly into an LDAP statement.
When this occurs, the attacker can use control characters in the input to modify the LDAP filter syntax
causing the server to execute unintended queries or unintentionally disclose data stored in fields
accessible via query results (e.g execution of logical operators such as OR or !). The easiest way to
prevent LDAP injection is to ensure that user input does not contain any special characters used in LDAP
filters, such as ( ) * & | !
If user input must contain one of these characters, then consider using whitespace as a delimiter
between multiple terms entered by users e.g. “a b c” instead of “a&b|c”.
It’s best to preemptively look into each specific type of injection flaw and its own set of best practices for
prevention.
Kiuwan provides static application security testing (SAST) through Kiuwan Code Security, which is
compliant with standards such as OWASP and Common Weakness Enumeration (CWE). Additionally,
Kiuwan offers software composition analysis (SCA), called Kiuwan Insights Open Source. This SCA reduces
risk from third-party components, assists in addressing vulnerabilities, and ensures license compliance
as well as policy automation throughout your software development life cycle.
Java applications can be made more secure with Kiuwan. In addition to Java, Kiuwan’s security
capabilities cover more than 30 coding languages. Schedule a demo with Kiuwan today.
GET IN TOUCH: