SonarQube Vulnerability Report

Report Generated On
Thu Aug 01 2019
Project Name
java tomcat
Application
tomcat
Release
1.0.0
Delta analysis
No

Summary of the Detected Vulnerabilities

Severity Number of Issues
BLOCKER 1
CRITICAL 0
MAJOR 0
MINOR 0

Detail of the Detected Vulnerabilities

Rule Severity Component Line Description Message Key
squid:S2068 BLOCKER modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/DataSourceFactory.java 66 Credentials should not be hard-coded 'PASSWORD' detected in this expression, review this potentially hardcoded credential. AWK40IMu-pl6AHs22MnV

Known Security Rules

Rule Description
squid:S2658

Dynamically loaded classes could contain malicious code executed by a static class initializer. I.E. you wouldn't even have to instantiate or explicitly invoke methods on such classes to be vulnerable to an attack.

This rule raises an issue for each use of dynamic class loading.

Noncompliant Code Example

String className = System.getProperty("messageClassName");
Class clazz = Class.forName(className);  // Noncompliant

See

squid:S3369

Websphere, Tomcat, and JBoss web servers allow the definition of role-based access to servlets. It may not be granular enough for your purposes, but it's a start, and should be used at least as a base.

This rule raises an issue when a web.xml file has no <security-constraint> elements.

See

squid:S2039

Failing to explicitly declare the visibility of a member variable could result it in having a visibility you don't expect, and potentially leave it open to unexpected modification by other classes.

Noncompliant Code Example

class Ball {
    String color="red";  // Noncompliant
}
enum A {
  B;
  int a;
}

Compliant Solution

class Ball {
    private String color="red";  // Compliant
}
enum A {
  B;
  private int a;
}

Exceptions

Members annotated with Guava's @VisibleForTesting annotation are ignored, as it indicates that visibility has been purposely relaxed to make the code testable.

class Cone {
  @VisibleForTesting
  Logger logger; // Compliant
}
javasecurity:S5135

User provided data such as URL parameters, POST data payloads or cookies should always be considered untrusted and tainted. Deserialization based on data supplied by the user could result in two types of attacks:

  • Remote code execution attacks, where the structure of the serialized data is changed to modify the behavior of the object being unserialized.
  • Parameter tampering attacks, where data is modified to escalate privileges or change for example quantity or price of products.

The problem could be mitigated in any of the following ways:

  • Instead of using a native data interchange format, use a safe, standard format such as JSON.
  • To ensure integrity is not compromised, add a digital signature to the serialized data that is validated before deserialization.
  • As a last resort, restrict deserialization to be possible only to specific, whitelisted classes.

Noncompliant Code Example

public class RequestProcessor {
  protected void processRequest(HttpServletRequest request) {
    ServletInputStream sis = request.getInputStream();
    ObjectInputStream ois = new ObjectInputStream(sis);
    Object obj = ois.readObject(); // Noncompliant
  }
}

Compliant Solution

public class SecureObjectInputStream extends ObjectInputStream {
  // Constructor here

  @Override
  protected Class<?> resolveClass(ObjectStreamClass osc) throws IOException, ClassNotFoundException {
    // Only deserialize instances of AllowedClass
    if (!osc.getName().equals(AllowedClass.class.getName())) {
      throw new InvalidClassException("Unauthorized deserialization", osc.getName());
    }
    return super.resolveClass(osc);
  }
}

public class RequestProcessor {
  protected void processRequest(HttpServletRequest request) {
    ServletInputStream sis = request.getInputStream();
    SecureObjectInputStream sois = new SecureObjectInputStream(sis);
    Object obj = sois.readObject();
  }
}

See

javasecurity:S5334

Applications that execute code dynamically should neutralize any externally-provided values used to construct the code. Failure to do so could allow an attacker to execute arbitrary code. This could enable a wide range of serious attacks like accessing/modifying sensitive information or gain full system access.

The mitigation strategy should be based on whitelisting of allowed values or casting to safe types.

Noncompliant Code Example

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
  String input = req.getParameter("input");

  ScriptEngineManager manager = new ScriptEngineManager();
  ScriptEngine engine = manager.getEngineByName("JavaScript");
  engine.eval(input); // Noncompliant
}

Compliant Solution

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
  String input = req.getParameter("input");

  // Match the input against a whitelist
  if (!whiteList.contains(input))
    throw new IOException();

  ScriptEngineManager manager = new ScriptEngineManager();
  ScriptEngine engine = manager.getEngineByName("JavaScript");
  engine.eval(input);
}

See

javasecurity:S3649

User provided data, such as URL parameters, should always be considered untrusted and tainted. Constructing SQL queries directly from tainted data enables attackers to inject specially crafted values that change the initial meaning of the query itself. Successful SQL injection attacks can read, modify, or delete sensitive information from the database and sometimes even shut it down or execute arbitrary operating system commands.

Typically, the solution is to rely on prepared statements rather than string concatenation to inject tainted data into SQL queries, which ensures that they will be properly escaped.

This rule supports: JDBC, Java EE Entity Manager, Spring Framework, Hibernate, JDO, Android Database, Apache Torque, Rapidoid.

Noncompliant Code Example

public boolean authenticate(javax.servlet.http.HttpServletRequest request, java.sql.Connection connection) throws SQLException {
  String user = request.getParameter("user");
  String pass = request.getParameter("pass");

  String query = "SELECT * FROM users WHERE user = '" + user + "' AND pass = '" + pass + "'"; // Unsafe

  // If the special value "foo' OR 1=1 --" is passed as either the user or pass, authentication is bypassed
  // Indeed, if it is passed as a user, the query becomes:
  // SELECT * FROM users WHERE user = 'foo' OR 1=1 --' AND pass = '...'
  // As '--' is the comment till end of line syntax in SQL, this is equivalent to:
  // SELECT * FROM users WHERE user = 'foo' OR 1=1
  // which is equivalent to:
  // SELECT * FROM users WHERE 1=1
  // which is equivalent to:
  // SELECT * FROM users

  java.sql.Statement statement = connection.createStatement();
  java.sql.ResultSet resultSet = statement.executeQuery(query); // Noncompliant
  return resultSet.next();
}

Compliant Solution

public boolean authenticate(javax.servlet.http.HttpServletRequest request, java.sql.Connection connection) throws SQLException {
  String user = request.getParameter("user");
  String pass = request.getParameter("pass");

  String query = "SELECT * FROM users WHERE user = ? AND pass = ?"; // Safe even if authenticate() method is still vulnerable to brute-force attack in this specific case

  java.sql.PreparedStatement statement = connection.prepareStatement(query);
  statement.setString(1, user); // Will be properly escaped
  statement.setString(2, pass);
  java.sql.ResultSet resultSet = statement.executeQuery();
  return resultSet.next();
}

See

roslyn.sonaranalyzer.security.cs:S2078

User provided data such as URL parameters should always be considered as untrusted and tainted. Constructing LDAP names or search filters directly from tainted data enables attackers to inject specially crafted values that changes the initial meaning of the name or filter itself. Successful LDAP injections attacks can read, modify or delete sensitive information from the directory service.

Within LDAP names, the special characters ' ', '#', '"', '+', ',', ';', '<', '>', '\' and null must be escaped according to RFC 4514, for example by replacing them with the backslash character '\' followed by the two hex digits corresponding to the ASCII code of the character to be escaped. Similarly, LDAP search filters must escape a different set of special characters (including but not limited to '*', '(', ')', '\' and null) according to RFC 4515.

Noncompliant Code Example

public class LDAPInjection : Controller
{
  public DirectorySearcher ds { get; set; }

  // GET /LDAPInjection/Authenticate
  public IActionResult Authenticate(string user, string pass)
  {
    ds.Filter = "(&(uid=" + user + ")(userPassword=" + pass + "))"; // Noncompliant

    // If the special value "*)(uid=*))(|(uid=*" is passed as user, authentication is bypassed
    // Indeed, if it is passed as a user, the filter becomes:
    // (&(uid=*)(uid=*))(|(uid=*)(userPassword=...))
    // as uid=* match all users, it is equivalent to:
    // (|(uid=*)(userPassword=...))
    // again, as uid=* match all users, the filter becomes useless

    return Content(ds.FindOne() != null ? "success" : "fail");
  }
}

Compliant Solution

public class LDAPInjection : Controller
{
  public DirectorySearcher ds { get; set; }

  // GET /LDAPInjection/Authenticate
  public IActionResult Authenticate(string user, string pass)
  {
    // Restrict the username and password to letters only
    if (!Regex.IsMatch(user, "^[a-zA-Z]+$") || !Regex.IsMatch(pass, "^[a-zA-Z]+$"))
    {
      return BadRequest();
    }

    ds.Filter = "(&(uid=" + user + ")(userPassword=" + pass + "))"; // Now safe
    return Content(ds.FindOne() != null ? "success" : "fail");
  }
}

See

roslyn.sonaranalyzer.security.cs:S3649

User provided data, such as URL parameters, should always be considered untrusted and tainted. Constructing SQL or SQL-like queries directly from tainted data enables attackers to inject specially crafted values that change the initial meaning of the query itself. Successful database query injection attacks can read, modify, or delete sensitive information from the database and sometimes even shut it down or execute arbitrary operating system commands.

Typically, the solution is to rely on prepared statements rather than string concatenation to inject tainted data into database queries, which ensures that they will be properly escaped.

Noncompliant Code Example

public class SqlInjection : Controller
{
  private readonly UsersContext _context;

  public SqlInjection(UsersContext context)
  {
    _context = context;
  }

  // GET /SqlInjection/Authenticate
  public IActionResult Authenticate(string user)
  {
    var query = "SELECT * FROM Users WHERE Username = '" + user + "'"; // Unsafe
    var userExists = _context.Users.FromSql(query).Any(); // Noncompliant

    // An attacker can bypass authentication by setting user to this special value
    user = "' or 1=1 or ''='";

    return Content(userExists ? "success" : "fail");
  }
}

Compliant Solution

public class SqlInjection : Controller
{
  private readonly UsersContext _context;

  public SqlInjection(UsersContext context)
  {
    _context = context;
  }

  // GET /SqlInjection/Authenticate
  public IActionResult Authenticate(string user)
  {
    var query = "SELECT * FROM Users WHERE Username = {0}"; // Safe
    var userExists = _context.Users.FromSql(query, user).Any();
    return Content(userExists ? "success" : "fail");
  }
}

See

roslyn.sonaranalyzer.security.cs:S2091

User provided data, such as URL parameters, should always be considered untrusted and tainted. Constructing XPath expressions directly from tainted data enables attackers to inject specially crafted values that changes the initial meaning of the expression itself. Successful XPath injection attacks can read sensitive information from XML documents.

Noncompliant Code Example

public class XPathInjection : Controller
{
  public XmlDocument doc { get; set; }

  // GET /XPathInjection/Authenticate
  public IActionResult Authenticate(string user, string pass)
  {
    String expression = "/users/user[@name='" + user + "' and @pass='" + pass + "']"; // Unsafe

    // An attacker can bypass authentication by setting user to this special value
    user = "' or 1=1 or ''='";

    return Content(doc.SelectSingleNode(expression) != null ? "success" : "fail"); // Noncompliant
  }
}

Compliant Solution

public class XPathInjection : Controller
{
  public XmlDocument doc { get; set; }

  // GET /XPathInjection/Authenticate
  public IActionResult Authenticate(string user, string pass)
  {
    // Restrict the username and password to letters only
    if (!Regex.IsMatch(user, "^[a-zA-Z]+$") || !Regex.IsMatch(pass, "^[a-zA-Z]+$"))
    {
      return BadRequest();
    }

    String expression = "/users/user[@name='" + user + "' and @pass='" + pass + "']"; // Now safe
    return Content(doc.SelectSingleNode(expression) != null ? "success" : "fail");
  }
}

See

phpsecurity:S2631

Evaluating regular expressions against input strings can be an extremely CPU-intensive task. For example, a specially crafted regular expression such as (a+)++ will take several seconds to evaluate the input string, aaaaaaaaaaaaaaaaaaaaaaaaaaaaa!. The problem is that every additional "a" added to the input doubles the time required to evaluate the regex. However, the equivalent regular expression, a (without grouping), is efficiently evaluated in milliseconds and scales linearly with the input size.

Evaluating user-provided strings as regular expressions opens the door for Denial Of Service attacks. In the context of a web application, attackers can force the web server to spend all of its resources evaluating regular expressions thereby making the service inaccessible to genuine users.

Noncompliant Code Example

$regex = $_GET["regex"];
$input = $_GET["input"];

// Enables attackers to force the web server to evaluate
// regex such as "(a+)+" on inputs such as "aaaaaaaaaaaaaaaaaaaaaaaaaaaaa!"

preg_grep ( $regex, $input ); // Noncompliant

Compliant Solution

$input = $_GET["input"];

preg_grep ( "a+", $input ); // Compliant - use a safe hardcoded regex

See

phpsecurity:S5135

User provided data such as URL parameters, POST data payloads or cookies should always be considered untrusted and tainted. Deserialization based on data supplied by the user could result in two types of attacks:

  • Remote code execution attacks, where the structure of the serialized data is changed to modify the behavior of the object being unserialized.
  • Parameter tampering attacks, where data is modified to escalate privileges or change for example quantity or price of products.

The problem could be mitigated in any of the following ways:

  • Instead of using a native data interchange format, use a safe, standard format such as JSON.
  • To ensure integrity is not compromised, add a digital signature to the serialized data that is validated before deserialization.
  • As a last resort, restrict deserialization to be possible only to specific, whitelisted classes.

Noncompliant Code Example

$data = $_GET["data"];
$object = unserialize($data);
// ...

Compliant Solution

$data = $_GET["data"];

list($hash, $data) = explode('|', $data, 2);
$hash_confirm = hash_hmac("sha256", $data, "secret-key");

// Confirm that the data integrity is not compromised
if ($hash === $hash_confirm) {
  $object = unserialize($data);
  // ...
}

See

phpsecurity:S2078

User provided data such as URL parameters should always be considered as untrusted and tainted. Constructing LDAP names or search filters directly from tainted data enables attackers to inject specially crafted values that changes the initial meaning of the name or filter itself. Successful LDAP injections attacks can read, modify or delete sensitive information from the directory service.

Within LDAP names, the special characters ' ', '#', '"', '+', ',', ';', '<', '>', '\' and null must be escaped according to RFC 4514, for example by replacing them with the backslash character '\' followed by the two hex digits corresponding to the ASCII code of the character to be escaped. Similarly, LDAP search filters must escape a different set of special characters (including but not limited to '*', '(', ')', '\' and null) according to RFC 4515.

Noncompliant Code Example

$user = $_GET["user"];
$pass = $_GET["pass"];

$filter = "(&(uid=" . $user . ")(userPassword=" . $pass . "))"; // Unsafe

$ds = ...
$basedn = "o=My Company, c=US";

$sr = ldap_list($ds, $basedn, $filter); // Noncompliant

Compliant Solution

function sanitize_ldap_criteria($val) {
  $val = str_replace(['\\', '*', '(', ')'], ['\5c', '\2a', '\28', '\29'], $val);
  for ($i = 0; $i<strlen($val); $i++) {
    $char = substr($val, $i, 1);
    if (ord($char)<32) {
      $hex = dechex(ord($char));
      if (strlen($hex) == 1) $hex = '0' . $hex;
      $val = str_replace($char, '\\' . $hex, $val);
    }
  }
  return $val;
}

$user = sanitize_ldap_criteria( $_GET["user"] );
$pass = sanitize_ldap_criteria( $_GET["pass"] );

$filter = "(&(uid=" . $user . ")(userPassword=" . $pass . "))"; // Safe

$ds = ...
$basedn = "o=My Company, c=US";

$sr = ldap_list($ds, $basedn, $filter);

See

phpsecurity:S5335

User provided data such as URL parameters, POST data payloads or cookies should always be considered untrusted and tainted. Constructing include statements based on data supplied by the user could enable an attacker to control which files are included. If the attacker has the ability to upload files to the system, then arbitrary code could be executed. This could enable a wide range of serious attacks like accessing/modifying sensitive information or gain full system access.

The mitigation strategy should be based on whitelisting of allowed values or casting to safe types.

Noncompliant Code Example

$filename = $_GET["filename"];
include $filename . ".php";

Compliant Solution

$filename = $_GET["filename"];
if (in_array($filename, $whitelist)) {
  include $filename . ".php";
}

See

phpsecurity:S2076

Applications that execute operating system commands or execute commands that interact with the underlying system should neutralize any externally-provided values used in those commands. Failure to do so could allow an attacker to include input that executes unintended commands or exposes sensitive data.

The mitigation strategy should be based on whitelisting of allowed characters or commands.

Noncompliant Code Example

$binary = $_GET["binary"];

// If the value "/sbin/shutdown" is passed as binary and the web server is running as root,
// then the machine running the web server will be shut down and become unavailable for future requests

exec( $binary ); // Noncompliant

Compliant Solution

$binary = $_GET["binary"];

// Restrict to binaries within the current working directory whose name only contains letters
$pattern = "[a-zA-Z]++";
if ( preg_match($pattern, $binary) ) {
  exec( $binary ); // Compliant
}

See

phpsecurity:S5334

Applications that execute code dynamically should neutralize any externally-provided values used to construct the code. Failure to do so could allow an attacker to execute arbitrary code. This could enable a wide range of serious attacks like accessing/modifying sensitive information or gain full system access.

The mitigation strategy should be based on whitelisting of allowed values or casting to safe types.

Noncompliant Code Example

$data = $_GET["data"];
eval("echo \$data;");

Compliant Solution

$data = $_GET["data"];
if (in_array($data, $whitelist)) {
  eval("echo \$data;");
}

See

phpsecurity:S3649

User provided data, such as URL parameters, should always be considered untrusted and tainted. Constructing SQL queries directly from tainted data enables attackers to inject specially crafted values that change the initial meaning of the query itself. Successful SQL injection attacks can read, modify, or delete sensitive information from the database and sometimes even shut it down or execute arbitrary operating system commands.

Typically, the solution is to rely on the prepared statements rather than string concatenation, which ensures that user provided data will be properly escaped.

This rule supports: Native Database Extensions, PDO, Symfony/Doctrine, Laravel/Eloquent.

Noncompliant Code Example

function authenticate() {
  if( isset( $_POST[ 'Connect' ] ) ) {
    $login = $_POST[ 'login' ];
    $pass = $_POST[ 'pass' ];

    $query = "SELECT * FROM users WHERE login = '" . $login . "' AND pass = '" . $pass . "'"; // Unsafe

    // If the special value "foo' OR 1=1 --" is passed as either the user or pass, authentication is bypassed
    // Indeed, if it is passed as a user, the query becomes:
    // SELECT * FROM users WHERE user = 'foo' OR 1=1 --' AND pass = '...'
    // As '--' is the comment till end of line syntax in SQL, this is equivalent to:
    // SELECT * FROM users WHERE user = 'foo' OR 1=1
    // which is equivalent to:
    // SELECT * FROM users WHERE 1=1
    // which is equivalent to:
    // SELECT * FROM users

    $con = getDatabaseConnection();
    $result = mysqli_query($con, $query);

    $authenticated = false;
    if ( $row = mysqli_fetch_row( $result ) ) {
      $authenticated = true;
    }
    mysqli_free_result( $result );
    return $authenticated;
  }
}

Compliant Solution

function authenticate() {
  if( isset( $_POST[ 'Connect' ] ) ) {
    $login = $_POST[ 'login' ];
    $pass = $_POST[ 'pass' ];

    $query = "SELECT * FROM users WHERE login = ? AND pass = ?"; // Safe even if authenticate() method is still vulnerable to brute-force attack in this specific case

    $stmt = $pdo->prepare($query);

    $stmt->execute(array($login, $pass));

    $authenticated = false;
    if ( $stmt->rowCount() == 1 ) {
      $authenticated = true;
    }

    return $authenticated;
  }
}

See

phpsecurity:S2083

User provided data, such as URL parameters, POST data payloads, or cookies, should always be considered untrusted and tainted. Constructing file system paths directly from tainted data could enable an attacker to inject specially crafted values, such as '../', that change the initial path and, when accessed, resolve to a path on the filesystem where the user should normally not have access.

A successful attack might give an attacker the ability to read, modify, or delete sensitive information from the file system and sometimes even execute arbitrary operating system commands. This is often referred to as a "path traversal" or "directory traversal" attack.

The mitigation strategy should be based on the whitelisting of allowed paths or characters.

Noncompliant Code Example

$userId = $_GET["userId"];
$fileUUID = $_GET["fileUUID"];

if ( $_SESSION["userId"] == $userId ) {
  unlink("/storage/" . $userId . "/" . $fileUUID); // Noncompliant
}

Compliant Solution

$userId = (int) $_GET["userId"];
$fileUUID = (int) $_GET["fileUUID"];

if ( $_SESSION["userId"] == $userId ) {
  unlink("/storage/" . $userId . "/" . $fileUUID);
}

See

phpsecurity:S2091

User provided data, such as URL parameters, should always be considered untrusted and tainted. Constructing XPath expressions directly from tainted data enables attackers to inject specially crafted values that changes the initial meaning of the expression itself. Successful XPath injection attacks can read sensitive information from XML documents.

Noncompliant Code Example

$user = $_GET["user"];
$pass = $_GET["pass"];

$doc = new DOMDocument();
$doc->load("test.xml");
$xpath = new DOMXPath($doc);

$expression = "/users/user[@name='" . $user . "' and @pass='" . $pass . "']";
$xpath->evaluate($expression); // Noncompliant

Compliant Solution

$user = $_GET["user"];
$pass = $_GET["pass"];

$doc = new DOMDocument();
$doc->load("test.xml");
$xpath = new DOMXPath($doc);

$user = str_replace("'", "&apos;", $user);
$pass = str_replace("'", "&apos;", $pass);

$expression = "/users/user[@name='" . $user . "' and @pass='" . $pass . "']";
$xpath->evaluate($expression); // Compliant

See

objc:S2486

When exceptions occur, it is usually a bad idea to simply ignore them. Instead, it is better to handle them properly, or at least to log them.

Noncompliant Code Example

void save() {
  try {
    saveDocument();
  } catch (const std::exception& ex) {
  }
}

Compliant Solution

void save() {
  try {
    saveDocument();
  } catch (const std::exception& ex) {
    log << "Exception while saving the document: " << ex.what();
  }
}

See

objc:S1081

When using legacy C functions, it's up to the developer to make sure the size of the buffer to be written to is large enough to avoid buffer overflows. Buffer overflows can cause the program to crash at a minimum. At worst, a carefully crafted overflow can cause malicious code to be executed.

This rule reports use of the following insecure functions: strcpy(), strcat(), sprintf(), gets() and getpw().

In such cases, it's better to use an alternate, secure function which allows you to define the maximum number of characters to be written to the buffer:

  • strlcpy (BSD library) or strncpy
  • strlcat (BSD library) or strncat
  • snprintf
  • fgets
  • getpwuid

(Be aware that strncpy and strncat don't guarantee the string will be null-terminated.)

Noncompliant Code Example

sprintf(str, "%s", message);   // Noncompliant
strcpy(str, message); // Noncompliant

Compliant Solution

snprintf(str, sizeof(str), "%s", message);
strlcpy(str, message, sizeof(str));

strncpy(str, message, sizeof(str) -1); // Leave room for null
str[sizeof(str) - 1] = '\0'; // Make sure the string is null-terminated

See

php:S2068

Because it is easy to extract strings from a compiled application, credentials should never be hard-coded. Do so, and they're almost guaranteed to end up in the hands of an attacker. This is particularly true for applications that are distributed.

Credentials should be stored outside of the code in a strongly-protected encrypted configuration file or database.

Noncompliant Code Example

$uname = "steve";
$password = "blue";
connect($uname, $password);

Compliant Solution

$uname = getEncryptedUser();
$password = getEncryptedPass();
connect($uname, $password);

See

php:S2278

According to the US National Institute of Standards and Technology (NIST), the Data Encryption Standard (DES) is no longer considered secure:

Adopted in 1977 for federal agencies to use in protecting sensitive, unclassified information, the DES is being withdrawn because it no longer provides the security that is needed to protect federal government information.

Federal agencies are encouraged to use the Advanced Encryption Standard, a faster and stronger algorithm approved as FIPS 197 in 2001.

For similar reasons, RC2 should also be avoided.

Noncompliant Code Example

<?php
  $ciphertext = mcrypt_encrypt(MCRYPT_DES, $key, $plaintext, $mode); // Noncompliant
  // ...
  $ciphertext = mcrypt_encrypt(MCRYPT_DES_COMPAT, $key, $plaintext, $mode); // Noncompliant
  // ...
  $ciphertext = mcrypt_encrypt(MCRYPT_TRIPLEDES, $key, $plaintext, $mode); // Noncompliant
  // ...
  $ciphertext = mcrypt_encrypt(MCRYPT_3DES, $key, $plaintext, $mode); // Noncompliant

  $cipher = "des-ede3-cfb";  // Noncompliant
  $ciphertext_raw = openssl_encrypt($plaintext, $cipher, $key, $options=OPENSSL_RAW_DATA, $iv);
?>

Compliant Solution

<?php
  $ciphertext = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $plaintext, MCRYPT_MODE_CBC, $iv);
?>

See

php:S4433

An un-authenticated LDAP connection can lead to transactions without access control. Authentication, and with it, access control, are the last line of defense against LDAP injections and should not be disabled.

This rule raises an issue when an anonymous LDAP connection is created.

Noncompliant Code Example

$ldapconn = ldap_connect("ldap.example.com");

if ($ldapconn) {
    $ldapbind = ldap_bind($ldapconn); // Noncompliant; anonymous authentication, no user/password provided
}

Compliant Solution

$ldaprdn  = 'uname';
$ldappass = 'password';

$ldapconn = ldap_connect("ldap.example.com");

if ($ldapconn) {
    $ldapbind = ldap_bind($ldapconn, $ldaprdn, $ldappass); // Compliant
}

See

c:S1081

When using legacy C functions, it's up to the developer to make sure the size of the buffer to be written to is large enough to avoid buffer overflows. Buffer overflows can cause the program to crash at a minimum. At worst, a carefully crafted overflow can cause malicious code to be executed.

This rule reports use of the following insecure functions: strcpy(), strcat(), sprintf(), gets() and getpw().

In such cases, it's better to use an alternate, secure function which allows you to define the maximum number of characters to be written to the buffer:

  • strlcpy (BSD library) or strncpy
  • strlcat (BSD library) or strncat
  • snprintf
  • fgets
  • getpwuid

(Be aware that strncpy and strncat don't guarantee the string will be null-terminated.)

Noncompliant Code Example

sprintf(str, "%s", message);   // Noncompliant
strcpy(str, message); // Noncompliant

Compliant Solution

snprintf(str, sizeof(str), "%s", message);
strlcpy(str, message, sizeof(str));

strncpy(str, message, sizeof(str) -1); // Leave room for null
str[sizeof(str) - 1] = '\0'; // Make sure the string is null-terminated

See

vbnet:S2068

Because it is easy to extract strings from a compiled application, credentials should never be hard-coded. Do so, and they're almost guaranteed to end up in the hands of an attacker. This is particularly true for applications that are distributed.

Credentials should be stored outside of the code in a strongly-protected encrypted configuration file or database.

Noncompliant Code Example

Dim username As String = "admin"
Dim password As String = "Password123"
Dim usernamePassword As String = "user=admin&password=Password123"
Dim usernamePassword2 As String = "user=admin&" & "password=" & password

Compliant Solution

Dim username As String = "admin"
Dim password As String = GetEncryptedPassword()
Dim usernamePassword As String = String.Format("user={0}&password={1}", GetEncryptedUsername(), GetEncryptedPassword())

See

flex:S1951

The trace() function outputs debug statements, which can be read by anyone with a debug version of the Flash player. Because sensitive information could easily be exposed in this manner, trace() should never appear in production code.

Noncompliant Code Example

    var val:Number = doCalculation();
    trace("Calculation result: " + val);  // Noncompliant

Compliant Solution

    var val:Number = doCalculation();

See

flex:S1444

There is no good reason to declare a field "public" and "static" without also declaring it "const". Most of the time this is a kludge to share a state among several objects. But with this approach, any object can do whatever it wants with the shared state, such as setting it to null.

Noncompliant Code Example

public class Greeter {
  public static var foo:Foo = new Foo(...);
  ...
}

Compliant Solution

public class Greeter {
  public static const FOO:Foo = new Foo(...);
  ...
}

See

flex:S1442

Alert.show(...) can be useful for debugging during development, but in production mode this kind of pop-up could expose sensitive information to attackers, and should never be displayed.

Noncompliant Code Example

if(unexpectedCondition)
{
  Alert.show("Unexpected Condition");
}

See

cpp:S2486

When exceptions occur, it is usually a bad idea to simply ignore them. Instead, it is better to handle them properly, or at least to log them.

Noncompliant Code Example

void save() {
  try {
    saveDocument();
  } catch (const std::exception& ex) {
  }
}

Compliant Solution

void save() {
  try {
    saveDocument();
  } catch (const std::exception& ex) {
    log << "Exception while saving the document: " << ex.what();
  }
}

See

cpp:S1081

When using legacy C functions, it's up to the developer to make sure the size of the buffer to be written to is large enough to avoid buffer overflows. Buffer overflows can cause the program to crash at a minimum. At worst, a carefully crafted overflow can cause malicious code to be executed.

This rule reports use of the following insecure functions: strcpy(), strcat(), sprintf(), gets() and getpw().

In such cases, it's better to use an alternate, secure function which allows you to define the maximum number of characters to be written to the buffer:

  • strlcpy (BSD library) or strncpy
  • strlcat (BSD library) or strncat
  • snprintf
  • fgets
  • getpwuid

(Be aware that strncpy and strncat don't guarantee the string will be null-terminated.)

Noncompliant Code Example

sprintf(str, "%s", message);   // Noncompliant
strcpy(str, message); // Noncompliant

Compliant Solution

snprintf(str, sizeof(str), "%s", message);
strlcpy(str, message, sizeof(str));

strncpy(str, message, sizeof(str) -1); // Leave room for null
str[sizeof(str) - 1] = '\0'; // Make sure the string is null-terminated

See

csharpsquid:S2228

Debug statements are always useful during development. But include them in production code - particularly in code that runs client-side - and you run the risk of inadvertently exposing sensitive information.

Noncompliant Code Example

private void DoSomething()
{
    // ...
    Console.WriteLine("so far, so good..."); // Noncompliant
    // ...
}

Exceptions

The following are ignored by this rule:

  • Console Applications
  • Calls in methods decorated with [Conditional ("DEBUG")]
  • Calls included in DEBUG preprocessor branches (#if DEBUG)

See

csharpsquid:S2386

public static mutable fields of classes which are accessed directly should be protected to the degree possible. This can be done by reducing the accessibility of the field or by changing the return type to an immutable type.

This rule raises issues for public static fields with a type inheriting/implementing System.Array or System.Collections.Generic.ICollection<T>.

Noncompliant Code Example

public class A
{
  public static string[] strings1 = {"first","second"};  // Noncompliant
  public static List<String> strings3 = new List<String>();  // Noncompliant
  // ...
}

Compliant Solution

public class A
{
  protected static string[] strings1 = {"first","second"};
  protected static List<String> strings3 = new List<String>();
  // ...
}

Exceptions

No issue is reported:

  • If the type of the field inherits/implements one (at least) of the following types:
    • System.Collections.ObjectModel.ReadOnlyCollection<T>
    • System.Collections.ObjectModel.ReadOnlyDictionary<TKey, TValue>
    • System.Collections.Immutable.IImmutableArray<T>
    • System.Collections.Immutable.IImmutableDictionary<TKey, TValue>
    • System.Collections.Immutable.IImmutableList<T>
    • System.Collections.Immutable.IImmutableSet<T>
    • System.Collections.Immutable.IImmutableStack<T>
    • System.Collections.Immutable.IImmutableQueue<T>
  • If the field is readonly and is initialized inline with an immutable type (i.e. inherits/implements one of the types in the previous list) or null.

See

csharpsquid:S4564

ASP.Net has a feature to validate HTTP requests to prevent potentially dangerous content to perform a cross-site scripting (XSS) attack. There is no reason to disable this mechanism even if other checks to prevent XXS attacks are in place.

This rule raises an issue if a method with parameters is marked with System.Web.Mvc.HttpPostAttribute and not System.Web.Mvc.ValidateInputAttribute(true).

Noncompliant Code Example

public class FooBarController : Controller
{
    [HttpPost] // Noncompliant
    [ValidateInput(false)]
    public ActionResult Purchase(string input)
    {
        return Foo(input);
    }

    [HttpPost] // Noncompliant
    public ActionResult PurchaseSomethingElse(string input)
    {
        return Foo(input);
    }
}

Compliant Solution

public class FooBarController : Controller
{
    [HttpPost]
    [ValidateInput(true)] // Compliant
    public ActionResult Purchase(string input)
    {
        return Foo(input);
    }
}

Exceptions

Parameterless methods marked with System.Web.Mvc.HttpPostAttribute will not trigger this issue.

See

csharpsquid:S2278

According to the US National Institute of Standards and Technology (NIST), the Data Encryption Standard (DES) is no longer considered secure:

Adopted in 1977 for federal agencies to use in protecting sensitive, unclassified information, the DES is being withdrawn because it no longer provides the security that is needed to protect federal government information.

Federal agencies are encouraged to use the Advanced Encryption Standard, a faster and stronger algorithm approved as FIPS 197 in 2001.

For similar reasons, RC2 should also be avoided.

Noncompliant Code Example

using (var tripleDES = new TripleDESCryptoServiceProvider()) //Noncompliant
{
  //...
}

Compliant Solution

using (var aes = new AesCryptoServiceProvider())
{
  //...
}

See

csharpsquid:S4211

Transparency attributes, SecurityCriticalAttribute and SecuritySafeCriticalAttribute are used to identify code that performs security-critical operations. The second one indicates that it is safe to call this code from transparent, while the first one does not. Since the transparency attributes of code elements with larger scope take precedence over transparency attributes of code elements that are contained in the first element a class, for instance, with a SecurityCriticalAttribute can not contain a method with a SecuritySafeCriticalAttribute.

This rule raises an issue when a member is marked with a System.Security security attribute that has a different transparency than the security attribute of a container of the member.

Noncompliant Code Example

using System;
using System.Security;

namespace MyLibrary
{

    [SecurityCritical]
    public class Foo
    {
        [SecuritySafeCritical] // Noncompliant
        public void Bar()
        {
        }
    }
}

Compliant Solution

using System;
using System.Security;

namespace MyLibrary
{

    [SecurityCritical]
    public class Foo
    {
        public void Bar()
        {
        }
    }
}

See

csharpsquid:S4212

Because serialization constructors allocate and initialize objects, security checks that are present on regular constructors must also be present on a serialization constructor. Failure to do so would allow callers that could not otherwise create an instance to use the serialization constructor to do this.

This rule raises an issue when a type implements the System.Runtime.Serialization.ISerializable interface, is not a delegate or interface, is declared in an assembly that allows partially trusted callers and has a constructor that takes a System.Runtime.Serialization.SerializationInfo object and a System.Runtime.Serialization.StreamingContext object which is not secured by a security check, but one or more of the regular constructors in the type is secured.

Noncompliant Code Example

using System;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Security;
using System.Security.Permissions;

[assembly: AllowPartiallyTrustedCallersAttribute()]
namespace MyLibrary
{
    [Serializable]
    public class Foo : ISerializable
    {
        private int n;

        [FileIOPermissionAttribute(SecurityAction.Demand, Unrestricted = true)]
        public Foo()
        {
           n = -1;
        }

        protected Foo(SerializationInfo info, StreamingContext context) // Noncompliant
        {
           n = (int)info.GetValue("n", typeof(int));
        }

        void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
        {
           info.AddValue("n", n);
        }
    }
}

Compliant Solution

using System;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Security;
using System.Security.Permissions;

[assembly: AllowPartiallyTrustedCallersAttribute()]
namespace MyLibrary
{
    [Serializable]
    public class Foo : ISerializable
    {
        private int n;

        [FileIOPermissionAttribute(SecurityAction.Demand, Unrestricted = true)]
        public Foo()
        {
           n = -1;
        }

        [FileIOPermissionAttribute(SecurityAction.Demand, Unrestricted = true)]
        protected Foo(SerializationInfo info, StreamingContext context)
        {
           n = (int)info.GetValue("n", typeof(int));
        }

        void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
        {
           info.AddValue("n", n);
        }
    }
}

See

csharpsquid:S2486

When exceptions occur, it is usually a bad idea to simply ignore them. Instead, it is better to handle them properly, or at least to log them.

This rule only reports on empty catch clauses that catch generic Exceptions.

Noncompliant Code Example

string text = "";
try
{
    text = File.ReadAllText(fileName);
}
catch (Exception exc) // Noncompliant
{
}

Compliant Solution

string text = "";
try
{
    text = File.ReadAllText(fileName);
}
catch (Exception exc)
{
    logger.Log(exc);
}

Exceptions

When a block contains a comment, it is not considered to be empty.

See

csharpsquid:S4433

An un-authenticated LDAP connection can lead to transactions without access control. Authentication, and with it, access control, are the last line of defense against LDAP injections and should not be disabled.

This rule raises an issue when an LDAP connection is created with AuthenticationTypes.Anonymous or AuthenticationTypes.None.

Noncompliant Code Example

DirectoryEntry myDirectoryEntry = new DirectoryEntry(adPath);
myDirectoryEntry.AuthenticationType = AuthenticationTypes.None; // Noncompliant

DirectoryEntry myDirectoryEntry = new DirectoryEntry(adPath, "u", "p", AuthenticationTypes.None); // Noncompliant

Compliant Solution

DirectoryEntry myDirectoryEntry = new DirectoryEntry(myADSPath); // Compliant; default DirectoryEntry.AuthenticationType property value is "Secure" since .NET Framework 2.0

DirectoryEntry myDirectoryEntry = new DirectoryEntry(myADSPath, "u", "p", AuthenticationTypes.Secure);

See

csharpsquid:S4432

Encryption algorithms can be used with various modes. Some combinations are not secured:

  • Electronic Codebook (ECB) mode: Under a given key, any given plaintext block always gets encrypted to the same ciphertext block. Thus, it does not hide data patterns well. In some senses, it doesn't provide serious message confidentiality, and it is not recommended for use in cryptographic protocols at all.
  • Cipher Block Chaining (CBC) with PKCS#5 padding (or PKCS#7) is susceptible to padding oracle attacks. CBC + PKCS#7 can be used if combined with an authenticity check (HMAC-SHA256 for example) on the cipher text.

In both cases, Galois/Counter Mode (GCM) with no padding should be preferred. As the .NET framework doesn't provide this natively, the use of a certified third party lib is recommended.

This rule raises an issue when any of the following CipherMode is detected: ECB, CBC, OFB, CFB, CTS.

Noncompliant Code Example

AesManaged aes = new AesManaged
{
  KeySize = 128,
  BlockSize = 128,
  Mode = CipherMode.OFB, // Noncompliant
  Padding = PaddingMode.PKCS7
};

See

csharpsquid:S2068

Because it is easy to extract strings from a compiled application, credentials should never be hard-coded. Do so, and they're almost guaranteed to end up in the hands of an attacker. This is particularly true for applications that are distributed.

Credentials should be stored outside of the code in a strongly-protected encrypted configuration file or database.

Noncompliant Code Example

string username = "admin";
string password = "Password123"; // Noncompliant
string usernamePassword  = "user=admin&password=Password123"; // Noncompliant
string usernamePassword2 = "user=admin&" + "password=" + password; // Noncompliant

Compliant Solution

string username = "admin";
string password = GetEncryptedPassword();
string usernamePassword = string.Format("user={0}&password={1}", GetEncryptedUsername(), GetEncryptedPassword());

See

csharpsquid:S3884

CoSetProxyBlanket and CoInitializeSecurity both work to set the permissions context in which the process invoked immediately after is executed. Calling them from within that process is useless because it's too late at that point; the permissions context has already been set.

Specifically, these methods are meant to be called from non-managed code such as a C++ wrapper that then invokes the managed, i.e. C# or VB.NET, code.

Noncompliant Code Example

[DllImport("ole32.dll")]
static extern int CoSetProxyBlanket([MarshalAs(UnmanagedType.IUnknown)]object pProxy, uint dwAuthnSvc, uint dwAuthzSvc,
	[MarshalAs(UnmanagedType.LPWStr)] string pServerPrincName, uint dwAuthnLevel, uint dwImpLevel, IntPtr pAuthInfo,
	uint dwCapabilities);

public enum RpcAuthnLevel
{
	Default = 0,
	None = 1,
	Connect = 2,
	Call = 3,
	Pkt = 4,
	PktIntegrity = 5,
	PktPrivacy = 6
}

public enum RpcImpLevel
{
	Default = 0,
	Anonymous = 1,
	Identify = 2,
	Impersonate = 3,
	Delegate = 4
}

public enum EoAuthnCap
{
	None = 0x00,
	MutualAuth = 0x01,
	StaticCloaking = 0x20,
	DynamicCloaking = 0x40,
	AnyAuthority = 0x80,
	MakeFullSIC = 0x100,
	Default = 0x800,
	SecureRefs = 0x02,
	AccessControl = 0x04,
	AppID = 0x08,
	Dynamic = 0x10,
	RequireFullSIC = 0x200,
	AutoImpersonate = 0x400,
	NoCustomMarshal = 0x2000,
	DisableAAA = 0x1000
}

[DllImport("ole32.dll")]
public static extern int CoInitializeSecurity(IntPtr pVoid, int cAuthSvc, IntPtr asAuthSvc, IntPtr pReserved1,
	RpcAuthnLevel level, RpcImpLevel impers, IntPtr pAuthList, EoAuthnCap dwCapabilities, IntPtr pReserved3);

static void Main(string[] args)
{
	var hres1 = CoSetProxyBlanket(null, 0, 0, null, 0, 0, IntPtr.Zero, 0); // Noncompliant

	var hres2 = CoInitializeSecurity(IntPtr.Zero, -1, IntPtr.Zero, IntPtr.Zero, RpcAuthnLevel.None,
		RpcImpLevel.Impersonate, IntPtr.Zero, EoAuthnCap.None, IntPtr.Zero); // Noncompliant
}

See

javascript:DebuggerStatement

The debugger statement can be placed anywhere in procedures to suspend execution. Using the debugger statement is similar to setting a breakpoint in the code. By definition such statement must absolutely be removed from the source code to prevent any unexpected behavior or added vulnerability to attacks in production.

Noncompliant Code Example

for (i = 1; i<5; i++) {
  // Print i to the Output window.
  Debug.write("loop index is " + i);
  // Wait for user to resume.
  debugger;
}

Compliant Solution

for (i = 1; i<5; i++) {
  // Print i to the Output window.
  Debug.write("loop index is " + i);
}

See

javascript:S2819

HTML5 adds the ability to send messages to documents served from other domains. According to the specification:

Authors should not use the wildcard keyword ( *) in the targetOrigin argument in messages that contain any confidential information, as otherwise there is no way to guarantee that the message is only delivered to the recipient to which it was intended.

To mitigate the risk of sending sensitive information to a document served from a hostile or unknown domain, this rule raises an issue each time Window.postMessage is used.

Noncompliant Code Example

var myWindow = document.getElementById('myIFrame').contentWindow;
myWindow.postMessage(message, "*"); // Noncompliant; how do you know what you loaded in 'myIFrame' is still there?

See

javascript:S2817

The Web SQL Database standard never saw the light of day. It was first formulated, then deprecated by the W3C and was only implemented in some browsers. (It is not supported in Firefox or IE.)

Further, the use of a Web SQL Database poses security concerns, since you only need its name to access such a database.

Noncompliant Code Example

var db = window.openDatabase("myDb", "1.0", "Personal secrets stored here", 2*1024*1024);  // Noncompliant

See

javascript:S3271

Session storage and local storage are HTML 5 features which allow developers to easily store megabytes of data client-side, as opposed to the 4Kb cookies can accommodate. While useful to speed applications up on the client side, it can be dangerous to store sensitive information this way because the data is not encrypted by default and any script on the page may access it.

This rule raises an issue when the localStorage and sessionStorage API's are used.

Noncompliant Code Example

localStorage.setItem("login", login); // Noncompliant
sessionStorage.setItem("sessionId", sessionId); // Noncompliant

See

javascript:S2611

Including content in your site from an untrusted source can expose your users to attackers and even compromise your own site. For that reason, this rule raises an issue for each non-relative URL.

Noncompliant Code Example

function include(url) {
  var s = document.createElement("script");
  s.setAttribute("type", "text/javascript");
  s.setAttribute("src", url);
  document.body.appendChild(s);
}
include("http://hackers.com/steal.js")  // Noncompliant

See

javascript:S1442

alert(...) as well as confirm(...) and prompt(...) can be useful for debugging during development, but in production mode this kind of pop-up could expose sensitive information to attackers, and should never be displayed.

Noncompliant Code Example

if(unexpectedCondition) {
  alert("Unexpected Condition");
}

See

abap:S2068

Because it is easy to extract strings from a compiled application, credentials should never be hard-coded. Do so, and they're almost guaranteed to end up in the hands of an attacker. This is particularly true for applications that are distributed.

Credentials should be stored outside of the code in a strongly-protected encrypted configuration file or database.

This rule flags instances of hard-coded credentials used in database and LDAP connections. It looks for hard-coded credentials in connection strings, and for variable names that match any of the patterns from the provided list.

It's recommended to customize the configuration of this rule with additional credential words such as "oauthToken", "secret", ...

Noncompliant Code Example

DATA: password(10) VALUE 'secret123',
           pwd(10) VALUE 'secret123'.

See

abap:S1493

There are two main reasons to ban dynamic clauses in SELECT statements.

The first relates to maintainability. One of the nice features of ABAP Design Time is the connection to the data dictionary; you get syntax errors if you try to address table fields that are not present anymore or that have typos. With dynamic SQL, the ability to statically check the code for this type of error is lost.

The other more critical reason relates to security. By definition, dynamic clauses make an application susceptible to SQL injection attacks.

Noncompliant Code Example

SELECT (select_clause)
 FROM (from_clause) CLIENT SPECIFIED INTO <fs>
 WHERE (where_clause)
 GROUP BY (groupby_clause) HAVING (having_clause)
 ORDER BY (orderby_clause).

See

abap:S5117

Every AUTHORITY-CHECK statement sets the fields SY-SUBRC (also accessible as SYST-SUBRC) to the authorization check result. Thus SY-SUBRC value should be checked just after every AUTHORITY-CHECK statement.

Noncompliant Code Example

AUTHORITY-CHECK OBJECT 'S_MYOBJ' "Noncompliant
    ID 'ID1' FIELD myvalue.

Compliant Solution

AUTHORITY-CHECK OBJECT 'S_MYOBJ'  "Compliant
    ID 'ID1' FIELD myvalue.

  IF sy-subrc <> 0.
    MESSAGE 'NOT AUTHORIZED' TYPE 'E'.
  ENDIF.

Exceptions

No issue will be raised in the following cases:

  • One or more WRITE operation are performed between the AUTHORITY-CHECK statement and SY-SUBRC check. An exception will be however raised if the WRITE operation is a WRITE ... TO statement, as this will set again SY-SUBRC.
  • SY-SUBRC's value is assigned to a variable. We then assume that it will be checked later.
AUTHORITY-CHECK OBJECT 'S_MYOBJ'  "Compliant
    ID 'ID1' FIELD myvalue.
WRITE 'Test' " WRITE is accepted before checking SY-SUBRC
IF SY-SUBRC <> 0.
    EXIT.
ENDIF.

AUTHORITY-CHECK OBJECT 'S_MYOBJ'  "Compliant
    ID 'ID1' FIELD myvalue.
Tmp = SY-SUBRC " Assigning SY-SUBRC value to a variable. We assume that it will be checked later.
IF Tmp <> 0.
    EXIT.
ENDIF.
abap:S5115

Checking logged users' permissions by comparing their name to a hardcoded string can create security vulnerabilities. It prevents system administrators from changing users' permissions when needed (example: when their account has been compromised). Thus system fields SY-UNAME and SYST-UNAME should not be compared to hardcoded strings. Use instead AUTHORITY-CHECK to check users' permissions.

This rule raises an issue when either of the system fields SY-UNAME or SYST-UNAME are compared to a hardcoded value in a CASE statement or using one of the following operators: =, EQ, <>, NE.

Noncompliant Code Example

IF SY-UNAME = 'ALICE'. " Noncompliant
ENDIF.

CASE SY-UNAME.
WHEN 'A'. " Noncompliant
ENDCASE.

Compliant Solution

AUTHORITY-CHECK OBJECT 'S_CARRID'
  ID 'CARRID' FIELD mycarrid.
IF sy-subrc <> 0.
  MESSAGE 'Not authorized' TYPE 'E'.
ENDIF.
abap:S1486

A BREAK-POINT statement is used when debugging an application with help of the ABAP Debugger. But such debugging statements could make an application vulnerable to attackers, and should not be left in the source code.

Noncompliant Code Example

IF wv_parallel EQ 'X'.
  BREAK-POINT.
  WAIT UNTIL g_nb_return EQ wv_nb_call.
ENDIF.

Compliant Solution

IF wv_parallel EQ 'X'.
  WAIT UNTIL g_nb_return EQ wv_nb_call.
ENDIF.

See

squid:S2115

Failure to password-protect a database is so careless or naive as to be almost negligent. Databases should always be password protected, but the use of a database connection with an empty password is a clear indication of a database that is not protected.

This rule flags database connections with empty passwords.

Noncompliant Code Example

Connection conn = DriverManager.getConnection("jdbc:derby:memory:myDB;create=true", "AppLogin", "");
Connection conn2 = DriverManager.getConnection("jdbc:derby:memory:myDB;create=true?user=user&password=");

Compliant Solution

DriverManager.getConnection("jdbc:derby:memory:myDB;create=true?user=user&password=password");

DriverManager.getConnection("jdbc:mysql://address=(host=myhost1)(port=1111)(key1=value1)(user=sandy)(password=secret),address=(host=myhost2)(port=2222)(key2=value2)(user=sandy)(password=secret)/db");

DriverManager.getConnection("jdbc:mysql://sandy:secret@[myhost1:1111,myhost2:2222]/db");

String url = "jdbc:postgresql://localhost/test";
Properties props = new Properties();
props.setProperty("user", "fred");
props.setProperty("password", "secret");
DriverManager.getConnection(url, props);

See

squid:S1148

Throwable.printStackTrace(...) prints a Throwable and its stack trace to some stream. By default that stream System.Err, which could inadvertently expose sensitive information.

Loggers should be used instead to print Throwables, as they have many advantages:

  • Users are able to easily retrieve the logs.
  • The format of log messages is uniform and allow users to browse the logs easily.

This rule raises an issue when printStackTrace is used without arguments, i.e. when the stack trace is printed to the default stream.

Noncompliant Code Example

try {
  /* ... */
} catch(Exception e) {
  e.printStackTrace();        // Noncompliant
}

Compliant Solution

try {
  /* ... */
} catch(Exception e) {
  LOGGER.log("context", e);
}

See

squid:S3329

In encryption, when Cipher Block Chaining (CBC) is used, the Initialization Vector (IV) must be random and unpredictable. Otherwise, the encrypted value is vulnerable to crypto-analysis attacks such as the "Chosen-Plaintext Attack".

An IV value should be associated to one, and only one encryption cycle, because the IV's purpose is to ensure that the same plaintext encrypted twice will yield two different ciphertexts.

To that end, IV's should be:

  • random
  • unpredictable
  • publishable (IVs are frequently published)
  • authenticated, along with the ciphertext, with a Message Authentication Code (MAC)

This rule raises an issue when the IV is:

  • hard-coded
  • created using java.util.Random rather than java.security.SecureRandom.

Noncompliant Code Example

public class MyCbcClass {

  public String applyCBC(String strKey, String plainText) {
    byte[] bytesIV = "7cVgr5cbdCZVw5WY".getBytes("UTF-8");

    /* KEY + IV setting */
    IvParameterSpec iv = new IvParameterSpec(bytesIV);
    SecretKeySpec skeySpec = new SecretKeySpec(strKey.getBytes("UTF-8"), "AES");

    /* Ciphering */
    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
    cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);  // Noncompliant because IV hard coded and cannot vary with each ciphering round
    byte[] encryptedBytes = cipher.doFinal(plainText.getBytes("UTF-8"));
    return DatatypeConverter.printBase64Binary(bytesIV) // IV is typically published
            + ";" + DatatypeConverter.printBase64Binary(encryptedBytes);
  }
}

Compliant Solution

public class MyCbcClass {

  SecureRandom random = new SecureRandom();

  public String applyCBC(String strKey, String plainText) {
    byte[] bytesIV = new byte[16];
    random.nextBytes(bytesIV);

    /* KEY + IV setting */
    IvParameterSpec iv = new IvParameterSpec(bytesIV);
    SecretKeySpec skeySpec = new SecretKeySpec(strKey.getBytes("UTF-8"), "AES");

    /* Ciphering */
    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
    cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
    byte[] encryptedBytes = cipher.doFinal(plainText.getBytes("UTF-8"));
    return DatatypeConverter.printBase64Binary(bytesIV)
            + ";" + DatatypeConverter.printBase64Binary(encryptedBytes);
  }
}

See

  • MITRE, CWE-330 - Use of Insufficiently Random Values
  • OWASP Top 10 2017 Category A6 - Security Misconfiguration
  • Derived from FindSecBugs rule STATIC_IV
squid:S4684

On one side, Spring MVC automatically bind request parameters to beans declared as arguments of methods annotated with @RequestMapping. Because of this automatic binding feature, it's possible to feed some unexpected fields on the arguments of the @RequestMapping annotated methods.

On the other end, persistent objects (@Entity or @Document) are linked to the underlying database and updated automatically by a persistence framework, such as Hibernate, JPA or Spring Data MongoDB.

These two facts combined together can lead to malicious attack: if a persistent object is used as an argument of a method annotated with @RequestMapping, it's possible from a specially crafted user input, to change the content of unexpected fields into the database.

For this reason, using @Entity or @Document objects as arguments of methods annotated with @RequestMapping should be avoided.

In addition to @RequestMapping, this rule also considers the annotations introduced in Spring Framework 4.3: @GetMapping, @PostMapping, @PutMapping, @DeleteMapping, @PatchMapping.

Noncompliant Code Example

import javax.persistence.Entity;

@Entity
public class Wish {
  Long productId;
  Long quantity;
  Client client;
}

@Entity
public class Client {
  String clientId;
  String name;
  String password;
}

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class WishListController {

  @PostMapping(path = "/saveForLater")
  public String saveForLater(Wish wish) {
    session.save(wish);
  }

  @RequestMapping(path = "/saveForLater", method = RequestMethod.POST)
  public String saveForLater(Wish wish) {
    session.save(wish);
  }
}

Compliant Solution

public class WishDTO {
  Long productId;
  Long quantity;
  Long clientId;
}

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class PurchaseOrderController {

  @PostMapping(path = "/saveForLater")
  public String saveForLater(WishDTO wish) {
    Wish persistentWish = new Wish();
    // do the mapping between "wish" and "persistentWish"
    [...]
    session.save(persistentWish);
  }

  @RequestMapping(path = "/saveForLater", method = RequestMethod.POST)
  public String saveForLater(WishDTO wish) {
    Wish persistentWish = new Wish();
    // do the mapping between "wish" and "persistentWish"
    [...]
    session.save(persistentWish);
  }
}

See

squid:S3355

Every filter defined in web.xml file should be used in a <filter-mapping> element. Otherwise such filters are not invoked.

Noncompliant Code Example

  <filter>
     <filter-name>DefinedNotUsed</filter-name>
     <filter-class>com.myco.servlet.ValidationFilter</filter-class>
  </filter>

Compliant Solution

  <filter>
     <filter-name>ValidationFilter</filter-name>
     <filter-class>com.myco.servlet.ValidationFilter</filter-class>
  </filter>

  <filter-mapping>
     <filter-name>ValidationFilter</filter-name>
     <url-pattern>/*</url-pattern>
  </filter-mapping>

See

squid:S2278

According to the US National Institute of Standards and Technology (NIST), the Data Encryption Standard (DES) is no longer considered secure:

Adopted in 1977 for federal agencies to use in protecting sensitive, unclassified information, the DES is being withdrawn because it no longer provides the security that is needed to protect federal government information.

Federal agencies are encouraged to use the Advanced Encryption Standard, a faster and stronger algorithm approved as FIPS 197 in 2001.

For similar reasons, RC2 should also be avoided.

Noncompliant Code Example

Cipher c = Cipher.getInstance("DESede/ECB/PKCS5Padding");

Compliant Solution

Cipher c = Cipher.getInstance("AES/GCM/NoPadding");

See

squid:S2277

Without OAEP in RSA encryption, it takes less work for an attacker to decrypt the data or infer patterns from the ciphertext. This rule logs an issue as soon as a literal value starts with RSA/NONE.

Noncompliant Code Example

Cipher rsa = javax.crypto.Cipher.getInstance("RSA/NONE/NoPadding");

Compliant Solution

Cipher rsa = javax.crypto.Cipher.getInstance("RSA/ECB/OAEPWITHSHA-256ANDMGF1PADDING");

See

squid:S4424

Empty implementations of the X509TrustManager interface are often created to allow connection to a host that is not signed by a root certificate authority. Such an implementation will accept any certificate, which leaves the application vulnerable to Man-in-the-middle attacks. The correct solution is to provide an appropriate trust store.

This rule raises an issue when an implementation of X509TrustManager never throws exception.

Noncompliant Code Example

class TrustAllManager implements X509TrustManager {

    @Override
    public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {  // Noncompliant, nothing means trust any client
    }

    @Override
    public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException { // Noncompliant, this method never throws exception, it means trust any client
        LOG.log(Level.SEVERE, ERROR_MESSAGE);
    }

    @Override
    public X509Certificate[] getAcceptedIssuers() {
        return null;
    }
}

See

squid:S4423

javax.net.ssl.SSLContext.getInstance returns a SSLContext object that implements the specified secure socket protocol. However, not all protocols are created equal and some legacy ones like "SSL", have been proven to be insecure.

This rule raises an issue when an SSLContext is created with an insecure protocol (ie: a protocol different from "TLS", "DTLS", "TLSv1.2", "DTLSv1.2", "TLSv1.3", "DTLSv1.3").

The recommended value is "TLS" or "DTLS" as it will always use the latest version of the protocol. However an issue will be raised if the bytecode was compiled with JDK7 or an even older version of JDK because they are not alias for TLSv1.2 and DTLSv1.2 but for weaker protocols.

Note that calling SSLContext.getInstance(...) with "TLSv1.2" or "DTLSv1.2" doesn't prevent protocol version negotiation. For example, if a client connects with "TLSv1.1" and the server used SSLContext.getInstance("TLSv1.2"), the connection will use "TLSv1.1". It is possible to enable only specific protocol versions by calling setEnabledProtocols on SSLSocket, SSLServerSocket or SSLEngine. However this should be rarely needed as clients usually ask for the most secure protocol supported.

Noncompliant Code Example

context = SSLContext.getInstance("SSL"); // Noncompliant

Compliant Solution

context = SSLContext.getInstance("TLSv1.2");

See

squid:S4426

When generating cryptographic keys (or key pairs), it is important to use a key length that provides enough entropy against brute-force attacks. For the Blowfish algorithm the key should be at least 128 bits long, while for the RSA algorithm it should be at least 2048 bits long.

This rule raises an issue when a Blowfish key generator or RSA key-pair generator is initialized with too small a length parameter.

Noncompliant Code Example

KeyGenerator keyGen = KeyGenerator.getInstance("Blowfish");
keyGen.init(64); // Noncompliant

KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
keyPairGen.initialize(512); // Noncompliant

Compliant Solution

KeyGenerator keyGen = KeyGenerator.getInstance("Blowfish");
keyGen.init(128);

KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
keyPairGen.initialize(2048);

See

squid:S3330

The HttpOnly cookie attribute tells the browser to prevent client-side scripts from reading cookies with the attribute, and its use can go a long way to defending against Cross-Site Scripting (XSS) attacks. Thus, as a precaution, the attribute should be set by default on all cookies set server-side, such as session id cookies.

When implementing Cross Site Request Forgery (XSRF) protection, a JavaScript-readable session cookie, generally named XSRF-TOKEN, should be created on the first HTTP GET request. For such a cookie, the HttpOnly attribute should be set to "false".

Setting the attribute can be done either programmatically, or globally via configuration files.

Noncompliant Code Example

Cookie cookie = new Cookie("myCookieName", value); // Noncompliant; by default cookie.isHttpOnly() is returning false

Compliant Solution

Cookie cookie = new Cookie("myCookieName", value);
cookie.setHttpOnly(true); // Compliant

See

squid:S4435

An XML External Entity or XSLT External Entity (XXE) vulnerability can occur when a javax.xml.transform.Transformer is created without enabling "Secure Processing" or when one is created without disabling external DTDs. If that external entity is hijacked by an attacker it may lead to the disclosure of confidential data, denial of service, server side request forgery, port scanning from the perspective of the machine where the parser is located, and other system impacts.

This rule raises an issue when a Transformer is created without either of these settings.

Noncompliant Code Example

Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.transform(input, result);

Compliant Solution

TransformerFactory factory = TransformerFactory.newInstance();
factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);

Transformer transformer = factory.newTransformer();

transformer.transform(input, result);

or

TransformerFactory factory = TransformerFactory.newInstance();
factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, "");

Transformer transformer = factory.newTransformer();

transformer.transform(input, result);

See

squid:S2258

By contract, the NullCipher class provides an "identity cipher" one that does not transform or encrypt the plaintext in any way. As a consequence, the ciphertext is identical to the plaintext. So this class should be used for testing, and never in production code.

Noncompliant Code Example

NullCipher nc = new NullCipher();

See

squid:S4434

JNDI supports the deserialization of objects from LDAP directories, which is fundamentally insecure and can lead to remote code execution.

This rule raises an issue when an LDAP search query is executed with SearchControls configured to allow deserialization.

Noncompliant Code Example

DirContext ctx = new InitialDirContext();
// ...
ctx.search(query, filter,
        new SearchControls(scope, countLimit, timeLimit, attributes,
            true, // Noncompliant; allows deserialization
            deref));

Compliant Solution

DirContext ctx = new InitialDirContext();
// ...
ctx.search(query, filter,
        new SearchControls(scope, countLimit, timeLimit, attributes,
            false,
            deref));

See

squid:S2254

According to the Oracle Java API, the HttpServletRequest.getRequestedSessionId() method:

Returns the session ID specified by the client. This may not be the same as the ID of the current valid session for this request. If the client did not specify a session ID, this method returns null.

The session ID it returns is either transmitted in a cookie or a URL parameter so by definition, nothing prevents the end-user from manually updating the value of this session ID in the HTTP request.

Here is an example of a updated HTTP header:

GET /pageSomeWhere HTTP/1.1
Host: webSite.com
User-Agent: Mozilla/5.0
Cookie: JSESSIONID=Hacked_Session_Value'''">

Due to the ability of the end-user to manually change the value, the session ID in the request should only be used by a servlet container (E.G. Tomcat or Jetty) to see if the value matches the ID of an an existing session. If it does not, the user should be considered unauthenticated. Moreover, this session ID should never be logged to prevent hijacking of active sessions.

Noncompliant Code Example

if(isActiveSession(request.getRequestedSessionId()) ){
  ...
}

See

squid:S4433

An un-authenticated LDAP connection can lead to transactions without access control. Authentication, and with it, access control, are the last line of defense against LDAP injections and should not be disabled.

This rule raises an issue when an LDAP connection is created with Context.SECURITY_AUTHENTICATION set to "none".

Noncompliant Code Example

// Set up the environment for creating the initial context
Hashtable<String, Object> env = new Hashtable<String, Object>();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL, "ldap://localhost:389/o=JNDITutorial");

// Use anonymous authentication
env.put(Context.SECURITY_AUTHENTICATION, "none"); // Noncompliant

// Create the initial context
DirContext ctx = new InitialDirContext(env);

Compliant Solution

// Set up the environment for creating the initial context
Hashtable<String, Object> env = new Hashtable<String, Object>();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL, "ldap://localhost:389/o=JNDITutorial");

// Use simple authentication
env.put(Context.SECURITY_AUTHENTICATION, "simple");
env.put(Context.SECURITY_PRINCIPAL, "cn=S. User, ou=NewHires, o=JNDITutorial");
env.put(Context.SECURITY_CREDENTIALS, getLDAPPassword());

// Create the initial context
DirContext ctx = new InitialDirContext(env);

See

squid:S4432

The Advanced Encryption Standard (AES) encryption algorithm can be used with various modes. Some combinations are not secured:

  • Electronic Codebook (ECB) mode: Under a given key, any given plaintext block always gets encrypted to the same ciphertext block. Thus, it does not hide data patterns well. In some senses, it doesn't provide serious message confidentiality, and it is not recommended for use in cryptographic protocols at all.
  • Cipher Block Chaining (CBC) with PKCS#5 padding (or PKCS#7) is susceptible to padding oracle attacks.

In both cases, Galois/Counter Mode (GCM) with no padding should be preferred.

This rule raises an issue when a Cipher instance is created with either ECB or CBC/PKCS5Padding mode.

Noncompliant Code Example

Cipher c1 = Cipher.getInstance("AES/ECB/NoPadding"); // Noncompliant
Cipher c2 = Cipher.getInstance("AES/CBC/PKCS5Padding"); // Noncompliant

Compliant Solution

Cipher c = Cipher.getInstance("AES/GCM/NoPadding");

See

squid:S2755

Allowing external entities in untrusted documents to be processed could lay your systems bare to attackers. Imagine if these entities were parsed:

<!ENTITY xxe SYSTEM "file:///etc/passwd" >]><foo>&xxe;</foo>
<!ENTITY xxe SYSTEM "http://www.attacker.com/text.txt" >]><foo>&xxe;</foo>

If you must parse untrusted XML, the best way to protect yourself is to use a local, static DTD during parsing and ignore any DTD's included in included in the document.

This rule raises an issue when any of the following are used without first disabling external entity processing: javax.xml.validation.Validator, JAXP's DocumentBuilderFactory, SAXParserFactory, Xerces 1 and Xerces 2 StAX's XMLInputFactory and XMLReaderFactory.

To disable external entity processing for XMLInputFactory, configure one of the properties XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES or XMLInputFactory.SUPPORT_DTD to false.

To disable external entity processing for SAXParserFactory, XMLReader or DocumentBuilderFactory configure one of the features XMLConstants.FEATURE_SECURE_PROCESSING or "http://apache.org/xml/features/disallow-doctype-decl" to true.

To disable external entity processing for Validator, configure both properties XMLConstants.ACCESS_EXTERNAL_DTD, XMLConstants.ACCESS_EXTERNAL_SCHEMA to the empty string "".

Noncompliant Code Example

/* Load XML stream and display content */
String maliciousSample = "xxe.xml";
XMLInputFactory factory = XMLInputFactory.newInstance();

try (FileInputStream fis = new FileInputStream(malicousSample)) {
  // Load XML stream
  XMLStreamReader xmlStreamReader = factory.createXMLStreamReader(fis);  // Noncompliant; reader is vulnerable

  //...

Compliant Solution

/* Load XML stream and display content */
String maliciousSample = "xxe.xml";
XMLInputFactory factory = XMLInputFactory.newInstance();

// disable external entities
factory.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, Boolean.FALSE);
factory.setProperty(XMLInputFactory.SUPPORT_DTD, Boolean.FALSE);

try (FileInputStream fis = new FileInputStream(malicousSample)) {
    // Load XML stream
    XMLStreamReader xmlStreamReader = factory.createXMLStreamReader(fis);

See

squid:S2976

Using File.createTempFile as the first step in creating a temporary directory causes a race condition and is inherently unreliable and insecure. Instead, Files.createTempDirectory (Java 7+) or a library function such as Guava's similarly-named Files.createTempDir should be used.

This rule raises an issue when the following steps are taken in immediate sequence:

  • call to File.createTempFile
  • delete resulting file
  • call mkdir on the File object

Note that this rule is automatically disabled when the project's sonar.java.source is lower than 7.

Noncompliant Code Example

File tempDir;
tempDir = File.createTempFile("", ".");
tempDir.delete();
tempDir.mkdir();  // Noncompliant

Compliant Solution

Path tempPath = Files.createTempDirectory("");
File tempDir = tempPath.toFile();

See

squid:S3510

To prevent URL spoofing, HostnameVerifier.verify() methods should do more than simply return true. Doing so may get you quickly past an exception, but that comes at the cost of opening a security hole in your application.

Noncompliant Code Example

SSLContext sslcontext = SSLContext.getInstance( "TLS" );
sslcontext.init(null, new TrustManager[]{new X509TrustManager() {
  public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {}
  public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {}
  public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0]; }

}}, new java.security.SecureRandom());

Client client = ClientBuilder.newBuilder().sslContext(sslcontext).hostnameVerifier(new HostnameVerifier() {
  @Override
  public boolean verify(String requestedHost, SSLSession remoteServerSession) {
    return true;  // Noncompliant
  }
}).build();

Compliant Solution

SSLContext sslcontext = SSLContext.getInstance( "TLSv1.2" );
sslcontext.init(null, new TrustManager[]{new X509TrustManager() {
  @Override
  public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {}
  @Override
  public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {}
  @Override
  public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0]; }

}}, new java.security.SecureRandom());

Client client = ClientBuilder.newBuilder().sslContext(sslcontext).hostnameVerifier(new HostnameVerifier() {
  @Override
  public boolean verify(String requestedHost, SSLSession remoteServerSession) {
    return requestedHost.equalsIgnoreCase(remoteServerSession.getPeerHost()); // Compliant
  }
}).build();

See

squid:S3752

A @RequestMapping method handles all matching requests by default. That means that a method you intended only to be POST-ed to could also be called by a GET, thereby allowing hackers to call the method inappropriately. For example a "transferFunds" method might be invoked like so: <img src="http://bank.com/actions/transferFunds?reciepientRouting=000000&receipientAccount=11111111&amount=200.00" width="1" height="1"/>

For that reason, you should always explicitly list the single HTTP method with which you expect your @RequestMapping Java method to be called. This rule raises an issue when method is missing and when the method parameter is configured with more than one verb. Mixing GET and POST verbs can lead to information leakage. It's easier to setup Spring Security’s CSRF protection when there is only one verb per @RequestMapping.

Noncompliant Code Example

@RequestMapping("/greet")  // Noncompliant
public String greet(String greetee) {

Compliant Solution

  @RequestMapping("/greet", method = GET)
  public String greet(String greetee) {

See

squid:S4601

URL patterns configured on a HttpSecurity.authorizeRequests() method are considered in the order they were declared. It's easy to do a mistake and to declare a less restrictive configuration before a more restrictive one. Therefore, it's required to review the order of the "antMatchers" declarations. The /** one should be the last one if it is declared.

This rule raises an issue when:

- A pattern is preceded by another that ends with ** and has the same beginning. E.g.: /page*-admin/db/** is after /page*-admin/**

- A pattern without wildcard characters is preceded by another that matches. E.g.: /page-index/db is after /page*/**

Noncompliant Code Example

  protected void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests()
      .antMatchers("/resources/**", "/signup", "/about").permitAll() // Compliant
      .antMatchers("/admin/**").hasRole("ADMIN")
      .antMatchers("/admin/login").permitAll() // Noncompliant; the pattern "/admin/login" should occurs before "/admin/**"
      .antMatchers("/**", "/home").permitAll()
      .antMatchers("/db/**").access("hasRole('ADMIN') and hasRole('DBA')") // Noncompliant; the pattern "/db/**" should occurs before "/**"
      .and().formLogin().loginPage("/login").permitAll().and().logout().permitAll();
  }

Compliant Solution

  protected void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests()
      .antMatchers("/resources/**", "/signup", "/about").permitAll() // Compliant
      .antMatchers("/admin/login").permitAll()
      .antMatchers("/admin/**").hasRole("ADMIN") // Compliant
      .antMatchers("/db/**").access("hasRole('ADMIN') and hasRole('DBA')")
      .antMatchers("/**", "/home").permitAll() // Compliant; "/**" is the last one
      .and().formLogin().loginPage("/login").permitAll().and().logout().permitAll();
  }

See

squid:S3751

A method with a @RequestMapping annotation part of a class annotated with @Controller (directly or indirectly through a meta annotation - @RestController from Spring Boot is a good example) will be called to handle matching web requests. That will happen even if the method is private, because Spring invokes such methods via reflection, without checking visibility.

So marking a sensitive method private may seem like a good way to control how such code is called. Unfortunately, not all Spring frameworks ignore visibility in this way. For instance, if you've tried to control web access to your sensitive, private, @RequestMapping method by marking it @Secured ... it will still be called, whether or not the user is authorized to access it. That's because AOP proxies are not applied to non-public methods.

In addition to @RequestMapping, this rule also considers the annotations introduced in Spring Framework 4.3: @GetMapping, @PostMapping, @PutMapping, @DeleteMapping, @PatchMapping.

Noncompliant Code Example

@RequestMapping("/greet", method = GET)
private String greet(String greetee) {  // Noncompliant

Compliant Solution

@RequestMapping("/greet", method = GET)
public String greet(String greetee) {

See

squid:S2647

Basic authentication's only means of obfuscation is Base64 encoding. Since Base64 encoding is easily recognized and reversed, it offers only the thinnest veil of protection to your users, and should not be used.

Noncompliant Code Example

// Using HttpPost from Apache HttpClient
String encoding = Base64Encoder.encode ("login:passwd");
org.apache.http.client.methods.HttpPost httppost = new HttpPost(url);
httppost.setHeader("Authorization", "Basic " + encoding);  // Noncompliant

or

// Using HttpURLConnection
String encoding = Base64.getEncoder().encodeToString(("login:passwd").getBytes(‌"UTF‌​-8"​));
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setDoOutput(true);
conn.setRequestProperty("Authorization", "Basic " + encoding); // Noncompliant

See

squid:S2653

There is no reason to have a main method in a web application. It may have been useful for debugging during application development, but such a method should never make it into production. Having a main method in a web application opens a door to the application logic that an attacker may never be able to reach (but watch out if one does!), but it is a sloppy practice and indicates that other problems may be present.

This rule raises an issue when a main method is found in a servlet or an EJB.

Noncompliant Code Example

public class MyServlet extends HttpServlet {
  public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
    if (userIsAuthorized(req)) {
      updatePrices(req);
    }
  }

  public static void main(String[] args) { // Noncompliant
    updatePrices(req);
  }
}

See

squid:S3749

Spring @Controller, @Service, and @Repository classes are singletons by default, meaning only one instance of the class is ever instantiated in the application. Typically such a class might have a few static members, such as a logger, but all non-static members should be managed by Spring. That is, they should have one of these annotations: @Resource, @Inject, @Autowired or @Value.

Having non-injected members in one of these classes could indicate an attempt to manage state. Because they are singletons, such an attempt is almost guaranteed to eventually expose data from User1's session to User2.

This rule raises an issue when a singleton @Controller, @Service, or @Repository has non-static members that are not annotated with one of:

  • org.springframework.beans.factory.annotation.Autowired
  • org.springframework.beans.factory.annotation.Value
  • javax.annotation.Inject
  • javax.annotation.Resource

Noncompliant Code Example

@Controller
public class HelloWorld {

  private String name = null;

  @RequestMapping("/greet", method = GET)
  public String greet(String greetee) {

    if (greetee != null) {
      this.name = greetee;
    }

    return "Hello " + this.name;  // if greetee is null, you see the previous user's data
  }
}

See

squid:S1989

Even though the signatures for methods in a servlet include throws IOException, ServletException, it's a bad idea to let such exceptions be thrown. Failure to catch exceptions in a servlet could leave a system in a vulnerable state, possibly resulting in denial-of-service attacks, or the exposure of sensitive information because when a servlet throws an exception, the servlet container typically sends debugging information back to the user. And that information could be very valuable to an attacker.

This rule checks all exceptions in methods named "do*" are explicitly handled in servlet classes.

Noncompliant Code Example

public void doGet(HttpServletRequest request, HttpServletResponse response)
  throws IOException, ServletException {
  String ip = request.getRemoteAddr();
  InetAddress addr = InetAddress.getByName(ip); // Noncompliant; getByName(String) throws UnknownHostException
  //...
}

Compliant Solution

public void doGet(HttpServletRequest request, HttpServletResponse response)
  throws IOException, ServletException {
  try {
    String ip = request.getRemoteAddr();
    InetAddress addr = InetAddress.getByName(ip);
    //...
  }
  catch (UnknownHostException uhex) {
    //...
  }
}

See

squid:S2068

Because it is easy to extract strings from a compiled application, credentials should never be hard-coded. Do so, and they're almost guaranteed to end up in the hands of an attacker. This is particularly true for applications that are distributed.

Credentials should be stored outside of the code in a strongly-protected encrypted configuration file or database.

It's recommended to customize the configuration of this rule with additional credential words such as "oauthToken", "secret", ...

Noncompliant Code Example

Connection conn = null;
try {
  conn = DriverManager.getConnection("jdbc:mysql://localhost/test?" +
        "user=steve&password=blue"); // Noncompliant
  String uname = "steve";
  String password = "blue";
  conn = DriverManager.getConnection("jdbc:mysql://localhost/test?" +
        "user=" + uname + "&password=" + password); // Noncompliant

  java.net.PasswordAuthentication pa = new java.net.PasswordAuthentication("userName", "1234".toCharArray());  // Noncompliant

Compliant Solution

Connection conn = null;
try {
  String uname = getEncryptedUser();
  String password = getEncryptedPass();
  conn = DriverManager.getConnection("jdbc:mysql://localhost/test?" +
        "user=" + uname + "&password=" + password);

See

squid:S5344

Storing users' passwords in clear-text in a database is definitely not safe as hackers may have read access to all user accounts stored in the database. It's common then to hash passwords and only store these hashes in the database. When running the authentication process, the hash of the password provided by the user is compared to the hash stored in the database. If both matches, the access is granted.

This looks like a perfect solution but some algorithms such as MD5 and its successor, SHA-1, are no longer considered secure, because it is too easy to create hash collisions with them.

That is, it takes too little computational effort to come up with a different input that produces the same MD5 or SHA-1 hash, and using the new, same-hash value gives an attacker the same access as if he had the originally-hashed value. This applies as well to the other Message-Digest algorithms: MD2, MD4, MD6, HAVAL-128, HMAC-MD5, DSA (which uses SHA-1), RIPEMD, RIPEMD-128, RIPEMD-160, HMACRIPEMD160.

For this reason, when PasswordEncoder is used to authenticate user in a Spring application, it should use a secure algorithm. The following algorithms are considered not safe and should not be used:

  • org.springframework.security.authentication.encoding.ShaPasswordEncoder (Spring Security 4.2.x)
  • org.springframework.security.authentication.encoding.Md5PasswordEncoder (Spring Security 4.2.x)
  • org.springframework.security.crypto.password.LdapShaPasswordEncoder (Spring Security 5.0.x)
  • org.springframework.security.crypto.password.Md4PasswordEncoder (Spring Security 5.0.x)
  • org.springframework.security.crypto.password.MessageDigestPasswordEncoder (Spring Security 5.0.x)
  • org.springframework.security.crypto.password.NoOpPasswordEncoder (Spring Security 5.0.x)
  • org.springframework.security.crypto.password.StandardPasswordEncoder (Spring Security 5.0.x)
  • org.springframework.security.crypto.scrypt.SCryptPasswordEncoder (Spring Security 5.0.x)

Consider using safer alternatives, such as org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder (preferred) or org.springframework.security.crypto.password.Pbkdf2PasswordEncoder.

Noncompliant Code Example

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth, DataSource dataSource) throws Exception {
        auth.jdbcAuthentication()
                .dataSource(dataSource)
                .usersByUsernameQuery("SELECT * FROM users WHERE username = ?")
                .passwordEncoder(new StandardPasswordEncoder()); // Noncompliant
        // OR
        auth.jdbcAuthentication()
                .dataSource(dataSource)
                .usersByUsernameQuery("SELECT * FROM users WHERE username = ?"); // Noncompliant; default uses plain-text
        // OR
        auth.userDetailsService(...); // Noncompliant; default uses plain-text
        // OR
        auth.userDetailsService(...).passwordEncoder(new StandardPasswordEncoder()); // Noncompliant
    }

Compliant Solution

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth, DataSource dataSource) throws Exception {
        auth.jdbcAuthentication()
                .dataSource(dataSource)
                .usersByUsernameQuery("Select * from users where username=?")
                .passwordEncoder(new BCryptPasswordEncoder());
        // or
        auth.userDetailsService(null).passwordEncoder(new BCryptPasswordEncoder());
    }

See

squid:S4499

This rule raises an issue when:

- a JavaMail's javax.mail.Session is created with a Properties object having no mail.smtp.ssl.checkserveridentity or mail.smtps.ssl.checkserveridentity not configured to true

- a Apache Common Emails's org.apache.commons.mail.SimpleEmail is used with setSSLOnConnect(true) or setStartTLSEnabled(true) or setStartTLSRequired(true) without a call to setSSLCheckServerIdentity(true)

Noncompliant Code Example

Email email = new SimpleEmail();
email.setSmtpPort(465);
email.setAuthenticator(new DefaultAuthenticator(username, password));
email.setSSLOnConnect(true); // Noncompliant; setSSLCheckServerIdentity(true) should also be called before sending the email
email.send();
Properties props = new Properties();
props.put("mail.smtp.host", "smtp.gmail.com");
props.put("mail.smtp.socketFactory.port", "465");
props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory"); // Noncompliant; Session is created without having "mail.smtp.ssl.checkserveridentity" set to true
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.port", "465");
Session session = Session.getDefaultInstance(props, new javax.mail.Authenticator() {
  protected PasswordAuthentication getPasswordAuthentication() {
    return new PasswordAuthentication("username@gmail.com", "password");
  }
});

Compliant Solution

Email email = new SimpleEmail();
email.setSmtpPort(465);
email.setAuthenticator(new DefaultAuthenticator(username, password));
email.setSSLOnConnect(true);
email.setSSLCheckServerIdentity(true); // Compliant
email.send();
Properties props = new Properties();
props.put("mail.smtp.host", "smtp.gmail.com");
props.put("mail.smtp.socketFactory.port", "465");
props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.port", "465");
props.put("mail.smtp.ssl.checkserveridentity", true); // Compliant
Session session = Session.getDefaultInstance(props, new javax.mail.Authenticator() {
  protected PasswordAuthentication getPasswordAuthentication() {
    return new PasswordAuthentication("username@gmail.com", "password");
  }
});

See

squid:S2070

The MD5 algorithm and its successor, SHA-1, are no longer considered secure, because it is too easy to create hash collisions with them. That is, it takes too little computational effort to come up with a different input that produces the same MD5 or SHA-1 hash, and using the new, same-hash value gives an attacker the same access as if he had the originally-hashed value. This applies as well to the other Message-Digest algorithms: MD2, MD4, MD6, HAVAL-128, HMAC-MD5, DSA (which uses SHA-1), RIPEMD, RIPEMD-128, RIPEMD-160, HMACRIPEMD160.

The following APIs are tracked for use of obsolete crypto algorithms:

* java.security.AlgorithmParameters (JDK)

* java.security.AlgorithmParameterGenerator (JDK)

* java.security.MessageDigest (JDK)

* java.security.KeyFactory (JDK)

* java.security.KeyPairGenerator (JDK)

* java.security.Signature (JDK)

* javax.crypto.Mac (JDK)

* javax.crypto.KeyGenerator (JDK)

* org.apache.commons.codec.digest.DigestUtils (Apache Commons Codec)

* com.google.common.hash.Hashing (Guava)

* org.springframework.security.authentication.encoding.ShaPasswordEncoder (Spring Security 4.2.x)

* org.springframework.security.authentication.encoding.Md5PasswordEncoder (Spring Security 4.2.x)

* org.springframework.security.crypto.password.LdapShaPasswordEncoder (Spring Security 5.0.x)

* org.springframework.security.crypto.password.Md4PasswordEncoder (Spring Security 5.0.x)

* org.springframework.security.crypto.password.MessageDigestPasswordEncoder (Spring Security 5.0.x)

* org.springframework.security.crypto.password.NoOpPasswordEncoder (Spring Security 5.0.x)

* org.springframework.security.crypto.password.StandardPasswordEncoder (Spring Security 5.0.x)

Consider using safer alternatives, such as SHA-256, SHA-3 or adaptive one way functions like bcrypt or PBKDF2.

Noncompliant Code Example

MessageDigest md = MessageDigest.getInstance("SHA1");  // Noncompliant

Compliant Solution

MessageDigest md = MessageDigest.getInstance("SHA-256");

See

Deprecated

This rule is deprecated; use S4790 instead.

squid:S3281

Default interceptors, such as application security interceptors, must be listed in the ejb-jar.xml file, or they will not be treated as default.

This rule applies to projects that contain JEE Beans (any one of javax.ejb.Singleton, MessageDriven, Stateless or Stateful).

Noncompliant Code Example

// file: ejb-interceptors.xml
<assembly-descriptor>
 <interceptor-binding> <!-- should be declared in ejb-jar.xml -->
      <ejb-name>*</ejb-name>
      <interceptor-class>com.myco.ImportantInterceptor</interceptor-class><!-- Noncompliant; will NOT be treated as default -->
   </interceptor-binding>
</assembly-descriptor>

Compliant Solution

// file: ejb-jar.xml
<assembly-descriptor>
 <interceptor-binding>
      <ejb-name>*</ejb-name>
      <interceptor-class>com.myco.ImportantInterceptor</interceptor-class>
   </interceptor-binding>
</assembly-descriptor>

See

squid:S4347

The java.security.SecureRandom class provides a strong random number generator (RNG) appropriate for cryptography. However, seeding it with a constant or another predictable value will weaken it significantly. In general, it is much safer to rely on the seed provided by the SecureRandom implementation.

This rule raises an issue when SecureRandom.setSeed() or SecureRandom(byte[]) are called with a seed that is either of:

  • a constant
  • System.currentTimeMillis()

Noncompliant Code Example

SecureRandom sr = new SecureRandom();
sr.setSeed(123456L); // Noncompliant
int v = sr.next(32);

sr = new SecureRandom("abcdefghijklmnop".getBytes("us-ascii")); // Noncompliant
v = sr.next(32);

Compliant Solution

SecureRandom sr = new SecureRandom();
int v = sr.next(32);

See

squid:S2089

The fields in an HTTP request are putty in the hands of an attacker, and you cannot rely on them to tell you the truth about anything. While it may be safe to store such values after they have been neutralized, decisions should never be made based on their contents.

This rule flags uses of the referer header field.

Noncompliant Code Example

public class MyServlet extends HttpServlet {
  protected void doPost(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
    String referer = request.getHeader("referer");  // Noncompliant
    if(isTrustedReferer(referer)){
      //..
    }
    //...
  }
}

See

squid:S899

When the return value of a function call contain the operation status code, this value should be tested to make sure the operation completed successfully.

This rule raises an issue when the return values of the following are ignored:

  • java.io.File operations that return a status code (except mkdirs)
  • Iterator.hasNext()
  • Enumeration.hasMoreElements()
  • Lock.tryLock()
  • non-void Condition.await* methods
  • CountDownLatch.await(long, TimeUnit)
  • Semaphore.tryAcquire
  • BlockingQueue: offer, remove

Noncompliant Code Example

public void doSomething(File file, Lock lock) {
  file.delete();  // Noncompliant
  // ...
  lock.tryLock(); // Noncompliant
}

Compliant Solution

public void doSomething(File file, Lock lock) {
  if (!lock.tryLock()) {
    // lock failed; take appropriate action
  }
  if (!file.delete()) {
    // file delete failed; take appropriate action
  }
}

See

  • MISRA C:2004, 16.10 - If a function returns error information, then that error information shall be tested
  • MISRA C++:2008, 0-1-7 - The value returned by a function having a non-void return type that is not an overloaded operator shall always be used.
  • MISRA C:2012, Dir. 4.7 - If a function returns error information, then that error information shall be tested
  • MISRA C:2012, 17.7 - The value returned by a function having non-void return type shall be used
  • CERT, ERR33-C. - Detect and handle standard library errors
  • CERT, POS54-C. - Detect and handle POSIX library errors
  • CERT, EXP00-J. - Do not ignore values returned by methods
  • CERT, EXP12-C. - Do not ignore values returned by functions
  • CERT, FIO02-J. - Detect and handle file-related errors
  • MITRE, CWE-754 - Improper Check for Unusual Exceptional Conditions
tsql:S2068

Because it is easy to extract strings from a compiled application, credentials should never be hard-coded. Do so, and they're almost guaranteed to end up in the hands of an attacker. This is particularly true for applications that are distributed.

Credentials should be stored outside of the code in a strongly-protected encrypted configuration file or database.

This rule flags instances of hard-coded credentials used in database and LDAP connections. It looks for hard-coded credentials in connection strings, and for variable names that match any of the patterns from the provided list.

It's recommended to customize the configuration of this rule with additional credential words such as "oauthToken", "secret", ...

See

tsql:S2070

The MD5 algorithm and its successor, SHA-1, are no longer considered secure, because it is too easy to create hash collisions with them. That is, it takes too little computational effort to come up with a different input that produces the same MD5 or SHA-1 hash, and using the new, same-hash value gives an attacker the same access as if he had the originally-hashed value. This applies as well to the other Message-Digest algorithms: MD2, MD4, MD6, HAVAL-128, HMAC-MD5, DSA (which uses SHA-1), RIPEMD, RIPEMD-128, RIPEMD-160, HMACRIPEMD160.

Consider using safer alternatives, such as SHA-256, or SHA-3.

Noncompliant Code Example

SELECT HASHBYTES('SHA1', MyColumn) FROM dbo.MyTable;

Compliant Solution

SELECT HASHBYTES('SHA2_256', MyColumn) FROM dbo.MyTable;

See

csharpsquid:S4426

When generating cryptograpic keys (or key pairs), it is important to use a key length that provides enough entropy against brute-force attacks. For the RSA algorithm the key should be at

least 2048 bits long.

This rule raises an issue when a RSA key-pair generator is initialized with too small a length parameter.

Noncompliant Code Example

using System;
using System.Security.Cryptography;

namespace MyLibrary
{
    public class MyCryptoClass
    {
        static void Main()
        {
            RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(1024); // Noncompliant
            // ...
        }
    }
}

Compliant Solution

using System;
using System.Security.Cryptography;

namespace MyLibrary
{
    public class MyCryptoClass
    {
        static void Main()
        {
            RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(2048);
            // ...
        }
    }
}

See

csharpsquid:S3330

The HttpOnly cookie attribute tells the browser to prevent client-side scripts from reading cookies with the attribute, and its use can go a long way to defending against Cross-Site Scripting (XSS) attacks. Thus, as a precaution, the attribute should be set by default on all cookies set server-side, such as session id cookies.

When implementing Cross Site Request Forgery (XSRF) protection, a JavaScript-readable session cookie, generally named XSRF-TOKEN, should be created on the first HTTP GET request. For such a cookie, the HttpOnly attribute should be set to "false".

Setting the attribute can be done either programmatically, or globally via configuration files.

Noncompliant Code Example

HttpCookie myCookie = new HttpCookie("UserSettings");
myCookie.HttpOnly = false; // Noncompliant; explicitly set to false
...
Response.Cookies.Add(myCookie);
HttpCookie myCookie = new HttpCookie("UserSettings"); // Noncompliant; the default value of 'HttpOnly' is used (=false)
...
Response.Cookies.Add(myCookie);

Compliant Solution

HttpCookie myCookie = new HttpCookie("UserSettings");
myCookie.HttpOnly = true; // Compliant
...
Response.Cookies.Add(myCookie);

See

csharpsquid:S2070

The MD5 algorithm and its successor, SHA-1, are no longer considered secure, because it is too easy to create hash collisions with them. That is, it takes too little computational effort to come up with a different input that produces the same MD5 or SHA-1 hash, and using the new, same-hash value gives an attacker the same access as if he had the originally-hashed value. This applies as well to the other Message-Digest algorithms: MD2, MD4, MD6.

This rule tracks usage of the System.Security.Cryptography.CryptoConfig.CreateFromName(), and System.Security.Cryptography.HashAlgorithm.Create() methods to instantiate MD5, DSA, HMACMD5, HMACRIPEMD160, RIPEMD-160 or SHA-1 algorithms, and of derived class instances of System.Security.Cryptography.SHA1 and System.Security.Cryptography.MD5.

Consider using safer alternatives, such as SHA-256, or SHA-3.

Noncompliant Code Example

var hashProvider1 = new MD5CryptoServiceProvider(); //Noncompliant
var hashProvider2 = (HashAlgorithm)CryptoConfig.CreateFromName("MD5"); //Noncompliant
var hashProvider3 = new SHA1Managed(); //Noncompliant
var hashProvider4 = HashAlgorithm.Create("SHA1"); //Noncompliant

Compliant Solution

var hashProvider1 = new SHA256Managed();
var hashProvider2 = (HashAlgorithm)CryptoConfig.CreateFromName("SHA256Managed");
var hashProvider3 = HashAlgorithm.Create("SHA256Managed");

See

Deprecated

This rule is deprecated; use S4790 instead.

php:S2115

Failure to password-protect a database is so careless or naive as to be almost negligent. Databases should always be password protected, but the use of a database connection with an empty password is a clear indication of a database that is not protected.

This rule flags database connections with empty passwords.

Noncompliant Code Example

<?php
  $servername = "localhost";
  $username = "AppLogin";
  $password = "";

  // MySQL
  $conn = new mysqli($servername, $username, $password);
  // MySQL
  $conn = mysqli_connect($servername, $username, $password);
  // PDO way
  $conn = new PDO("mysql:host=$servername;dbname=myDB", $username, $password);
  // Oracle
  $conn = oci_connect($username, $password, "//localhost/orcl");
  // MS SQL Server
  $sqlsrvName = "serverName\sqlexpress";
  $sqlsrvConnInfo = array( "Database"=>"myDB", "UID"=>$username, "PWD"=>$password);
  $conn = sqlsrv_connect( $sqlsrvName, $sqlsrvConnInfo);
  // PosgreSQL
  $pgConnInfo = "host=localhost port=5432 dbname=test user=" . $username . " password=" . $password;
  $conn = pg_connect($pgConnInfo);
?>

See

php:S2070

The MD5 algorithm and its successor, SHA-1, are no longer considered secure, because it is too easy to create hash collisions with them. That is, it takes too little computational effort to come up with a different input that produces the same MD5 or SHA-1 hash, and using the new, same-hash value gives an attacker the same access as if he had the originally-hashed value. This applies as well to the other Message-Digest algorithms: MD2, MD4, MD6, HAVAL-128, HMAC-MD5, DSA (which uses SHA-1), RIPEMD, RIPEMD-128, RIPEMD-160, HMACRIPEMD160.

Consider using safer alternatives, such as SHA-256, or SHA-3.

Noncompliant Code Example

$password = ...

if (md5($password) === '1f3870be274f6c49b3e31a0c6728957f') { // Noncompliant; md5() hashing algorithm is not secure for password management
   [...]
}

if (sha1($password) === 'd0be2dc421be4fcd0172e5afceea3970e2f3d940') { // Noncompliant; sha1() hashing algorithm is not secure for password management
   [...]
}

See

Deprecated

This rule is deprecated; use S4790 instead.

php:S2964

sleep is sometimes used in a mistaken attempt to prevent Denial of Service (DoS) attacks by throttling response rate. But because it ties up a thread, each request takes longer to serve that it otherwise would, making the application more vulnerable to DoS attacks, rather than less.

Noncompliant Code Example

if (is_bad_ip($requester)) {
  sleep(5);  // Noncompliant
}

See

php:S2053

In cryptography, "salt" is extra piece of data which is included in a hashing algorithm. It makes dictionary attacks more difficult. Using a cryptographic hash function without an unpredictable salt increases the likelihood that an attacker will be able to successfully guess a hashed value such as a password with a dictionary attack.

This rule raises an issue when a hashing function which has been specifically designed for hashing sensitive data, such as pbkdf2, is used with a non-random, reused or too short salt value. It does not raise an issue on base hashing algorithms such as sha1 or md5 as these are often used for other purposes.

Recommended Secure Coding Practices

  • use hashing functions generating their own salt or generate a long random salt of at least 32 bytes.
  • the salt is at least as long as the resulting hash value.
  • provide the salt to a safe hashing function such as PBKDF2.
  • save both the salt and the hashed value in the relevant database record; during future validation operations, the salt and hash can then be retrieved from the database. The hash is recalculated with the stored salt and the value being validated, and the result compared to the stored hash.

Noncompliant Code Example

function createMyAccount() {
  $email = $_GET['email'];
  $name = $_GET['name'];
  $password = $_GET['password'];

  $hash = hash_pbkdf2('sha256', $password, $email, 100000); // Noncompliant; salt (3rd argument) is predictable because initialized with the provided $email

  $hash = hash_pbkdf2('sha256', $password, '', 100000); // Noncompliant; salt is empty

  $hash = hash_pbkdf2('sha256', $password, 'D8VxSmTZt2E2YV454mkqAY5e', 100000); // Noncompliant; salt is hardcoded

  $hash = crypt($password); // Noncompliant; salt is not provided
  $hash = crypt($password, ""); // Noncompliant; salt is hardcoded

  $options = [
    'cost' => 11,
    'salt' => mcrypt_create_iv(22, MCRYPT_DEV_URANDOM), // Noncompliant ; use salt generated by default
  ];
  echo password_hash("rasmuslerdorf", PASSWORD_BCRYPT, $options);
}

Compliant Solution

$salt = openssl_random_pseudo_bytes(16);
$hash = hash_pbkdf2("sha256", $password, $salt, $iterations, 20);

See

php:S2277

Without OAEP in RSA encryption, it takes less work for an attacker to decrypt the data or infer patterns from the ciphertext. This rule logs an issue when openssl_public_encrypt is used with one the following padding constants: OPENSSL_NO_PADDING or OPENSSL_PKCS1_PADDING or OPENSSL_SSLV23_PADDING.

Noncompliant Code Example

function encrypt($data, $key) {
  $crypted='';
  openssl_public_encrypt($data, $crypted, $key, OPENSSL_NO_PADDING); // Noncompliant
  return $crypted;
}

Compliant Solution

function encrypt($data, $key) {
  $crypted='';
  openssl_public_encrypt($data, $crypted, $key, OPENSSL_PKCS1_OAEP_PADDING);
  return $crypted;
}

See

php:S3336

PHP's session.use_trans_sid automatically appends the user's session id to urls when cookies are disabled. On the face of it, this seems like a nice way to let uncookie-able users use your site anyway. In reality, it makes those users vulnerable to having their sessions hijacked by anyone who might:

  • see the URL over the user's shoulder
  • be sent the URL by the user
  • retrieve the URL from browser history
  • ...

For that reason, it's better to practice a little "tough love" with your users and force them to turn on cookies.

Since session.use_trans_sid is off by default, this rule raises an issue when it is explicitly enabled.

Noncompliant Code Example

; php.ini
session.use_trans_sid=1  ; Noncompliant

See

php:S3337

enable_dl is on by default and allows open_basedir restrictions, which limit the files a script can access, to be ignored. For that reason, it's a dangerous option and should be explicitly turned off.

This rule raises an issue when enable_dl is not explicitly set to 0 in php.ini.

Noncompliant Code Example

; php.ini
enable_dl=1  ; Noncompliant

Compliant Solution

; php.ini
enable_dl=0

See

php:S4423

Not all SSL protocols are created equal and some legacy ones like "SSL", have been proven to be insecure.

This rule raises an issue when an SSL context is created with an insecure protocol (ie: a protocol different from "TLSv1.2" or "DTLSv1.2").

Noncompliant Code Example

$ctx = stream_context_create([
  'ssl' => [
    'crypto_method' =>
      STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT // Noncompliant
  ],
]);

Compliant Solution

$ctx = stream_context_create([
    'ssl' => [
        'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT
    ],
]);

See

php:S3334

allow_url_fopen and allow_url_include allow code to be read into a script from URL's. The ability to suck in executable code from outside your site, coupled with imperfect input cleansing could lay your site bare to attackers. Even if your input filtering is perfect today, are you prepared to bet your site that it will always be perfect in the future?

This rule raises an issue when either property is explicitly enabled in php.ini and when allow_url_fopen, which defaults to enabled, is not explicitly disabled.

Noncompliant Code Example

; php.ini  Noncompliant; allow_url_fopen not explicitly disabled
allow_url_include=1  ; Noncompliant

Compliant Solution

; php.ini
allow_url_fopen=0
allow_url_include=0

See

php:S4426

When generating cryptographic keys (or key pairs), it is important to use a key length that provides enough entropy against brute-force attacks. For the RSA algorithm, it should be at least 2048 bits long.

This rule raises an issue when an RSA key-pair generator is initialized with too small a length parameter.

Noncompliant Code Example

$config = array(
    "digest_alg" => "sha512",
    "private_key_bits" => 1024, // Noncompliant
    "private_key_type" => OPENSSL_KEYTYPE_RSA,
);
$res = openssl_pkey_new($config);

Compliant Solution

$config = array(
    "digest_alg" => "sha512",
    "private_key_bits" => 4096, // Compliant
    "private_key_type" => OPENSSL_KEYTYPE_RSA,
);
$res = openssl_pkey_new($config);

See

php:S3335

The cgi.force_redirect php.ini configuration is on by default, and it prevents unauthenticated access to scripts when PHP is running as a CGI. Unfortunately, it must be disabled on IIS, OmniHTTPD and Xitami, but in all other cases it should be on.

This rule raises an issue when when cgi.force_redirect is explicitly disabled.

Noncompliant Code Example

; php.ini
cgi.force_redirect=0  ; Noncompliant

See

php:S3332

Cookies without fixed lifetimes or expiration dates are known as non-persistent, or "session" cookies, meaning they last only as long as the browser session, and poof away when the browser closes. Cookies with expiration dates, "persistent" cookies, are stored/persisted until those dates.

Non-persistent cookies should be used for the management of logged-in sessions on web sites. To make a cookie non-persistent, simply omit the expires attribute.

This rule raises an issue when expires is set for a session cookie, either programmatically or via configuration, such as session.cookie_lifetime.

See

php:S3333

The open_basedir configuration in php.ini limits the files the script can access using, for example, include and fopen(). Leave it out, and there is no default limit, meaning that any file can be accessed. Include it, and PHP will refuse to access files outside the allowed path.

open_basedir should be configured with a directory, which will then be accessible recursively. However, the use of . (current directory) as an open_basedir value should be avoided since it's resolved dynamically during script execution, so a chdir('/') command could lay the whole server open to the script.

This is not a fool-proof configuration; it can be reset or overridden at the script level. But its use should be seen as a minimum due diligence step. This rule raises an issue when open_basedir is not present in php.ini, and when open_basedir contains root, or the current directory (.) symbol.

Noncompliant Code Example

; php.ini try 1
; open_basedir="${USER}/scripts/data"  Noncompliant; commented out

; php.ini try 2
open_basedir="/:${USER}/scripts/data"  ; Noncompliant; root directory in the list

Compliant Solution

; php.ini try 1
open_basedir="${USER}/scripts/data"

See

php:S3330

The HttpOnly cookie attribute tells the browser to prevent client-side scripts from reading cookies with the attribute, and its use can go a long way to defending against Cross-Site Scripting (XSS) attacks. Thus, as a precaution, the attribute should be set by default on all cookies set server-side, such as session id cookies.

Setting the attribute can be done either programmatically, or globally via configuration files.

This rule raises an issue:

  • when HttpOnly is missing from php.ini or explicitly set to false
  • when setcookie()'s last parameter is explicitly set to false

Noncompliant Code Example

; php.ini
session.cookie_httponly=false  ; Noncompliant; explicitly set to false

// file.php
setcookie($name, $value, $expire, $path, $domain, $secure, false);  // Noncompliant; explicitly set to false

See

php:S3338

file_uploads is an on-by-default PHP configuration that allows files to be uploaded to your site. Since accepting candy files from strangers is inherently dangerous, this feature should be disabled unless it is absolutely necessary for your site.

This rule raises an issue when file_uploads is not explicitly disabled.

Noncompliant Code Example

; php.ini
file_uploads=1  ; Noncompliant

Compliant Solution

; php.ini
file_uploads=0

See

php:S4830

Disabling SSL/TLS certificates chain of trust verification is similar to trust every one in the chain and so to expose the application to man-in-the-middle (MITM) attacks.

Noncompliant Code Example

curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, TRUE); // Noncompliant; TRUE is casted to 1 which is not a secure configuration
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0);

// and/or

curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);

Compliant Solution

curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2); // Compliant; default value is 2 to "check the existence of a common name and also verify that it matches the hostname provided" according to PHP's documentation

// and/or

curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, TRUE); // Compliant; default value is TRUE
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 1);

See

javasecurity:S2631

Evaluating regular expressions against input strings can be an extremely CPU-intensive task. For example, a specially crafted regular expression such as (a+)++ will take several seconds to evaluate the input string, aaaaaaaaaaaaaaaaaaaaaaaaaaaaa!. The problem is that every additional "a" added to the input doubles the time required to evaluate the regex. However, the equivalent regular expression, a (without grouping), is efficiently evaluated in milliseconds and scales linearly with the input size.

Evaluating user-provided strings as regular expressions opens the door for Denial Of Service attacks. In the context of a web application, attackers can force the web server to spend all of its resources evaluating regular expressions thereby making the service inaccessible to genuine users.

Noncompliant Code Example

public boolean validate(javax.servlet.http.HttpServletRequest request) {
  String regex = request.getParameter("regex");
  String input = request.getParameter("input");

  // Enables attackers to force the web server to evaluate
  // regex such as "(a+)+" on inputs such as "aaaaaaaaaaaaaaaaaaaaaaaaaaaaa!"

  input.matches(regex);  // Noncompliant
}

Compliant Solution

public boolean validate(javax.servlet.http.HttpServletRequest request) {
  String input = request.getParameter("input");

  input.matches("a+");  // Compliant - use a safe hardcoded regex
}

See

javasecurity:S5146

User provided data, such as URL parameters, POST data payloads, or cookies, should always be considered untrusted and tainted. Applications performing HTTP redirects based on tainted data could enable an attacker to redirect users to a malicious site to, for example, steal login credentials.

This problem could be mitigated in any of the following ways:

  • Validate the user provided data based on a whitelist and reject input not matching.
  • Redesign the application to not perform redirects based on user provided data.

Noncompliant Code Example

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
  String location = req.getParameter("url");
  resp.sendRedirect(location); // Noncompliant
}

Compliant Solution

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
  String location = req.getParameter("url");

  // Match the incoming URL against a whitelist
  if (!urlWhiteList.contains(location))
    throw new IOException();

  resp.sendRedirect(location);
}

See

javasecurity:S2078

User provided data such as URL parameters should always be considered as untrusted and tainted. Constructing LDAP names or search filters directly from tainted data enables attackers to inject specially crafted values that changes the initial meaning of the name or filter itself. Successful LDAP injections attacks can read, modify or delete sensitive information from the directory service.

Within LDAP names, the special characters ' ', '#', '"', '+', ',', ';', '<', '>', '\' and null must be escaped according to RFC 4514, for example by replacing them with the backslash character '\' followed by the two hex digits corresponding to the ASCII code of the character to be escaped. Similarly, LDAP search filters must escape a different set of special characters (including but not limited to '*', '(', ')', '\' and null) according to RFC 4515.

Noncompliant Code Example

public boolean authenticate(javax.servlet.http.HttpServletRequest request, DirContext ctx) throws NamingException {
  String user = request.getParameter("user");
  String pass = request.getParameter("pass");

  String filter = "(&(uid=" + user + ")(userPassword=" + pass + "))"; // Unsafe

  // If the special value "*)(uid=*))(|(uid=*" is passed as user, authentication is bypassed
  // Indeed, if it is passed as a user, the filter becomes:
  // (&(uid=*)(uid=*))(|(uid=*)(userPassword=...))
  // as uid=* match all users, it is equivalent to:
  // (|(uid=*)(userPassword=...))
  // again, as uid=* match all users, the filter becomes useless

  NamingEnumeration<SearchResult> results = ctx.search("ou=system", filter, new SearchControls()); // Noncompliant
  return results.hasMore();
}

Compliant Solution

public boolean authenticate(javax.servlet.http.HttpServletRequest request, DirContext ctx) throws NamingException {
  String user = request.getParameter("user");
  String pass = request.getParameter("pass");

  String filter = "(&(uid={0})(userPassword={1}))"; // Safe

  NamingEnumeration<SearchResult> results = ctx.search("ou=system", filter, new String[]{user, pass}, new SearchControls());
  return results.hasMore();
}

See

javasecurity:S5145

User provided data, such as URL parameters, POST data payloads or cookies, should always be considered untrusted and tainted. Applications logging tainted data could enable an attacker to inject characters that would break the log file pattern. This could be used to block monitors and SIEM (Security Information and Event Management) systems from detecting other malicious events.

This problem could be mitigated by sanitizing the user provided data before logging it.

Noncompliant Code Example

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
  String param1 = req.getParameter("param1");
  Logger.info("Param1: " + param1 + " " + Logger.getName()); // Noncompliant
  // ...
}

Compliant Solution

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
  String param1 = req.getParameter("param1");

  // Replace pattern-breaking characters
  param1 = param1.replaceAll("[\n|\r|\t]", "_");

  Logger.info("Param1: " + param1 + " " + Logger.getName());
  // ...
}

See

javasecurity:S5167

User provided data, such as URL parameters, POST data payloads, or cookies, should always be considered untrusted and tainted. Applications constructing HTTP response headers based on tainted data could allow attackers to inject characters that would be interpreted as a new line in some browsers. This could, for example, enable Cross-Site Scripting (XSS) attacks.

Most modern web application frameworks and servers mitigate this type of attack by default, but there might be rare cases where older versions are still vulnerable. As a best practice, applications that use user provided data to construct the response header should always validate the data first. Validation should be based on a whitelist.

Noncompliant Code Example

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
  String value = req.getParameter("value");
  resp.addHeader("X-Header", value); // Noncompliant
  // ...
}

Compliant Solution

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
  String value = req.getParameter("value");

  // Allow only alphanumeric characters
  if (!value.matches("[a-zA-Z0-9]++"))
    throw new IOException();

  resp.addHeader("X-Header", value);
  // ...
}

See

javasecurity:S2076

Applications that execute operating system commands or execute commands that interact with the underlying system should neutralize any externally-provided values used in those commands. Failure to do so could allow an attacker to include input that executes unintended commands or exposes sensitive data.

The mitigation strategy should be based on whitelisting of allowed characters or commands.

Noncompliant Code Example

public void run(javax.servlet.http.HttpServletRequest request) throws IOException {
  String binary = request.getParameter("binary");

  // If the value "/sbin/shutdown" is passed as binary and the web server is running as root,
  // then the machine running the web server will be shut down and become unavailable for future requests

  Runtime.getRuntime().exec(binary); // Noncompliant
}

Compliant Solution

public void run(javax.servlet.http.HttpServletRequest request) throws IOException {
  String binary = request.getParameter("binary");

  // Restrict to binaries within the current working directory whose name only contains letters
  if (!binary.matches("[a-zA-Z]++")) {
    throw new IllegalArgumentException();
  }

  Runtime.getRuntime().exec(binary);
}

See

javasecurity:S5131

User provided data, such as URL parameters, POST data payloads, or cookies, should always be considered untrusted and tainted. Endpoints reflecting back tainted data could allow attackers to inject code that would eventually be executed in the user's browser. This could enable a wide range of serious attacks like accessing/modifying sensitive information or impersonating other users.

Typically, the solution is one of the following:

  • Validate user provided data based on a whitelist and reject input that's not whitelisted.
  • Sanitize user provided data from any characters that can be used for malicious purposes.
  • Encode user provided data being reflected as output. Adjust the encoding to the output context so that, for example, HTML encoding is used for HTML content, HTML attribute encoding is used for attribute values, and JavaScript encoding is used for server-generated JavaScript.

When sanitizing or encoding data, it is recommended to only use libraries specifically designed for security purposes. Also, make sure that the library you are using is being actively maintained and is kept up-to-date with the latest discovered vulnerabilities.

Noncompliant Code Example

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
  String name = req.getParameter("name");
  PrintWriter out = resp.getWriter();
  out.write("Hello " + name); // Noncompliant
}

Compliant Solution

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
  String name = req.getParameter("name");
  String encodedName = org.owasp.encoder.Encode.forHtml(name);
  PrintWriter out = resp.getWriter();
  out.write("Hello " + encodedName);
}

See

  • OWASP Cheat Sheet - XSS Prevention Cheat Sheet
  • OWASP Top 10 2017 Category A7 - Cross-Site Scripting (XSS)
  • MITRE, CWE-79 - Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')
  • MITRE, CWE-80 - Improper Neutralization of Script-Related HTML Tags in a Web Page (Basic XSS)
  • MITRE, CWE-81 - Improper Neutralization of Script in an Error Message Web Page
  • MITRE, CWE-82 - Improper Neutralization of Script in Attributes of IMG Tags in a Web Page
  • MITRE, CWE-83 - Improper Neutralization of Script in Attributes in a Web Page
  • MITRE, CWE-84 - Improper Neutralization of Encoded URI Schemes in a Web Page
  • MITRE, CWE-85 - Doubled Character XSS Manipulations
  • MITRE, CWE-86 - Improper Neutralization of Invalid Characters in Identifiers in Web Pages
  • MITRE, CWE-87 - Improper Neutralization of Alternate XSS Syntax
  • SANS Top 25 - Insecure Interaction Between Components
javasecurity:S5144

User provided data, such as URL parameters, POST data payloads, or cookies, should always be considered untrusted and tainted. A remote server making requests to URLs based on tainted data could enable attackers to make arbitrary requests to the internal network or to the local file system.

The problem could be mitigated in any of the following ways:

  • Validate the user provided data based on a whitelist and reject input not matching.
  • Redesign the application to not send requests based on user provided data.

Noncompliant Code Example

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
  URL url = new URL(req.getParameter("url"));
  HttpURLConnection conn = (HttpURLConnection) url.openConnection(); // Noncompliant
  // ...
}

Compliant Solution

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
  URL url = new URL(req.getParameter("url"));

  // The safest way is to match the incoming URL against a whitelist
  if (!urlWhiteList.contains(url.toString()))
    throw new IOException();

  // If whitelisting is not possible, at least make sure that things like file:// and http://localhost are blocked
  InetAddress inetAddress = InetAddress.getByName(url.getHost());
  if (!url.getProtocol().startsWith("http") ||
      inetAddress.isAnyLocalAddress() ||
      inetAddress.isLoopbackAddress() ||
      inetAddress.isLinkLocalAddress())
    throw new IOException();

  HttpURLConnection conn = (HttpURLConnection) url.openConnection();
  // ...
}

See

javasecurity:S2083

User provided data, such as URL parameters, POST data payloads, or cookies, should always be considered untrusted and tainted. Constructing file system paths directly from tainted data could enable an attacker to inject specially crafted values, such as '../', that change the initial path and, when accessed, resolve to a path on the filesystem where the user should normally not have access.

A successful attack might give an attacker the ability to read, modify, or delete sensitive information from the file system and sometimes even execute arbitrary operating system commands. This is often referred to as a "path traversal" or "directory traversal" attack.

The mitigation strategy should be based on the whitelisting of allowed paths or characters.

Noncompliant Code Example

public boolean authenticate(javax.servlet.http.HttpServletRequest request) {
  String user = request.getParameter("user");

  // If the special value "../bin" is passed as user, authentication is bypassed
  // Indeed, if it passed as a user, the path becomes:
  // /bin
  // which exists on most Linux / BSD / Mac OS distributions

  return Files.exists(Paths.get("/home/", user)); // Noncompliant
}

Compliant Solution

public boolean authenticate(javax.servlet.http.HttpServletRequest request) {
  String user = request.getParameter("user");

  // Restrict the username to letters and digits only
  if (!user.matches("[a-zA-Z0-9]++")) {
    return false;
  }

  return Files.exists(Paths.get("/home/", user));
}

See

javasecurity:S2091

User provided data, such as URL parameters, should always be considered untrusted and tainted. Constructing XPath expressions directly from tainted data enables attackers to inject specially crafted values that changes the initial meaning of the expression itself. Successful XPath injection attacks can read sensitive information from XML documents.

Noncompliant Code Example

public boolean authenticate(javax.servlet.http.HttpServletRequest request, javax.xml.xpath.XPath xpath, org.w3c.dom.Document doc) throws XPathExpressionException {
  String user = request.getParameter("user");
  String pass = request.getParameter("pass");

  String expression = "/users/user[@name='" + user + "' and @pass='" + pass + "']"; // Unsafe

  // An attacker can bypass authentication by setting user to this special value
  user = "' or 1=1 or ''='";

  return (boolean)xpath.evaluate(expression, doc, XPathConstants.BOOLEAN); // Noncompliant
}

Compliant Solution

public boolean authenticate(javax.servlet.http.HttpServletRequest request, javax.xml.xpath.XPath xpath, org.w3c.dom.Document doc) throws XPathExpressionException {
  String user = request.getParameter("user");
  String pass = request.getParameter("pass");

  String expression = "/users/user[@name=$user and @pass=$pass]";

  xpath.setXPathVariableResolver(v -> {
    switch (v.getLocalPart()) {
      case "user":
        return user;
      case "pass":
        return pass;
      default:
        throw new IllegalArgumentException();
    }
  });

  return (boolean)xpath.evaluate(expression, doc, XPathConstants.BOOLEAN);
}

See

roslyn.sonaranalyzer.security.cs:S2631

Evaluating regular expressions against input strings can be an extremely CPU-intensive task. For example, a specially crafted regular expression such as (a+)++ will take several seconds to evaluate the input string, aaaaaaaaaaaaaaaaaaaaaaaaaaaaa!. The problem is that every additional "a" added to the input doubles the time required to evaluate the regex. However, the equivalent regular expression, a (without grouping), is efficiently evaluated in milliseconds and scales linearly with the input size.

Evaluating user-provided strings as regular expressions opens the door for Denial Of Service attacks. In the context of a web application, attackers can force the web server to spend all of its resources evaluating regular expressions thereby making the service inaccessible to genuine users.

Noncompliant Code Example

public class RegexDoS : Controller
{
  // GET /RegexDoS/Validate
  public IActionResult Validate(string regex, string input)
  {
    // Enables attackers to force the web server to evaluate
    // regex such as "^(a+)+$" on inputs such as "aaaaaaaaaaaaaaaaaaaaaaaaaaaaa!"

    bool match = Regex.IsMatch(input, regex); // Noncompliant

    return Content("Valid? " + match);
  }
}

Compliant Solution

public class RegexDoS : Controller
{
  // GET /RegexDoS/Validate
  public IActionResult Validate(string regex, string input)
  {
    // Option 1: Use a hardcoded regex
    bool match = Regex.IsMatch(input, "^a+$");

    // Option 2: Set a timeout on the regex's evaluation
    match = new Regex(regex, RegexOptions.None, TimeSpan.FromMilliseconds(100)).IsMatch(input);

    return Content("Valid? " + match);
  }
}

See

roslyn.sonaranalyzer.security.cs:S5146

User provided data, such as URL parameters, POST data payloads, or cookies, should always be considered untrusted and tainted. Applications performing HTTP redirects based on tainted data could enable an attacker to redirect users to a malicious site to, for example, steal login credentials.

This problem could be mitigated in any of the following ways:

  • Validate the user provided data based on a whitelist and reject input not matching.
  • Redesign the application to not perform redirects based on user provided data.

Noncompliant Code Example

public class OpenRedirect : Controller
{
  public IActionResult Test(string url)
  {
    return Redirect(url); // Noncompliant
  }
}

Compliant Solution

public class OpenRedirect : Controller
{
  private string[] whiteList = { "https://www.sonarsource.com" };

  public IActionResult Test(string url)
  {
    // Match the incoming URL against a whitelist
    if (!whiteList.Contains(url))
    {
      return BadRequest();
    }

    return Redirect(url);
  }
}

See

roslyn.sonaranalyzer.security.cs:S5145

User provided data, such as URL parameters, POST data payloads or cookies, should always be considered untrusted and tainted. Applications logging tainted data could enable an attacker to inject characters that would break the log file pattern. This could be used to block monitors and SIEM (Security Information and Event Management) systems from detecting other malicious events.

This problem could be mitigated by sanitizing the user provided data before logging it.

Noncompliant Code Example

public class LogForging : Controller
{
  public IActionResult Test(string id)
  {
    logger.Info("ID: {0}", id); // Noncompliant
    // ...
  }
}

Compliant Solution

public class LogForging : Controller
{
  public IActionResult Test(string id)
  {
    // Replace pattern-breaking characters
    id = id.Replace('\n', '_').Replace('\r', '_').Replace('\t', '_');

    logger.Info("ID: {0}", id);
    // ...
  }
}

See

roslyn.sonaranalyzer.security.cs:S5167

User provided data, such as URL parameters, POST data payloads, or cookies, should always be considered untrusted and tainted. Applications constructing HTTP response headers based on tainted data could allow attackers to inject characters that would be interpreted as a new line in some browsers. This could, for example, enable Cross-Site Scripting (XSS) attacks.

Most modern web application frameworks and servers mitigate this type of attack by default, but there might be rare cases where older versions are still vulnerable. As a best practice, applications that use user provided data to construct the response header should always validate the data first. Validation should be based on a whitelist.

Noncompliant Code Example

string value = Request.QueryString["value"];
Response.AddHeader("X-Header", value); // Noncompliant

Compliant Solution

string value = Request.QueryString["value"];
// Allow only alphanumeric characters
if (value == null || !Regex.IsMatch(value, "^[a-zA-Z0-9]+$"))
{
  throw new Exception("Invalid value");
}
Response.AddHeader("X-Header", value);

See

roslyn.sonaranalyzer.security.cs:S2076

Applications that execute operating system commands or execute commands that interact with the underlying system should neutralize any externally-provided values used in those commands. Failure to do so could allow an attacker to include input that executes unintended commands or exposes sensitive data.

The mitigation strategy should be based on whitelisting of allowed characters or commands.

Noncompliant Code Example

public class CommandInjection : Controller
{
  // GET /CommandInjection/Run
  public IActionResult Run(string binary)
  {
    // If the value "/sbin/shutdown" is passed as binary and the web server is running as root,
    // then the machine running the web server will be shut down and become unavailable for future requests

    Process p = new Process();
    p.StartInfo.FileName = binary; // Noncompliant
    p.StartInfo.RedirectStandardOutput = true;
    p.Start();
    string output = p.StandardOutput.ReadToEnd();
    return Content(output);
  }
}

Compliant Solution

public class CommandInjection : Controller
{
  // GET /CommandInjection/Run
  public IActionResult Run(string binary)
  {
    // Restrict to binaries within the current working directory whose name only contains letters
    if (binary == null || !Regex.IsMatch(binary, "^[a-zA-Z]+$"))
    {
      return BadRequest();
    }

    Process p = new Process();
    p.StartInfo.FileName = binary; // Now safe
    p.StartInfo.RedirectStandardOutput = true;
    p.Start();
    string output = p.StandardOutput.ReadToEnd();
    return Content(output);
  }
}

See

roslyn.sonaranalyzer.security.cs:S5131

User provided data, such as URL parameters, POST data payloads, or cookies, should always be considered untrusted and tainted. Endpoints reflecting back tainted data could allow attackers to inject code that would eventually be executed in the user's browser. This could enable a wide range of serious attacks like accessing/modifying sensitive information or impersonating other users.

Typically, the solution is one of the following:

  • Validate user provided data based on a whitelist and reject input that's not whitelisted.
  • Sanitize user provided data from any characters that can be used for malicious purposes.
  • Encode user provided data being reflected as output. Adjust the encoding to the output context so that, for example, HTML encoding is used for HTML content, HTML attribute encoding is used for attribute values, and JavaScript encoding is used for server-generated JavaScript.

When sanitizing or encoding data, it is recommended to only use libraries specifically designed for security purposes. Also, make sure that the library you are using is being actively maintained and is kept up-to-date with the latest discovered vulnerabilities.

Noncompliant Code Example

string name = Request.QueryString["name"];
Response.Write("Hello " + name); // Noncompliant

Compliant Solution

string name = Request.QueryString["name"];
name = System.Web.Security.AntiXss.AntiXssEncoder.HtmlEncode(name, true);
Response.Write("Hello " + name);

See

  • OWASP Cheat Sheet - XSS Prevention Cheat Sheet
  • OWASP Top 10 2017 Category A7 - Cross-Site Scripting (XSS)
  • MITRE, CWE-79 - Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')
  • MITRE, CWE-80 - Improper Neutralization of Script-Related HTML Tags in a Web Page (Basic XSS)
  • MITRE, CWE-81 - Improper Neutralization of Script in an Error Message Web Page
  • MITRE, CWE-82 - Improper Neutralization of Script in Attributes of IMG Tags in a Web Page
  • MITRE, CWE-83 - Improper Neutralization of Script in Attributes in a Web Page
  • MITRE, CWE-84 - Improper Neutralization of Encoded URI Schemes in a Web Page
  • MITRE, CWE-85 - Doubled Character XSS Manipulations
  • MITRE, CWE-86 - Improper Neutralization of Invalid Characters in Identifiers in Web Pages
  • MITRE, CWE-87 - Improper Neutralization of Alternate XSS Syntax
  • SANS Top 25 - Insecure Interaction Between Components
roslyn.sonaranalyzer.security.cs:S5144

User provided data, such as URL parameters, POST data payloads, or cookies, should always be considered untrusted and tainted. A remote server making requests to URLs based on tainted data could enable attackers to make arbitrary requests to the internal network or to the local file system.

The problem could be mitigated in any of the following ways:

  • Validate the user provided data based on a whitelist and reject input not matching.
  • Redesign the application to not send requests based on user provided data.

Noncompliant Code Example

public class SSRF : Controller
{
  public IActionResult Test(string url)
  {
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); // Noncompliant
    // ...
  }
}

Compliant Solution

public class SSRF : Controller
{
  private string[] whiteList = { "https://www.sonarsource.com" };

  public IActionResult Test(string url)
  {
    // Match the incoming URL against a whitelist
    if (!whiteList.Contains(url))
    {
      return BadRequest();
    }

    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
    // ...
  }
}

See

roslyn.sonaranalyzer.security.cs:S2083

User provided data, such as URL parameters, POST data payloads, or cookies, should always be considered untrusted and tainted. Constructing file system paths directly from tainted data could enable an attacker to inject specially crafted values, such as '../', that change the initial path and, when accessed, resolve to a path on the filesystem where the user should normally not have access.

A successful attack might give an attacker the ability to read, modify, or delete sensitive information from the file system and sometimes even execute arbitrary operating system commands. This is often referred to as a "path traversal" or "directory traversal" attack.

The mitigation strategy should be based on the whitelisting of allowed paths or characters.

Noncompliant Code Example

public class PathTraversal : Controller
{
  // GET /PathTraversal/Authenticate
  public IActionResult Authenticate(string user)
  {
    bool userExists = System.IO.File.Exists("/home/" + user); // Noncompliant

    // If the special value "../bin" is passed as user, authentication is bypassed
    // Indeed, if it passed as a user, the path becomes:
    // /bin
    // which exists on most Linux / BSD / Mac OS distributions

    return Content(userExists ? "success" : "fail");
  }
}

Compliant Solution

public class PathTraversal : Controller
{
  // GET /PathTraversal/Authenticate
  public IActionResult Authenticate(string user)
  {
    // Restrict the username to letters and digits only
    if (!Regex.IsMatch(user, "^[a-zA-Z0-9]+$"))
    {
        return BadRequest();
    }

    bool userExists = System.IO.File.Exists("/home/" + user); // Now safe
    return Content(userExists ? "success" : "fail");
  }
}

See

phpsecurity:S5146

User provided data, such as URL parameters, POST data payloads, or cookies, should always be considered untrusted and tainted. Applications performing HTTP redirects based on tainted data could enable an attacker to redirect users to a malicious site to, for example, steal login credentials.

This problem could be mitigated in any of the following ways:

  • Validate the user provided data based on a whitelist and reject input not matching.
  • Redesign the application to not perform redirects based on user provided data.

Noncompliant Code Example

$url = $this->request->getQuery("url");
return $this->redirect($url); // Noncompliant

Compliant Solution

$whitelist = array(
  "https://www.sonarsource.com/"
);
$url = $this->request->getQuery("url");
if (in_array($url, $whitelist)) {
  return $this->redirect($url);
} else {
  throw new ForbiddenException();
}

See

phpsecurity:S5145

User provided data, such as URL parameters, POST data payloads or cookies, should always be considered untrusted and tainted. Applications logging tainted data could enable an attacker to inject characters that would break the log file pattern. This could be used to block monitors and SIEM (Security Information and Event Management) systems from detecting other malicious events.

This problem could be mitigated by sanitizing the user provided data before logging it.

Noncompliant Code Example

$data = $_GET["data"];
error_log($data); // Noncompliant

Compliant Solution

$data = $_GET["data"];
$badchars = array("\n", "\r", "\t");
$safedata = str_replace($badchars, "", $data);
error_log($safedata);

See

phpsecurity:S5167

User provided data, such as URL parameters, POST data payloads, or cookies, should always be considered untrusted and tainted. Applications constructing HTTP response headers based on tainted data could allow attackers to inject characters that would be interpreted as a new line in some browsers. This could, for example, enable Cross-Site Scripting (XSS) attacks.

Most modern web application frameworks and servers mitigate this type of attack by default, but there might be rare cases where older versions are still vulnerable. As a best practice, applications that use user provided data to construct the response header should always validate the data first. Validation should be based on a whitelist.

Noncompliant Code Example

$value = $_GET["value"];
header("X-Header: $value"); // Noncompliant

Compliant Solution

$value = $_GET["value"];
if (ctype_alnum($value)) {
  header("X-Header: $value"); // Compliant
} else {
  // Error
}

See

phpsecurity:S5131

User provided data, such as URL parameters, POST data payloads, or cookies, should always be considered untrusted and tainted. Endpoints reflecting back tainted data could allow attackers to inject code that would eventually be executed in the user's browser. This could enable a wide range of serious attacks like accessing/modifying sensitive information or impersonating other users.

Typically, the solution is one of the following:

  • Validate user provided data based on a whitelist and reject input that's not whitelisted.
  • Sanitize user provided data from any characters that can be used for malicious purposes.
  • Encode user provided data being reflected as output. Adjust the encoding to the output context so that, for example, HTML encoding is used for HTML content, HTML attribute encoding is used for attribute values, and JavaScript encoding is used for server-generated JavaScript.

When sanitizing or encoding data, it is recommended to only use libraries specifically designed for security purposes. Also, make sure that the library you are using is being actively maintained and is kept up-to-date with the latest discovered vulnerabilities.

Noncompliant Code Example

$name = $_GET["name"];
echo "Welcome $name"; // Noncompliant

Compliant Solution

$name = $_GET["name"];
$safename = htmlspecialchars($name);
echo "Welcome $safename";

See

  • OWASP Cheat Sheet - XSS Prevention Cheat Sheet
  • OWASP Top 10 2017 Category A7 - Cross-Site Scripting (XSS)
  • MITRE, CWE-79 - Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')
  • MITRE, CWE-80 - Improper Neutralization of Script-Related HTML Tags in a Web Page (Basic XSS)
  • MITRE, CWE-81 - Improper Neutralization of Script in an Error Message Web Page
  • MITRE, CWE-82 - Improper Neutralization of Script in Attributes of IMG Tags in a Web Page
  • MITRE, CWE-83 - Improper Neutralization of Script in Attributes in a Web Page
  • MITRE, CWE-84 - Improper Neutralization of Encoded URI Schemes in a Web Page
  • MITRE, CWE-85 - Doubled Character XSS Manipulations
  • MITRE, CWE-86 - Improper Neutralization of Invalid Characters in Identifiers in Web Pages
  • MITRE, CWE-87 - Improper Neutralization of Alternate XSS Syntax
  • SANS Top 25 - Insecure Interaction Between Components
phpsecurity:S5144

User provided data, such as URL parameters, POST data payloads, or cookies, should always be considered untrusted and tainted. A remote server making requests to URLs based on tainted data could enable attackers to make arbitrary requests to the internal network or to the local file system.

The problem could be mitigated in any of the following ways:

  • Validate the user provided data based on a whitelist and reject input not matching.
  • Redesign the application to not send requests based on user provided data.

Noncompliant Code Example

$url = $_GET["url"];
$resp = file_get_contents($url); // Noncompliant
// ...

Compliant Solution

$whitelist = array(
  "https://www.sonarsource.com"
);
$url = $_GET["url"];
if (in_array($url, $whitelist)) {
  $resp = file_get_contents($url);
  // ...
}

See

cpp:S5184

The RAII idiom associates the lifetime of a resource with the lifetime of an object: The resource is acquired when the object is created, and released when it is destroyed.

If the object that controls the resource lifetime is a temporary, chances are that it will get destroyed while the resource should still be in use, leading to resource corruption. This rules detects temporaries that look like RAII objects.

Noncompliant Code Example

void f() {
  scoped_lock{myMutex}; // Non compliant. The mutex will be locked then immediately unlocked
  protectedCode(); // This code is not protected by the mutex
}

Compliant Solution

void f() {
  scoped_lock lock{myMutex}; // Compliant
  protectedCode();
  // The mutex is correctly released at this point
}

See

ruby:S2068

Because it is easy to extract strings from a compiled application, credentials should never be hard-coded. Do so, and they're almost guaranteed to end up in the hands of an attacker. This is particularly true for applications that are distributed.

Credentials should be stored outside of the code in a strongly-protected encrypted configuration file or database.

This rule flags instances of hard-coded credentials used in database and LDAP connections. It looks for hard-coded credentials in connection strings, and for variable names that match any of the patterns from the provided list.

It's recommended to customize the configuration of this rule with additional credential words such as "oauthToken", "secret", ...

See

scala:S2068

Because it is easy to extract strings from a compiled application, credentials should never be hard-coded. Do so, and they're almost guaranteed to end up in the hands of an attacker. This is particularly true for applications that are distributed.

Credentials should be stored outside of the code in a strongly-protected encrypted configuration file or database.

This rule flags instances of hard-coded credentials used in database and LDAP connections. It looks for hard-coded credentials in connection strings, and for variable names that match any of the patterns from the provided list.

It's recommended to customize the configuration of this rule with additional credential words such as "oauthToken", "secret", ...

See

cobol:S3394

The ACCEPT keyword does no editing or error checking of the data it stores, therefore its use can be dangerous. For this reason, ACCEPT should be avoided.

Noncompliant Code Example

 01 USER-INPUT PIC X(4).

  GET-USER-INPUT.
       MOVE 'N' TO WS-NUMERIC.
       PERFORM UNTIL WS-NUMERIC = 'Y'
           DISPLAY 'ENTER YOUR 4 DIGIT RECORD NUMBER: ' NO ADVANCING
           ACCEPT USER-RECORD *> Noncompliant

Exceptions

This rule ignores uses of ACCEPT FROM with date/time-related inputs.

See

  • OWASP Top 10 2017 Category A1 - Injection
cobol:SQL.SelectWithNoWhereClauseCheck

Although the WHERE condition is optional in a SELECT statement, for performance and security reasons, a WHERE clause should always be specified to prevent reading the whole table.

Noncompliant Code Example

SELECT * FROM db_persons INTO us_persons

Compliant Solution

SELECT * FROM db_persons INTO us_persons WHERE country IS 'US'

Exceptions

Not having a WHERE clause is acceptable in read-only cursors as results are generally sorted and it is possible to stop processing in the middle.

cobol:SQL.DynamicSqlCheck

It is a bad practice to use Dynamic SQL. It differs from static embedded SQL in that part or all of the actual SQL commands may be stored in a host variable that is built on the fly during execution of the program. In the extreme case, the SQL commands are generated in their entirety by the application program at run time. While dynamic SQL is more flexible than static embedded SQL, it does require additional overhead and is much more difficult to understand and to maintain.

Moreover, dynamic SQL may expose the application to SQL injection vulnerabilities.

This rule raises an issue when PREPARE or EXECUTE IMMEDIATE is used.

Noncompliant Code Example

EXEC SQL PREPARE SEL INTO :SQLDA FROM :STMTBUF END-EXEC.

See

  • MITRE, CWE-89 - SQL Injection
  • OWASP Top 10 2017 Category A1 - Injection
  • SANS Top 25 - Insecure Interaction Between Components
cobol:S1685

Debug statements (ones with 'D' or 'd' in the indicator area) should not be executed in production, but the WITH DEBUGGING MODE clause activates all debug lines, which could expose sensitive information to attackers. Therefore the WITH DEBUGGING MODE clause should be removed.

Noncompliant Code Example

SOURCE-COMPUTER. IBM-370 WITH DEBUGGING MODE.

Compliant Solution

SOURCE-COMPUTER. IBM-370.

See

  • MITRE, CWE-489 - Leftover Debug Code
  • OWASP Top 10 2017 Category A3 - Sensitive Data Exposure
cobol:S1686

Defining a subprogram to be called at runtime is possible but ill-advised. This extremely powerful feature can quite easily be misused, and even when used correctly, it highly increases the overall complexity of the program, and makes it impossible before runtime to know exactly what will be executed. Therefore defining the subprogram to be called at runtime is a feature that should be avoided.

Noncompliant Code Example

MOVE SOMETHING TO MY_SUBPROG.
...
CALL MY_SUBPROG.

Compliant Solution

01 MY_SUBPROG PIC X(10) VALUE "SUB123".
....
CALL MY_SUBPROG.
cobol:COBOL.DisplayStatementUsageCheck

The DISPLAY statement outputs data to standard out or some other destination and could reveal sensitive information. Therefore, it should be avoided.

Noncompliant Code Example

DISPLAY "hello world"  *> Noncompliant

See

  • MITRE, CWE-489 - Leftover Debug Code
  • OWASP Top 10 2017 Category A3 - Sensitive Data Exposure
plsql:MaskedExceptionCheck

When exceptions occur, it is usually a bad idea to simply ignore them. Instead, it is better to handle them properly, or at least to log them.

Noncompliant Code Example

SET SERVEROUTPUT ON

DECLARE
  d VARCHAR2(1);
BEGIN
  SELECT dummy INTO d FROM DUAL WHERE dummy = 'Y'; -- Will raise NO_DATA_FOUND
  DBMS_OUTPUT.PUT_LINE('d = ' || d);
EXCEPTION
  WHEN NO_DATA_FOUND THEN -- Noncompliant, did we really want to mask this exception?
    NULL;
END;
/

Compliant Solution

SET SERVEROUTPUT ON

DECLARE
  d VARCHAR2(1);
BEGIN
  SELECT dummy INTO d FROM DUAL WHERE dummy = 'Y'; -- Will raise NO_DATA_FOUND
  DBMS_OUTPUT.PUT_LINE('d = ' || d);
EXCEPTION
  WHEN NO_DATA_FOUND THEN
    DBMS_OUTPUT.PUT_LINE('Error: No data found');
END;
/

See

  • MITRE, CWE-391 - Unchecked Error Condition
  • OWASP Top 10 2017 Category A10 - Insufficient Logging & Monitoring
typescript:S2068

Because it is easy to extract strings from a compiled application, credentials should never be hard-coded. Do so, and they're almost guaranteed to end up in the hands of an attacker. This is particularly true for applications that are distributed.

Credentials should be stored outside of the code in a strongly-protected encrypted configuration file or database.

This rule flags instances of hard-coded credentials used in database and LDAP connections. It looks for hard-coded credentials in connection strings, and for variable names that match any of the patterns from the provided list.

It's recommended to customize the configuration of this rule with additional credential words such as "oauthToken", "secret", ...

Noncompliant Code Example

const password = "asdasd";

let my_pwd;
my_pwd = "qwerewt";

login({ passwd: "zxvxcv"});

const url = "https://example.com?password=hl2OAIXXZ60";

Compliant Solution

const password = loadCredentials();

See

typescript:S1525

The debugger statement can be placed anywhere in procedures to suspend execution. Using the debugger statement is similar to setting a breakpoint in the code. By definition such statement must absolutely be removed from the source code to prevent any unexpected behavior or added vulnerability to attacks in production.

Noncompliant Code Example

for (i = 1; i<5; i++) {
  // Print i to the Output window.
  Debug.write("loop index is " + i);
  // Wait for user to resume.
  debugger;
}

Compliant Solution

for (i = 1; i<5; i++) {
  // Print i to the Output window.
  Debug.write("loop index is " + i);
}

See

  • MITRE, CWE-489 - Leftover Debug Code
  • OWASP Top 10 2017 Category A3 - Sensitive Data Exposure
swift:S2068

Because it is easy to extract strings from a compiled application, credentials should never be hard-coded. Do so, and they're almost guaranteed to end up in the hands of an attacker. This is particularly true for applications that are distributed.

Credentials should be stored outside of the code in a strongly-protected encrypted configuration file or database.

This rule flags instances of hard-coded credentials used in database and LDAP connections. It looks for hard-coded credentials in connection strings, and for variable names that match any of the patterns from the provided list.

It's recommended to customize the configuration of this rule with additional credential words such as "oauthToken", "secret", ...

Noncompliant Code Example

var post:NSString = "username=Steve&password=123456"  // Noncompliant
var postData:NSData = post.dataUsingEncoding(NSASCIIStringEncoding)!
//...
var request:NSMutableURLRequest = NSMutableURLRequest(URL: url)
request.HTTPBody = postData
//...
var urlData: NSData? = NSURLConnection.sendSynchronousRequest(request, returningResponse:&response, error:&reponseError)

Compliant Solution

var post:NSString = "username=\(getEncryptedUser())&password=\(getEncryptedPass())"
var postData:NSData = post.dataUsingEncoding(NSASCIIStringEncoding)!
//...
var request:NSMutableURLRequest = NSMutableURLRequest(URL: url)
request.HTTPBody = postData
//...
var urlData: NSData? = NSURLConnection.sendSynchronousRequest(request, returningResponse:&response, error:&reponseError)

See

swift:S2070

The MD5 algorithm and its successor, SHA-1, are no longer considered secure, because it is too easy to create hash collisions with them. That is, it takes too little computational effort to come up with a different input that produces the same MD5 or SHA-1 hash, and using the new, same-hash value gives an attacker the same access as if he had the originally-hashed value. This applies as well to the other Message-Digest algorithms: MD2, MD4, MD6, HAVAL-128, HMAC-MD5, DSA (which uses SHA-1), RIPEMD, RIPEMD-128, RIPEMD-160, HMACRIPEMD160.

Consider using safer alternatives, such as SHA-256, or SHA-3.

Noncompliant Code Example

  var hash = MD5() // Noncompliant
  "123".sha1() // Noncompliant

Compliant Solution

  "123".sha512()

See

  • MITRE, CWE-328 - Reversible One-Way Hash
  • MITRE, CWE-327 - Use of a Broken or Risky Cryptographic Algorithm
  • OWASP Top 10 2017 Category A6 - Security Misconfiguration
  • SANS Top 25 - Porous Defenses
  • SHAttered - The first concrete collision attack against SHA-1.
objc:S1079

The %s placeholder is used to read a word into a string.

By default, there is no restriction on the length of that word, and the developer is required to pass a sufficiently large buffer for storing it.

No matter how large the buffer is, there will always be a longer word.

Therefore, programs relying on %s are vulnerable to buffer overflows.

A field width specifier can be used together with the %s placeholder to limit the number of bytes which will by written to the buffer.

Note that an additional byte is required to store the null terminator.

Noncompliant Code Example

char buffer[10];
scanf("%s", buffer);      // Noncompliant - will overflow when a word longer than 9 characters is entered

Compliant Solution

char buffer[10];
scanf("%9s", buffer);     // Compliant - will not overflow

See

c:S1079

The %s placeholder is used to read a word into a string.

By default, there is no restriction on the length of that word, and the developer is required to pass a sufficiently large buffer for storing it.

No matter how large the buffer is, there will always be a longer word.

Therefore, programs relying on %s are vulnerable to buffer overflows.

A field width specifier can be used together with the %s placeholder to limit the number of bytes which will by written to the buffer.

Note that an additional byte is required to store the null terminator.

Noncompliant Code Example

char buffer[10];
scanf("%s", buffer);      // Noncompliant - will overflow when a word longer than 9 characters is entered

Compliant Solution

char buffer[10];
scanf("%9s", buffer);     // Compliant - will not overflow

See

cpp:S1079

The %s placeholder is used to read a word into a string.

By default, there is no restriction on the length of that word, and the developer is required to pass a sufficiently large buffer for storing it.

No matter how large the buffer is, there will always be a longer word.

Therefore, programs relying on %s are vulnerable to buffer overflows.

A field width specifier can be used together with the %s placeholder to limit the number of bytes which will by written to the buffer.

Note that an additional byte is required to store the null terminator.

Noncompliant Code Example

char buffer[10];
scanf("%s", buffer);      // Noncompliant - will overflow when a word longer than 9 characters is entered

Compliant Solution

char buffer[10];
scanf("%9s", buffer);     // Compliant - will not overflow

See

apex:S2068

Because it is easy to extract strings from a compiled application, credentials should never be hard-coded. Do so, and they're almost guaranteed to end up in the hands of an attacker. This is particularly true for applications that are distributed.

Credentials should be stored outside of the code in a strongly-protected encrypted configuration file or database.

Noncompliant Code Example

String password = "xxxx"; // Noncompliant

Compliant Solution

String password = retrievePassword();

See

plsql:S2070

The MD5 algorithm and its successor, SHA-1, are no longer considered secure, because it is too easy to create hash collisions with them. That is, it takes too little computational effort to come up with a different input that produces the same MD5 or SHA-1 hash, and using the new, same-hash value gives an attacker the same access as if he had the originally-hashed value. This applies as well to the other Message-Digest algorithms: MD2, MD4, MD6, HAVAL-128, HMAC-MD5, DSA (which uses SHA-1), RIPEMD, RIPEMD-128, RIPEMD-160, HMACRIPEMD160.

Consider using safer alternatives, such as SHA-256, or SHA-3.

Noncompliant Code Example

DBMS_CRYPTO.Hash(str, HASH_MD4);

DBMS_CRYPTO.Hash(str, HASH_MD5);

DBMS_CRYPTO.Hash(str, HASH_SH1);

See

  • MITRE, CWE-328 - Reversible One-Way Hash
  • MITRE, CWE-327 - Use of a Broken or Risky Cryptographic Algorithm
  • OWASP Top 10 2017 Category A6 - Security Misconfiguration
  • SANS Top 25 - Porous Defenses
  • SHAttered - The first concrete collision attack against SHA-1.
plsql:SysOwnedFunctions

Some Oracle packages contain powerful SYS-owned functions that can be used to perform malicious operations. For instance, DBMS_SYS_SQL.PARSE_AS_USER can be used to execute a statement as another user.

Most programs do not need those functions and this rule helps identify them in order to prevent security risks.

Noncompliant Code Example

DECLARE
  c INTEGER;
  sqltext VARCHAR2(100) := 'ALTER USER system IDENTIFIED BY hacker'; -- Might be injected by the user
BEGIN
  c := SYS.DBMS_SYS_SQL.OPEN_CURSOR();                               -- Noncompliant

   -- Will change 'system' user's password to 'hacker'
  SYS.DBMS_SYS_SQL.PARSE_AS_USER(c, sqltext, DBMS_SQL.NATIVE, UID);  -- Non-Compliant

  SYS.DBMS_SYS_SQL.CLOSE_CURSOR(c);                                  -- Noncompliant
END;
/

See

plsql:S2278

According to the US National Institute of Standards and Technology (NIST), the Data Encryption Standard (DES) is no longer considered secure:

Adopted in 1977 for federal agencies to use in protecting sensitive, unclassified information, the DES is being withdrawn because it no longer provides the security that is needed to protect federal government information.

Federal agencies are encouraged to use the Advanced Encryption Standard, a faster and stronger algorithm approved as FIPS 197 in 2001.

For similar reasons, RC2 should also be avoided.

Noncompliant Code Example

PLS_INTEGER := DBMS_CRYPTO.ENCRYPT_DES
                           + DBMS_CRYPTO.CHAIN_CBC
                           + DBMS_CRYPTO.PAD_PKCS5;

Compliant Solution

PLS_INTEGER := DBMS_CRYPTO.ENCRYPT_AES256
                           + DBMS_CRYPTO.CHAIN_CBC
                           + DBMS_CRYPTO.PAD_PKCS5;

See

kotlin:S2068

Because it is easy to extract strings from a compiled application, credentials should never be hard-coded. Do so, and they're almost guaranteed to end up in the hands of an attacker. This is particularly true for applications that are distributed.

Credentials should be stored outside of the code in a strongly-protected encrypted configuration file or database.

Noncompliant Code Example

val params = "password=xxxx" // Noncompliant
val writer = OutputStreamWriter(getOutputStream())
writer.write(params)
writer.flush()
...
val password = "xxxx" // Noncompliant
...

Compliant Solution

val params = "password=${retrievePassword()}"
val writer = OutputStreamWriter(getOutputStream())
writer.write(params)
writer.flush()
...
val password = retrievePassword()
...

See

abap:S1492

Although the WHERE condition is optional in a SELECT statement, for performance and security reasons, a WHERE clause should always be specified to prevent reading the whole table.

Noncompliant Code Example

SELECT * FROM db_persons INTO us_persons.

Compliant Solution

SELECT * FROM db_persons INTO us_persons WHERE country IS 'US'.

Exceptions

SELECT SINGLE and UP TO 1 ROWS result in only one record being read, so such SELECTs are ignored by this rule.

SELECT SINGLE * FROM db_persons INTO us_persons.

SELECT * FROM db_persons UP TO 1 ROWS INTO us_persons.
abap:S1674

Leaving a CATCH block empty means that the exception in question is neither handled nor passed forward to callers for handling at a higher level. Suppressing errors rather than handling them could lead to unpredictable system behavior and should be avoided.

Noncompliant Code Example

  try.
    if ABS( NUMBER ) > 100.
      write / 'Number is large'.
    endif.
    catch CX_SY_ARITHMETIC_ERROR into OREF.
  endtry.

Compliant Solution

  try.
    if ABS( NUMBER ) > 100.
      write / 'Number is large'.
    endif.
  catch CX_SY_ARITHMETIC_ERROR into OREF.
    write / OREF->GET_TEXT( ).
  endtry.

Exceptions

When a block contains a comment, it is not considered to be empty.

See

  • MITRE, CWE-391 - Unchecked Error Condition
  • OWASP Top 10 2017 Category A10 - Insufficient Logging & Monitoring
csharpsquid:S1104

Public fields in public classes do not respect the encapsulation principle and has three main disadvantages:

  • Additional behavior such as validation cannot be added.
  • The internal representation is exposed, and cannot be changed afterwards.
  • Member values are subject to change from anywhere in the code and may not meet the programmer's assumptions.

By using private fields and public properties (set and get), unauthorized modifications are prevented. Properties also benefit from additional protection (security) features such as Link Demands.

Note that due to optimizations on simple properties, public fields provide only very little performance gain.

Noncompliant Code Example

public class Foo
{
    public int instanceData = 32; // Noncompliant
}

Compliant Solution

public class Foo
{
    private int instanceData = 32;

    public int InstanceData
    {
        get { return instanceData; }
	set { instanceData = value ; }
    }
}

Exceptions

Fields marked as readonly or const are ignored by this rule.

Fields inside classes or structs annotated with the StructLayoutAttribute are ignored by this rule.

See

flex:S1465

A LocalConnection object is used to invoke a method in another LocalConnection object, either within a single SWF file or between multiple SWF files. This kind of local connection should be authorized only when the origin (domain) of the other Flex applications is perfectly defined.

Noncompliant Code Example

localConnection.allowDomain("*");

Compliant Solution

localConnection.allowDomain("www.myDomain.com");
flex:S1466

The Security.exactSettings value should remain set at the default value of true. Setting this value to false could make the SWF vulnerable to cross-domain attacks.

Noncompliant Code Example

Security.exactSettings = false;
flex:S1468

Calling Security.allowDomain("*") lets any domain cross-script into the domain of this SWF and exercise its functionality.

Noncompliant Code Example

Security.allowDomain("*");

Compliant Solution

Security.allowDomain("www.myDomain.com");
go:S1313

Hardcoding an IP address into source code is a bad idea for several reasons:

  • a recompile is required if the address changes
  • it forces the same address to be used in every environment (dev, sys, qa, prod)
  • it places the responsibility of setting the value to use in production on the shoulders of the developer
  • it allows attackers to decompile the code and thereby discover a potentially sensitive address

Noncompliant Code Example

var (
  ip   = "127.0.0.1"
  port = 3333
)

SocketClient(ip, port)

Compliant Solution

config, err := ReadConfig("properties.ini")

ip := config["ip"]
port := config["ip"]

SocketClient(ip, port)

See

go:S2068

Because it is easy to extract strings from a compiled application, credentials should never be hard-coded. Do so, and they're almost guaranteed to end up in the hands of an attacker. This is particularly true for applications that are distributed.

Credentials should be stored outside of the code in a strongly-protected encrypted configuration file or database.

This rule flags instances of hard-coded credentials used in database and LDAP connections. It looks for hard-coded credentials in connection strings, and for variable names that match any of the patterns from the provided list.

Noncompliant Code Example

func connect()  {
  user := "root"
  myPassword := "supersecret" // Noncompliant

  url := "login=" + user + "&passwd=" + myPassword
}

Compliant Solution

func connect()  {
  user := getEncryptedUser()
  myPassword := getEncryptedPass() // Compliant

  url := "login=" + user + "&passwd=" + myPassword
}

See

squid:ClassVariableVisibilityCheck

Public class variable fields do not respect the encapsulation principle and has three main disadvantages:

  • Additional behavior such as validation cannot be added.
  • The internal representation is exposed, and cannot be changed afterwards.
  • Member values are subject to change from anywhere in the code and may not meet the programmer's assumptions.

By using private attributes and accessor methods (set and get), unauthorized modifications are prevented.

Noncompliant Code Example

public class MyClass {

  public static final int SOME_CONSTANT = 0;     // Compliant - constants are not checked

  public String firstName;                       // Noncompliant

}

Compliant Solution

public class MyClass {

  public static final int SOME_CONSTANT = 0;     // Compliant - constants are not checked

  private String firstName;                      // Compliant

  public String getFirstName() {
    return firstName;
  }

  public void setFirstName(String firstName) {
    this.firstName = firstName;
  }

}

Exceptions

Because they are not modifiable, this rule ignores public final fields.

See

squid:S1444

There is no good reason to declare a field "public" and "static" without also declaring it "final". Most of the time this is a kludge to share a state among several objects. But with this approach, any object can do whatever it wants with the shared state, such as setting it to null.

Noncompliant Code Example

public class Greeter {
  public static Foo foo = new Foo();
  ...
}

Compliant Solution

public class Greeter {
  public static final Foo FOO = new Foo();
  ...
}

See

squid:S2384

Mutable objects are those whose state can be changed. For instance, an array is mutable, but a String is not. Mutable class members should never be returned to a caller or accepted and stored directly. Doing so leaves you vulnerable to unexpected changes in your class state.

Instead use an unmodifiable Collection (via Collections.unmodifiableCollection, Collections.unmodifiableList, ...) or make a copy of the mutable object, and store or return the copy instead.

This rule checks that arrays, collections and Dates are not stored or returned directly.

Noncompliant Code Example

class A {
  private String [] strings;

  public A () {
    strings = new String[]{"first", "second"};
  }

  public String [] getStrings() {
    return strings; // Noncompliant
  }

  public void setStrings(String [] strings) {
    this.strings = strings;  // Noncompliant
  }
}

public class B {

  private A a = new A();  // At this point a.strings = {"first", "second"};

  public void wreakHavoc() {
    a.getStrings()[0] = "yellow";  // a.strings = {"yellow", "second"};
  }
}

Compliant Solution

class A {
  private String [] strings;

  public A () {
    strings = new String[]{"first", "second"};
  }

  public String [] getStrings() {
    return strings.clone();
  }

  public void setStrings(String [] strings) {
    this.strings = strings.clone();
  }
}

public class B {

  private A a = new A();  // At this point a.strings = {"first", "second"};

  public void wreakHavoc() {
    a.getStrings()[0] = "yellow";  // a.strings = {"first", "second"};
  }
}

See

  • MITRE, CWE-374 - Passing Mutable Objects to an Untrusted Method
  • MITRE, CWE-375 - Returning a Mutable Object to an Untrusted Caller
  • CERT, OBJ05-J. - Do not return references to private mutable class members
  • CERT, OBJ06-J. - Defensively copy mutable inputs and mutable internal components
  • CERT, OBJ13-J. - Ensure that references to mutable objects are not exposed
squid:S2386

There is no good reason to have a mutable object as the public (by default), static member of an interface. Such variables should be moved into classes and their visibility lowered.

Similarly, mutable static members of classes and enumerations which are accessed directly, rather than through getters and setters, should be protected to the degree possible. That can be done by reducing visibility or making the field final if appropriate.

Note that making a mutable field, such as an array, final will keep the variable from being reassigned, but doing so has no effect on the mutability of the internal state of the array (i.e. it doesn't accomplish the goal).

This rule raises issues for public static array, Collection, Date, and awt.Point members.

Noncompliant Code Example

public interface MyInterface {
  public static String [] strings; // Noncompliant
}

public class A {
  public static String [] strings1 = {"first","second"};  // Noncompliant
  public static String [] strings2 = {"first","second"};  // Noncompliant
  public static List<String> strings3 = new ArrayList<>();  // Noncompliant
  // ...
}

See

squid:S3066

enums are generally thought of as constant, but an enum with a public field or public setter is not only non-constant, but also vulnerable to malicious code. Ideally fields in an enum are private and set in the constructor, but if that's not possible, their visibility should be reduced as much as possible.

Noncompliant Code Example

public enum Continent {

  NORTH_AMERICA (23, 24709000),
  // ...
  EUROPE (50, 39310000);

  public int countryCount;  // Noncompliant
  private int landMass;

  Continent(int countryCount, int landMass) {
    // ...
  }

  public void setLandMass(int landMass) {  // Noncompliant
    this.landMass = landMass;
  }

Compliant Solution

public enum Continent {

  NORTH_AMERICA (23, 24709000),
  // ...
  EUROPE (50, 39310000);

  private int countryCount;
  private int landMass;

  Continent(int countryCount, int landMass) {
    // ...
  }
squid:S3374

According to the Common Weakness Enumeration,

If two validation forms have the same name, the Struts Validator arbitrarily chooses one of the forms to use for input validation and discards the other. This decision might not correspond to the programmer's expectations...

In such a case, it is likely that the two forms should be combined. At the very least, one should be removed.

Noncompliant Code Example

<form-validation>
  <formset>
    <form name="BookForm"> ... </form>
    <form name="BookForm"> ... </form>  <!-- Noncompliant -->
  </formset>
</form-validation>

Compliant Solution

<form-validation>
  <formset>
    <form name="BookForm"> ... </form>
  </formset>
</form-validation>

See

swift:S2278

According to the US National Institute of Standards and Technology (NIST), the Data Encryption Standard (DES) is no longer considered secure:

Adopted in 1977 for federal agencies to use in protecting sensitive, unclassified information, the DES is being withdrawn because it no longer provides the security that is needed to protect federal government information.

Federal agencies are encouraged to use the Advanced Encryption Standard, a faster and stronger algorithm approved as FIPS 197 in 2001.

For similar reasons, RC2 should also be avoided.

Noncompliant Code Example

let cryptor = try Cryptor(operation: .encrypt, algorithm: .des, options: [.ecbMode], key: key, iv: []) // Noncompliant

let crypt = CkoCrypt2()
crypt.CryptAlgorithm = "3des" // Noncompliant

Compliant Solution

let cryptor = try Cryptor(operation: .encrypt, algorithm: .aes, options: [.ecbMode], key: key, iv: [])

let crypt = CkoCrypt2()
crypt.CryptAlgorithm = "blowfish"

See

swift:S2950

The access level defaults to internal if left unspecified. Since that doesn't make sense for most top-level declarations, access levels should always be specified explicitly, even when internal is what's intended.

This rule raises an issue when the access level is not specified on any top-level declaration.

Noncompliant Code Example

class Foo {  // Noncompliant
  // ...
}

Compliant Solution

public class Foo {
  // ...
}
typescript:S2228

Debug statements are always useful during development. But include them in production code - particularly in code that runs client-side - and you run the risk of inadvertently exposing sensitive information, slowing down the browser, or even erroring-out the site for some users.

Noncompliant Code Example

console.log(password_entered); // Noncompliant

See

  • OWASP Top 10 2017 Category A3 - Sensitive Data Exposure
Web:AvoidHtmlCommentCheck

Using HTML-style comments in a page that will be generated or interpolated server-side before being served to the user increases the risk of exposing data that should be kept private. For instance, a developer comment or line of debugging information that's left in a page could easily (and has) inadvertently expose:

  • Version numbers and host names
  • Full, server-side path names
  • Sensitive user data

Because every other language has its own native comment format, there is no justification for using HTML-style comments in anything other than a pure HTML or XML file.

Noncompliant Code Example

  <%
      out.write("<!-- ${username} -->");  // Noncompliant
  %>
      <!-- <% out.write(userId) %> -->  // Noncompliant
      <!-- #{userPhone} -->  // Noncompliant
      <!-- ${userAddress} --> // Noncompliant

      <!-- Replace 'world' with name --> // Noncompliant
      <h2>Hello world!</h2>

Compliant Solution

      <%-- Replace 'world' with name --%>  // Compliant
      <h2>Hello world!</h2>

See

  • MITRE, CWE-615 - Information Exposure Through Comments
  • OWASP Top 10 2017 Category A3 - Sensitive Data Exposure