9 Scala security issues you should know about

Here is a list of 9 security issues we feel every Scala developer should know about and try to avoid:

1. Avoid Object deserialization of untrusted data

Object deserialization of untrusted data can lead to remote code execution, if there is a class in classpath allow the trigger of malicious operation.

Libraries developers tend to fix classes that provided potential malicious trigger. There are still classes that are known to trigger Denial of Service.

Deserialization is a sensible operation that has a great history of vulnerabilities. The web application might become vulnerable has soon as a new vulnerability is found in the Java Virtual Machine.

Code at risk:

public UserData deserializeObject(InputStream receivedFile) throws IOException, ClassNotFoundException {
try (ObjectInputStream in = new ObjectInputStream(receivedFile)) {
        return (UserData) in.readObject();
    }
}

Solution:

Avoid deserializing object provided by remote users.

2. Avoid using the NullCipher

The NullCipher is seldom used intentionally in production applications. It implements the Cipher interface by returning ciphertext identical to the supplied plaintext. In a few contexts, such as testing, a NullCipher may be appropriate.

Solution:

Avoid using the NullCipher. Its accidental use can introduce a significant confidentiality risk.

3. Enforce secure RSA usage — RSA algorithm must have padding set.

Usage of the RSA algorithm without Optimal Asymmetric Encryption Padding (OAEP) might weaken encryption.

Vulnerable Code:

Cipher.getInstance("RSA/NONE/NoPadding")

Solution:

Cipher.getInstance("RSA/ECB/OAEPWithMD5AndMGF1Padding")

4. indexOf checks should be for negative numbers

Any checks that look for values > 0 ignore the first element, which is likely a bug.

Most checks against an indexOf value compare it with -1 because 0 is a valid index. Any checks which look for values > 0 ignore the first element, which is likely a bug. If the intent is merely to check inclusion of a value in a String or a List, consider using the contains method instead.

For strings, if the intent is truly to find the first index after a specific character index, then use the version ofindexOf which takes a start position argument.

This rule raises an issue any time an indexOf value retrieved either from a String or a List is tested for a positive value.

Noncompliant Code Example:

val color = "blue"
  val name = "ishmael"
val strings = List(color, name)
if (strings.indexOf(color) > 0) {
    // Noncompliant
  }
if (name.indexOf("ish") > 0) {
    // Noncompliant
  }
if (name.indexOf("hma") > 2) {
    // Noncompliant
  }

Compliant Solution:
val color = "blue"
val name = "ishmael"
val strings = List(color, name)
if (strings.indexOf(color) > -1) {
  // ...
}
if (name.indexOf("ish") >= 0) {
  // ...
}
if (name.indexOf("hma") > -1) {
  // ...
}

5. indexOf checks should use a start position

indexOf with start position argument is clearer because the result is tested against -1, which is an easily recognizable ‘not found’ indicator.

One thing that makes good code good is the clarity with which it conveys the intent of the original programmer to maintainers, and the proper choice of indexOf methods can help move code from confusing to clear.

If you need to see whether a substring is located beyond a certain point in a string, you can test the indexOfthe substring versus the target point, or you can use the version of indexOf which takes a starting point argument. The latter is arguably clearer because the result is tested against -1, which is an easily recognizable not found indicator.

Noncompliant Code Example:

String name = "ismael";
if (name.indexOf("ae") > 2) { // Noncompliant
  // ...
}

Compliant Solution:
String name = "ismael";
if (name.indexOf("ae", 2) > -1) {
  // ...
}

6. java.lang.Error should not be extended

java.lang.Error and its subclasses represent abnormal conditions, such as OutOfMemoryError, which should only be encountered by the Java Virtual Machine.

Noncompliant Code Example:

public class MyException extends Error { /* ... */ }       // Noncompliant

Compliant Solution:

public class MyException extends Exception { /* ... */ }   // Compliant

7. Prevent Path Traversal

The Path Traversal attack technique allows an attacker access to files, directories, and commands that potentially reside outside the web document root directory. An attacker may manipulate a URL in such a way that the web site will execute or reveal the contents of arbitrary files anywhere on the web server. Any device that exposes an HTTP-based interface is potentially vulnerable to Path Traversal.

Most web sites restrict user access to a specific portion of the file system, typically called the “web document root” or “CGI root” directory. These directories contain the files intended for user access and the executable necessary to drive web application functionality. To access files or execute commands anywhere on the filesystem, Path Traversal attacks will utilize the ability of special characters sequences.

The most basic Path Traversal attack uses the “../” special character sequence to alter the resource location requested in the URL. Although most popular web servers will prevent this technique from escaping the web document root, alternate encodings of the “../” sequence may help bypass the security filters. These method variations include valid and invalid Unicode-encoding (“..%u2216” or “..%c0%af”) of the forward slash character, backslash characters (“..”) on Windows-based servers, URL encoded characters (“%2e%2e%2f”), and double URL encoding (“..%255c”) of the backslash character. Even if the web server properly restricts Path Traversal attempts in the URL path, a web application itself may still be vulnerable due to improper handling of user-supplied input. This is a common problem of web applications that use template mechanisms or load static text from files. In variations of the attack, the original URL parameter value is substituted with the file name of one of the web application’s dynamic scripts. Consequently, the results can reveal source code because the file is interpreted as text instead of an executable script. These techniques often employ additional special characters such as the dot (“.”) to reveal the listing of the current working directory, or “%00” NULL characters in order to bypass rudimentary file extension checks.

Example:

http://example/../../../../../etc/passwd
http://example/..%255c..%255c..%255cboot.ini
http://example/..%u2216..%u2216someother/file

8. Prohibit insecure ciphers

DES and DESede (3DES) are not considered strong ciphers for modern applications. They should be replaced by AES block cipher.

An example of weak code:

Cipher c = Cipher.getInstance("DESede/ECB/PKCS5Padding");
c.init(Cipher.ENCRYPT_MODE, k, iv);
byte[] cipherText = c.doFinal(plainText);

Replaced with a stronger cipher:

Cipher c = Cipher.getInstance("AES/GCM/NoPadding");
c.init(Cipher.ENCRYPT_MODE, k, iv);
byte[] cipherText = c.doFinal(plainText);

9. Prohibit unencrypted sockets

When using an unencrypted Socket the traffic could be read by an attacker intercepting the network traffic.

Vulnerable Code:

Socket soc = new Socket("www.google.com",80);

Solution:

Socket soc = SSLSocketFactory.getDefault().createSocket("www.google.com", 443);

Enforce them now with Codacy

About Codacy

Codacy is used by thousands of developers to analyze billions of lines of code every day!

Getting started is easy – and free! Just use your  GitHub, Bitbucket or Google account to sign up.

GET STARTED

PS: We just published an ebook: “The Ultimate Guide to Code Review” based on a survey of 680+ developers. Enjoy!

Best PracticesSecurity

Related Articles