Prevent denial of service in Java applications
A denial-of-service (DoS) is any type of attack where the attackers (hackers) attempt to prevent legitimate users from accessing the service.
In JAVA SE applications, there are many ways a DOS can be triggered. Here the guidelines:
Beware of activities that may use disproportionate resources
―Requesting a large SVG
―"Billion laughs attack"
―Hash table keys insertion with the same hash code
―Consuming XPath expressions
―Malicious data (de)serialization
―Excessive output to log
Release resources in all cases
Resources should always be released promptly no matter what.
Even experienced programmers often handle resources incorrectly.
―Execute Around Method pattern
―Use Java SE 7 try-with-resource syntax
―Ensure that any output buffers are flushed
Resource limit checks should not suffer from integer overflow
―Some operations on primitive integral types silently overflow.
―Take care when checking resource limits.
Injection and Inclusion
=>Attack causing a program to interpret bad crafted data changing app control.
Generate valid formatting
―Prevent maliciously crafted inputs causing incorrect formatting of outputs.
Avoid dynamic SQL
―Beware of dynamically created SQL statements including untrusted input.
―Use java.sql PreparedStatement or CallableStatement instead of Statement.
XML and HTML generation requires care
―Untrusted data included in HTML/XML can lead to Cross-Site Scripting (XSS) and XML Injection.
―Use a library to filter, escape, or encode unsafe characters.
Avoid any untrusted data on the command line
―When creating new processes, do not place any untrusted data on the command line but pass it as Base64 encoded arguments, or in a temporary file, or through an inherited channel.
Restrict XML inclusion
―XML External Entity (XXE) attacks insert local files into XML data.
―The safest way to avoid this is to reduce privileges.
Care with BMP files
―Avoid BMP files.
Disable HTML display in Swing components
―Disable the HTML render feature of Swing pluggable look-and-feels.
Take care interpreting untrusted code
―Use secure sandbox to execute untrusted code
Prevent injection of exceptional floating point values
=>Confidential data should be readable only within a limited context. Data that is to be trusted should not be exposed to tampering. Privileged code should not be executable through intended interfaces.
Purge sensitive information from exceptions
―Exception objects may convey sensitive information.
(ie: java.io.FileNotFoundException exposing the file path with user's name or home directory.)
―Internal exceptions should be caught and sanitized before propagating them to upstream callers.
―Be careful when depending on an exception for security because its contents may change in the future.
―Do not include exception stack traces inside HTML comments.
Do not log highly sensitive information
―Data such as Social Security numbers (SSNs) and passwords, is highly sensitive.
―It should not be sent to log files and its presence should not be detectable through searches.
Consider purging highly sensitive information from memory after use
―To narrow the window when highly sensitive information may appear in core dumps, debugging, and confidentiality attacks, it may be appropriate to zero memory containing the data immediately after use.
=>Rigorous method parameter checking is used to improve robustness. More generally, validating external inputs is an important part of security.
―Maliciously crafted inputs may cause problems, whether coming through method arguments or external streams.
―Examples include overflow of integer values and directory traversal attacks by including "../" sequences in filenames.
Validate output from untrusted objects as input
―Method arguments should be validated but not return values.
―In the case of an upcall (invoking a method of higher level code) the returned value should be validated.
―A subtle example would be Class objects returned by ClassLoaders.
Define wrappers around native methods
―Java code is subject to runtime checks for type, array bounds, and library usage.
―Native code, on the other hand, is generally not.
―While pure Java code is effectively immune to traditional buffer overflow attacks, native methods are not.
To offer some of these protections during the invocation of native code, do not declare a native method public.
Instead, declare it private and expose the functionality through a public Java-based wrapper method.
Accessibility and Extensibility
=>The task of securing a system is made easier by reducing the "attack surface" of the code.
Limit the accessibility of classes, interfaces, and fields
―Make pulic only what is exposed by API
―Mark the packages as sealed in the jar file manifest
Limit accessibility of packages
―Hide container implementation code by adding it to the package.access security property
Isolate unrelated code
―Libraries require a level of trust at least equal to the code it is used by in order not to violate the integrity of the client code.
Limit exposures of classloader instances
―Access to ClassLoader instances allows certain operations that may be undesirable: access enability, URL information retrieving, turn on/off assertion, classloader side effect
Limit extensibility of classes and methods
―Design classes and methods for inheritance or declare them final.
―Prefer composition to inheritance.
Understand how a superclass can affect subclass behavior
―Changes to a superclass can unintentionally lead to subtle security vulnerabilities.
―Monitor all interfaces implemented by the class, due to their default methods possible unexpected access
=>Mutability, whilst appearing innocuous, can cause a surprising variety of security problems.
Prefer immutability for value types
Create copies of mutable output values
Create safe copies of mutable and subclassable input values
Support copy functionality for a mutable class
Do not trust identity equality when overridable on input reference objects
Treat passing input to untrusted object as output
reat output from untrusted object as input
Define wrapper methods around modifiable internal state
Make public static fields final
Ensure public static final field values are constants
Do not expose mutable statics
Do not expose modifiable collections
=>During construction objects are at an awkward stage where they exist but are not ready for use. Such awkwardness presents a few more difficulties in addition to those of ordinary methods.
Avoid exposing constructors of sensitive classes
―Define static factory methods instead of public constructors.
―Prefer delegation over inheritance.
―Avoid construct through serialization and clone.
Prevent the unauthorized construction of sensitive classes
―A security-sensitive class enables callers to modify or circumvent SecurityManager access controls.
―To restrict untrusted code from instantiating a class, enforce a SecurityManager check at all points where that class can be instantiated.
Defend against partially initialized instances of non-final classes
Prevent constructors from calling methods that can be overridden
―Constructors that call overridable methods give attackers a reference to this (the object being constructed) before the object has been fully initialized.
Defend against cloning of non final classes
―A non-final class may be subclassed by a class that also implements java.lang.Cloneable.
―The result is that the base class can be unexpectedly cloned.
Serialization & Deserialization
=>Java Serialization provides an interface to classes that sidesteps the field access control mechanisms of the Java language. As a result, care must be taken when performing serialization and deserialization
Avoid serialization for security-sensitive classes
―Making a class serializable effectively creates a public interface to all fields of that class
―Serialization adds a hidden public constructor to a class
Guard sensitive data during serialization
―Once an object has been serialized, attackers can access private fields in an object by analyzing its serialized byte stream
View deserialization the same as object construction
―Deserialization creates a new instance of a class without invoking any constructor on that class
―Deserialization should be designed to behave like normal construction
Duplicate the securitymanager checks enforced in a class during serialization and deserialization
―Prevent an attacker from using serialization or deserialization to bypass the SecurityManager checks enforced in a class
Understand the security permissions given to serialization and deserialization
―Permissions appropriate for deserialization should be carefully checked
Filter untrusted serial data