Skip to content

Semgrep rules

Boost is maintaining its own set of Semgrep rules. Below is the list of available rules per languages.

c, cpp

Name Identifiers Description
Use of deprecated function (gets) c_buffer_rule-gets--getts, CWE-120 Severity: High

The gets() function reads a line from stdin into the provided buffer until either a terminating newline or EOF. This terminating newline or EOF is replaced with a null byte '\0'. No check for buffer overruns are performed so it is recommended to use fgets() instead. Do note that some platforms will continue reading data after a '\0' is encountered.

Usage of fgets() is not recommended for reading binary based files or inputs, instead the read or fread functions should be used.

For more information please see: fgets

OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Insufficient protection against buffer overflow (getwd) c_buffer_rule-getwd, CWE-120 Severity: High

getwd does not contain a parameter to limit how many characters can be copied into the destination buffer. For portability and security reasons getwd has been deprecated in favor of getcwd.

For more information please see: getcwd

OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
scanf() functions may allow format string based overflows c_buffer_rule-scanf-vscanf, CWE-120 Severity: High

Format specifiers can take optional field widths, which should be used to limit how many characters are copied into the target buffer.

For more information please see: scanf

Example:

  char buf[11] = {0};
scanf("%10s", &buf); // buf = AAAAAAAAAA\0

If developing for C Runtime Library (CRT), more secure versions of these functions should be used, see: scanf-s-scanf-s-l-wscanf-s-wscanf-s-l

OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Potential format string vulnerability c_format_rule-fprintf-vfprintf, CWE-134 Severity: High

Format string vulnerabilities allow an attacker to read or in some cases, potentially write data to and from locations in the processes' memory. To prevent against format string attacks, do not allow users or un-validated input to provide the format specification. Consider using a constant for the format specification, or only allow specific characters to be provided to the format argument for the fprintf family of functions.

For more information please see: fprintf

For more information on format string attacks please see OWASP's attack guide: Format_string_attack

OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Potential format string vulnerability c_format_rule-printf-vprintf, CWE-134 Severity: High

Format string vulnerabilities allow an attacker to read or in some cases, potentially write data to and from locations in the processes' memory. To prevent against format string attacks, do not allow users or un-validated input to provide the format specification. Consider using a constant for the format specification, or only allow specific characters to be provided to the format argument for the printf family of functions.

For more information please see: fprintf

For more information on format string attacks please see OWASP's attack guide: Format_string_attack

OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Potential format string vulnerability c_format_rule-snprintf-vsnprintf, CWE-134 Severity: High

Format string vulnerabilities allow an attacker to read or in some cases, potentially write data to and from locations in the processes' memory. To prevent against format string attacks, do not allow users or un-validated input to provide the format specification. Consider using a constant for the format specification, or strip all format specifiers from the input prior to calling the snprintf family of functions.

Note that some variations of this function do not always null terminate the strings.

For more information on using snprintf please see: snprintf

For more information on format string attacks please see OWASP's attack guide: Format_string_attack

OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Potential format string vulnerability in syslog call c_format_rule-syslog, CWE-134 Severity: High

Format string vulnerabilities allow an attacker to read or in some cases, potentially write data to and from locations in the processes' memory. To prevent against format string attacks, do not allow users or un-validated input to provide the format specification. Consider using a constant for the format specification, or strip all format specifiers from the input prior to calling the syslog function.

For more information please see: 67.html

OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Possible executable path hijacking (CreateProcess) c_shell_rule-CreateProcess, CWE-78 Severity: High

Due to how CreateProcess parses spaces, an attacker may be able to exploit this function by creating a binary with the same name that is loaded first, depending on the search path order.

Ensure that quotation marks around the executable path are used, such as:

CreateProcessA(NULL, "\"C:\Program Files\MyApp.exe\"", ...)

For more information, please see MSDNs documentation at: nf-processthreadsapi-createprocessa

OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Possible executable path hijacking (CreateProcessAsUser / CreateProcessWithLogon) c_shell_rule-CreateProcessAsUser-CreateProcessWithLogon, CWE-78 Severity: High

Due to how CreateProcess parses spaces, an attacker may be able to exploit this function by creating a binary with the same name that is loaded first, depending on the search path order.

Ensure that quotation marks around the executable path are used, such as:

CreateProcessAsUser(hToken, NULL, "\"C:\Program Files\MyApp.exe\"", ...)

For more information, please see MSDNs documentation at: nf-processthreadsapi-createprocessasusera

OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Potential for OS command injection c_shell_rule-execl-execlp, CWE-78 Severity: High

It is generally not recommended to call out to the operating system to execute commands. When the application is executing file system based commands, user input should never be used in constructing commands or command arguments. If possible, determine if a library can be used instead to provide the same functionality. Otherwise, consider hard coding both the command and arguments to be used, or at the very least restricting which arguments can be passed to the command execution function.

Please see the compliant solutions in the following page: viewpage.action

OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Potential for OS command injection c_shell_rule-system, CWE-78 Severity: High

It is generally not recommended to call out to the operating system to execute commands. When the application is executing file system based commands, user input should never be used in constructing commands or command arguments. If possible, determine if a library can be used instead to provide the same functionality. Otherwise, consider hard coding both the command and arguments to be used, or at the very least restricting which arguments can be passed to the command execution function.

For more information please see: viewpage.action

OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Insecure encryption algorithm (DES) c_crypto_rule-EVP-des-ecb-EVP-des-cbc, CWE-327 Severity: Medium

The DES algorithm has not been recommended for over 15 years and was withdrawn from NIST (FIPS
46-3) in 2005.

Consider using libsodium's crypto_secretbox_easy authenticated encryption functions instead.

For more information please see: secretbox.

If you must be FIPS compliant, consider using OpenSSLs AES or 3DES ciphers.

OWASP:
  • A02:2021-Cryptographic Failures
  • A3:2017-Sensitive Data Exposure
Insecure stream cipher (RC4) c_crypto_rule-EVP-rc4-40-EVP-rc2-40-cbc, CWE-327 Severity: Medium

The RC4 algorithm is vulnerable to many attacks and should no longer be used for encrypting data streams.

Consider using libsodium's crypto_secretstream_xchacha20poly1305 stream cipher encryption functions instead. For more information please see: secretstream

If you must be FIPS compliant, consider using OpenSSLs AES or 3DES ciphers.

OWASP:
  • A02:2021-Cryptographic Failures
  • A3:2017-Sensitive Data Exposure
Insecure hashing algorithm c_crypto_rule-crypt-crypt-r, CWE-327 Severity: Medium

The crypt functions are not recommended due to the significantly small key space. Modern hardware can crack crypt produced passwords relatively quickly.

Consider using the Argon2id password hashing algorithm provided by libsodium. For more information please see: password_hashing.

OWASP:
  • A02:2021-Cryptographic Failures
  • A3:2017-Sensitive Data Exposure
Use of deprecated function (mktemp) c_tmpfile_rule-mktemp, CWE-377 Severity: Medium

The mktemp function should no longer be used due to multiple flaws. Some implementations created random files by using known information like the process ID and a single letter. This allows for possible race conditions where an attacker could guess or manipulate these files prior to them being used.

Consider using the mkstemp function instead, but be aware it also contains possible risks. Ensure the process has called the umask function with restricted permissions prior to calling mkstemp and validate the permissions prior to using the file descriptor.

For more information on temporary files please see: viewpage.action

OWASP:
  • A01:2021-Broken Access Control
  • A5:2017-Broken Access Control
Potential time of check time of use vulnerability (tmpnam / tempnam) c_tmpfile_rule-tmpnam-tempnam, CWE-377 Severity: Medium

There exists a possible race condition in between the time that tempnam or tmpnam
returns a pathname, and the time that the program opens it, another program might create that pathname using open, or create it as a symbolic link.

Consider using the mkstemp function instead, but be aware it also contains possible risks. Ensure the process has called the umask function with restricted permissions prior to calling mkstemp and validate the permissions prior to using the file descriptor.

For more information on temporary files please see: viewpage.action

OWASP:
  • A01:2021-Broken Access Control
  • A5:2017-Broken Access Control

csharp

Name Identifiers Description
Deserialization of potentially untrusted data csharp_deserialization_rule-InsecureDeserialization, CWE-502 Severity: High

Deserialization attacks exploit the process of reading serialized data and turning it back into an object. By constructing malicious objects and serializing them, an adversary may attempt to:

  • Inject code that is executed upon object construction, which occurs during the deserialization process.
  • Exploit mass assignment by including fields that are not normally a part of the serialized data but are
    read in during deserialization.

Microsoft recommends no longer using the following serialization formats:

  • BinaryFormatter
  • SoapFormatter
  • NetDataContractSerializer
  • LosFormatter
  • ObjectStateFormatter

Consider safer alternatives such as serializing data in the JSON format. Ensure any format chosen allows the application to specify exactly which object types are allowed to be deserialized. Additionally, when deserializing, never deserialize to base object types like Object and only cast to the exact object type that is expected.

To protect against mass assignment, only allow deserialization of the specific fields that are required. If this is not easily done, consider creating an intermediary type that can be serialized with only the necessary fields exposed.

For more information see Microsoft's deserialization security guide: binaryformatter-security-guide

For more details on deserialization attacks in general, see OWASP's guide: Deserialization_Cheat_Sheet.html

It should be noted that tools exist to automatically create exploit code for these vulnerabilities.

OWASP:
  • A08:2021-Software and Data Integrity Failures
  • A8:2017-Insecure Deserialization
Improper neutralization of special elements used in an OS command ('OS Command Injection') csharp_injection_rule-CommandInjection, CWE-78 Severity: High

OS command injection is a critical vulnerability that can lead to a full system compromise as it may allow an adversary to pass in arbitrary commands or arguments to be executed.

User input should never be used in constructing commands or command arguments to functions which execute OS commands. This includes filenames supplied by user uploads or downloads.

Ensure your application does not:

  • Use user-supplied information in the process name to execute.
  • Use user-supplied information in an OS command execution function which does not escape shell meta-characters.
  • Use user-supplied information in arguments to OS commands.

The application should have a hardcoded set of arguments that are to be passed to OS commands. If filenames are being passed to these functions, it is recommended that a hash of the filename be used instead, or some other unique identifier. It is strongly recommended that a native library that implements the same functionality be used instead of using OS system commands, due to the risk of unknown attacks against third party commands.

When specifying the OS command, ensure the application uses the full path information, otherwise the OS may attempt to look up which process to execute and could be vulnerable to untrusted search path vulnerabilities (CWE-426).

Example of safely executing an OS command:

public void ExecuteCommand(string userFileData) {
// generate a random filename, do not using user input
string fileName = "C:\Temp\" + Guid.NewGuid();
File.WriteAllText(fileName, userFileData);

using (Process process = new Process())
{
// hardcode the full process path
ProcessStartInfo processInfo = new ProcessStartInfo("C:\App\FileReader.exe");
// only pass in trust arguments, and never direct user input.
processInfo.Arguments = fileName;
processInfo.UseShellExecute = false;
process.StartInfo = processInfo;
process.Start();
}
}

For more information on OS command injection, see OWASP's guide: OS_Command_Injection_Defense_Cheat_Sheet.html

OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
XML injection (aka Blind XPath injection) csharp_other_rule-UnsafeXSLTSettingUsed, CWE-91 Severity: High

By setting XsltSettings.EnableScript to true, an adversary who is able to influence the loaded XSL document could directly inject code to compromise the system. It is strongly recommended that an alternative approach is used to work with XML data.

For increased security:

  • Never process user-supplied XSL style sheets
  • Ensure XsltSettings.EnableScript is set to false
  • Ensure XsltSettings.EnableDocumentFunction is set to false

If the application must calculate values from XML input, instead of using XSL scripts to execute functions, modify the XML document prior to running the
XslCompiledTransform.Transform method.

Example of modifying the XML prior to running Transform:

const String filename = "number.xml";
const String stylesheet = "calc.xsl";

// Compile the style sheet. XsltSettings xslt_settings = new XsltSettings();
xslt_settings.EnableScript = false; // disable script xslt_settings.EnableDocumentFunction = false; // disable document() function XslCompiledTransform xslt = new XslCompiledTransform();
XmlResolver resolver = null; // set a null entity resolver xslt.Load(stylesheet, xslt_settings, resolver);

// Load the XML source file, using XDocument for safety XDocument doc = XDocument.Load(filename);

// do our modifications to the document before the transformation
// instead of inside of a script. doc.Element("data").Add(new XElement("circle", new XElement("radius", 12)));

// Create an XmlWriter. XmlWriterSettings settings = new XmlWriterSettings();
settings.OmitXmlDeclaration = true;
settings.Indent = true;
XmlWriter writer = XmlWriter.Create("output.xml", settings);
// Finally, execute the transformation. xslt.Transform(doc.CreateReader(), writer);
writer.Close();
For more information on security considerations when using XSL see the following URLs:
xslt-security-considerations
system.xml.xsl.xslcompiledtransform
OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Certificate validation disabled csharp_crypto_rule-CertificateValidationDisabled, CWE-295 Severity: Medium

The ServicePointManager.ServerCertificateValidationCallback event has been set to always return true, which effectively disables the validation of server certificates.

This allows for an adversary who is in between the application and the target host to intercept potentially sensitive information or transmit malicious data.

Remove the callback function that is returning true to allow normal certificate validation to proceed. When no callback is provided, the client will validate that the certificate name matches the hostname that was used when creating the request.

For more information on the ServerCertificateValidationCallback property see: system.net.servicepointmanager.servercertificatevalidationcallback

OWASP:
  • A07:2021-Identification and Authentication Failures
  • A2:2017-Broken Authentication
Use of a broken or risky cryptographic algorithm csharp_crypto_rule-WeakCipherAlgorithm, CWE-327 Severity: Medium

DES, TripleDES and RC2 are all considered broken or insecure cryptographic algorithms. If using .NET Framework greater than version 6.0 consider using ChaCha20Poly1305
instead as it is easier and faster than the alternatives such as AES-256-GCM.

For older applications, AES-256-GCM is recommended, however it has many drawbacks:
- Slower than ChaCha20Poly1305.
- Catastrophic failure if nonce values are reused.

Example using ChaCha20Poly1305:

// Generate a random key byte[] key = new byte[32];
RandomNumberGenerator.Fill(key);

// Note nonce values must be regenerated every time they are used. byte[] nonce = new byte[12];
RandomNumberGenerator.Fill(nonce);

byte[] authTag = new byte[16];
byte[] cipherText;

using (ChaCha20Poly1305 encryptor = new ChaCha20Poly1305(key))
{
byte[] plainText = System.Text.Encoding.UTF8.GetBytes("Secret text to encrypt");
cipherText = new byte[plainText.Length];
encryptor.Encrypt(nonce, plainText, cipherText, authTag);
}

using (ChaCha20Poly1305 decryptor = new ChaCha20Poly1305(key))
{
byte[] output = new byte[cipherText.Length];
decryptor.Decrypt(nonce, cipherText, authTag, output);
Console.WriteLine("Output: {0}", System.Text.Encoding.UTF8.GetString(output));
}

Example using AES-256-GCM:

// Generate a random key byte[] key = new byte[32];
RandomNumberGenerator.Fill(key);

// Note nonce values must be regenerated every time they are used. byte[] nonce = new byte[AesGcm.NonceByteSizes.MaxSize];
RandomNumberGenerator.Fill(nonce);

byte[] authTag = new byte[AesGcm.TagByteSizes.MaxSize];
byte[] cipherText;

using (AesGcm encryptor = new AesGcm(key))
{
byte[] plainText = Encoding.UTF8.GetBytes("Secret text to encrypt");
cipherText = new byte[plainText.Length];
encryptor.Encrypt(nonce, plainText, cipherText, authTag);
}

using (AesGcm decryptor = new AesGcm(key))
{
byte[] output = new byte[cipherText.Length];
decryptor.Decrypt(nonce, cipherText, authTag, output);
Console.WriteLine("Output: {0}", Encoding.UTF8.GetString(output));
}
OWASP:
  • A02:2021-Cryptographic Failures
  • A3:2017-Sensitive Data Exposure
Use of a broken or risky cryptographic algorithm csharp_crypto_rule-WeakCipherMode, CWE-327 Severity: Medium

Cryptographic algorithms provide many different modes of operation, only some of which provide message integrity. Without message integrity it could be possible for an adversary to attempt to tamper with the ciphertext which could lead to compromising the encryption key. Newer algorithms apply message integrity to validate ciphertext has not been tampered with.

Instead of using an algorithm that requires configuring a CipherMode, an algorithm that has built-in message integrity should be used. If using .NET Framework greater than version 6.0 consider using ChaCha20Poly1305 or AES-256-GCM.

For older applications, AES-256-GCM is recommended, however it has many drawbacks:
- Slower than ChaCha20Poly1305.
- Catastrophic failure if nonce values are re-used.

Example using ChaCha20Poly1305:

// Generate a random key byte[] key = new byte[32];
RandomNumberGenerator.Fill(key);

ChaCha20Poly1305 encryptor = new ChaCha20Poly1305(key);

// Note nonce values must be regenerated every time they are used. var nonce = new byte[12];
RandomNumberGenerator.Fill(nonce);

byte[] plainText = System.Text.Encoding.UTF8.GetBytes("Secret text to encrypt");
byte[] cipherText = new byte[plainText.Length];
var authTag = new byte[16];

encryptor.Encrypt(nonce, plainText, cipherText, authTag);
byte[] output = new byte[cipherText.Length];
encryptor.Decrypt(nonce, cipherText, authTag, output);
Console.WriteLine("Output: {0}", System.Text.Encoding.UTF8.GetString(output));

Example using AES-256-GCM:

var plaintextBytes = Encoding.UTF8.GetBytes("Secret text to encrypt");
var key = new byte[32];
RandomNumberGenerator.Fill(key);

using var aes = new AesGcm(key);
var nonce = new byte[AesGcm.NonceByteSizes.MaxSize];
RandomNumberGenerator.Fill(nonce);

var cipherText = new byte[plaintextBytes.Length];
var tag = new byte[AesGcm.TagByteSizes.MaxSize];

aes.Encrypt(nonce, plaintextBytes, cipherText, tag);

// Decrypt using (var decrypt = new AesGcm(key))
{
var decryptedBytes = new byte[cipherText.Length];

decrypt.Decrypt(nonce, cipherText, tag, decryptedBytes);

Console.WriteLine("Decrypted: {0}", Encoding.UTF8.GetString(decryptedBytes));
}
OWASP:
  • A02:2021-Cryptographic Failures
  • A3:2017-Sensitive Data Exposure
Use of a broken or risky cryptographic algorithm (SHA1 / MD5) csharp_crypto_rule-WeakHashingFunction, CWE-327 Severity: Medium

Both MD5 and SHA1 hash algorithms have been found to be vulnerable to producing collisions. This means that two different values, when hashed, can lead to the same hash value. If the application is trying to use these hash methods for storing passwords, then it is recommended to switch to a password hashing algorithm such as Argon2id or PBKDF2. Currently there is no vetted Argon2id implementation for C# so it is recommended that PBKDF2 be used until one is available.

Example using PBKDF2 to generate and compare passwords:

const int SaltSize = 24;
const int HashSize = 24;
// number of pbkdf2 iterations, Rfc2898DeriveBytes uses hmac-sha1
// so set a high iteration count const int Iterations = 1_300_000;
byte[] salt = new byte[SaltSize];
RandomNumberGenerator.Fill(salt);

Rfc2898DeriveBytes pbkdf2 = new Rfc2898DeriveBytes("some password", salt, Iterations);
byte[] hashBytes = pbkdf2.GetBytes(HashSize);
// Store salt and hashedBytes in a data store such as database for authentication Console.WriteLine("Hash {0}", BitConverter.ToString(hashBytes).Replace("-", ""));
// Do a constant time comparison as to not leak data based on timing if (CryptographicOperations.FixedTimeEquals(hashBytes, hashBytes)) {
Console.WriteLine("hashes are equal");
}

For more information on PBKDF2 see: system.security.cryptography.rfc2898derivebytes

For more information on secure password storage see OWASP: Password_Storage_Cheat_Sheet.html

OWASP:
  • A02:2021-Cryptographic Failures
  • A3:2017-Sensitive Data Exposure
Use of cryptographically weak Pseudo-Random Number Generator (PRNG) csharp_crypto_rule-WeakRNG, CWE-338 Severity: Medium

Depending on the context, generating weak random numbers may expose cryptographic functions which rely on these numbers to be exploitable. When generating numbers for sensitive values such as tokens, nonces, and cryptographic keys, it is recommended that the
RandomNumberGenerator class be used.

Example RandomNumberGenerator usage:

Int32 randInt = RandomNumberGenerator.GetInt32(32000);
byte[] randomBytes = new byte[64];
RandomNumberGenerator.Fill(randomBytes);
Console.WriteLine("Random Int32: {0}", randInt);
Console.WriteLine("Random Bytes: {0}", BitConverter.ToString(randomBytes).Replace("-", ""));

For more information see: system.security.cryptography.randomnumbergenerator

OWASP:
  • A02:2021-Cryptographic Failures
  • A3:2017-Sensitive Data Exposure
Potential Cross-Site Request Forgery (CSRF) csharp_csrf_rule-Csrf, CWE-352 Severity: Medium

The application failed to protect against Cross-Site Request Forgery (CSRF)
due to not including the [ValidateAntiForgeryToken] attribute on an HTTP method handler that could change user state (usually in the form of POST or PUT methods).

The vulnerability can be exploited by an adversary creating a link or form on a third party site and tricking an authenticated victim to access them.

Add the [ValidateAntiForgeryToken] to all methods which take in user data and change user state (such as updating a database with a new value). This is especially true for functionality such as updating passwords or other security sensitive functions.

Alternatively, applications can enable a global
AutoValidateAntiforgeryTokenAttribute
filter.

For more information on ValidateAntiForgeryToken and other CSRF protections in .NET see the following URL: anti-request-forgery

Additionally, consider setting all session cookies to have the SameSite=Strict attribute. It should be noted that this may impact usability when sharing links across other mediums. It is recommended that a two cookie based approach is taken, as outlined in the
Top level navigations
section of the SameSite RFC.

For more information on CSRF see OWASP's guide: csrf

OWASP:
  • A01:2021-Broken Access Control
  • A5:2017-Broken Access Control
Improper neutralization of special elements used in an LDAP query ('LDAP Injection') csharp_injection_rule-LdapInjection, CWE-90 Severity: Medium

LDAP injection attacks exploit LDAP queries to influence how data is returned by the LDAP, or in this case an Active Directory server.

It is recommended that newer applications use the System.DirectoryServices.AccountManagement
API instead of DirectorySearcher API as it hides the complexity of querying LDAP directly. However, the AccountManagement API is still susceptible to LDAP injection if a user inputs LDAP queries, including LDAP filter characters such as .

It is recommended that all input passed to LDAP querying systems encode the following values:

  • Any occurrence of the null character must be escaped as “\00”.
  • Any occurrence of the open parenthesis character must be escaped as “\28”.
  • Any occurrence of the close parenthesis character must be escaped as “\29”.
  • Any occurrence of the asterisk character must be escaped as “\2a”.
  • Any occurrence of the backslash character must be escaped as “\5c”.

Example code that safely encodes input for use in an LDAP query using the AccountManagement
API:

using System.DirectoryServices.AccountManagement;

string EncodeLDAPString(string input) {
// Note the character is replaced first
char[] chars = new char[] { '\', '\0', '(', ')', '
' };
string[] encoded = new string[] { "\5c", "\00", "\28", "\29", "\2a" };

for (int i = 0; i < chars.Length; i++)
{
input = input.Replace(chars[i].ToString(), encoded[i]);
}

return input;
}

// unsafe, do not use without encoding first string userInput = "Administrator";
PrincipalContext AD = new PrincipalContext(ContextType.Domain, "ad.example.dev");

UserPrincipal u = new UserPrincipal(AD);
string encodedUserName = EncodeLDAPString(userInput);

// The AD search term, encoded prior to calling search u.SamAccountName = encodedUserName;

// Search for user PrincipalSearcher search = new PrincipalSearcher(u);

// Use FindOne to only return a single result UserPrincipal result = (UserPrincipal)search.FindOne();
search.Dispose();

// show some details if (result != null) {
Console.WriteLine("User: {0}", result.DisplayName);
} else {
Console.WriteLine("user not found");
}

The same encoding method shown in EncodeLDAPString can also be used when using the older DirectorySearcher API.

For more information see OWASP's guide: LDAP_Injection_Prevention_Cheat_Sheet.html

OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection') csharp_injection_rule-SQLInjection, CWE-89 Severity: Medium

SQL Injection is a critical vulnerability that can lead to data or system compromise. By dynamically generating SQL query strings, user input may be able to influence the logic of the SQL statement. This could lead to an adversary accessing information they should not have access to, or in some circumstances, being able to execute OS functionality or code.

Replace all dynamically generated SQL queries with parameterized queries. In situations where dynamic queries must be created, never use direct user input, but instead use a map or dictionary of valid values and resolve them using a user supplied key.

For example, some database drivers do not allow parameterized queries for > or < comparison operators. In these cases, do not use a user supplied > or < value, but rather have the user supply a gt or lt value. The alphabetical values are then used to look up the > and <
values to be used in the construction of the dynamic query. The same goes for other queries where column or table names are required but cannot be parameterized.

Example using parameterized queries with SqlCommand:

string userInput = "someUserInput";
string connectionString = ...;
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
String sql = "SELECT name, value FROM table where name=@Name";

using (SqlCommand command = new SqlCommand(sql, connection))
{
command.Parameters.Add("@Name", System.Data.SqlDbType.NVarChar);
command.Parameters["@Name"].Value = userInput;
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
Console.WriteLine("{0} {1}", reader.GetString(0), reader.GetString(1));
}
}
}
}

For more information on SQL Injection see OWASP: SQL_Injection_Prevention_Cheat_Sheet.html

OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Improper neutralization of data within XPath expressions ('XPath Injection') csharp_injection_rule-XPathInjection, CWE-643 Severity: Medium

XPath injection is a vulnerability that can allow an adversary to inject or modify how an XML query is structured. Depending on the logic of the original query, this could lead to adversaries extracting unauthorized information or in rare cases bypassing authorization checks.

It is recommended that LINQ to XML is used instead of XPath for querying XML documents. Care must be taken to <strong>not</strong> call these LINQ functions with user input as they can still lead to XPath injection:

  • XPathEvaluate
  • XPathSelectElement
  • XPathSelectElements

Example using LINQ to XML to safely extract the first user from a list of users:

// XDocument is safe from XXE attacks as the resolver is disabled by default XDocument doc = XDocument.Load("users.xml");
XNamespace ns = "urn:users-schema";

string userInput = "LastName";

// Get all the users. var user = doc.Descendants(ns + "user")
.Select(u => new {
FirstName = (string)u.Element(ns + "first-name"),
LastName = (string)u.Element(ns + "last-name")
}).Where(u => u.LastName == userInput).FirstOrDefault();

Console.WriteLine(user.FirstName + " " + user.LastName);

For more information on LINQ to XML security see: linq-xml-security

For more information on XML security see OWASP's guide: XML_External_Entity_Prevention_Cheat_Sheet.html

OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Improper restriction of XML external entity reference ('XXE') csharp_injection_rule-XmlDocumentXXEInjection, CWE-611 Severity: Medium

External XML entities are a feature of XML parsers that allow documents to contain references to other documents or data. This feature can be abused to read files, communicate with external hosts, exfiltrate data, or cause a Denial of Service (DoS).

XML parsers and document loaders must be configured to not resolve entities. This can be done by:
- Ensuring you are running a version of .NET Framework greater than 4.5.2 (released in 2014).
- Using XDocument which disables entity resolution and is generally safe from DoS.
- Setting XmlDocument's XmlResolver to null.

Example of safely loading an XML file using XmlDocument:

XmlDocument document = new XmlDocument();
document.XmlResolver = null;
document.Load("users.xml");

For more information on XML security, see OWASP's guide: XML_External_Entity_Prevention_Cheat_Sheet.html

OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Improper restriction of XML external entity reference ('XXE') csharp_injection_rule-XmlReaderXXEInjection, CWE-611 Severity: Medium

External XML entities are a feature of XML parsers that allow documents to contain references to other documents or data. This feature can be abused to read files, communicate with external hosts, exfiltrate data, or cause a Denial of Service (DoS).

XML parsers and document loaders must be configured to not resolve entities. This can be done by:
- Ensuring you are running a version of .NET Framework greater than 4.5.2 (released in 2014).
- Setting XmlTextReader's ProhibitDtd to true
- Setting XmlReaderSettings DtdProcessing to DtdProcessing.Prohibit

Example of safely loading an XML file using XmlDocument:

var settings = new XmlReaderSettings();
settings.DtdProcessing = DtdProcessing.Prohibit;
XmlReader reader = XmlReader.Create(path, settings);

For more information on XML security, see OWASP's guide: XML_External_Entity_Prevention_Cheat_Sheet.html

OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Improper limitation of a pathname to a restricted directory ('Path Traversal') csharp_path_rule-PathTraversal, CWE-22 Severity: Medium

The application dynamically constructs file or path information. If the path information comes from user input, it could be abused to read sensitive files, access other users data, or aid in exploitation to gain further system access.

User input should never be used in constructing paths or files for interacting with the filesystem. This includes filenames supplied by user uploads or downloads. If possible consider hashing user input or replacing it with unique values and use System.IO.Path.GetFullPath to resolve and validate the path information prior to processing any file functionality.

Example using Path.GetFullPath and not allowing direct user input:

// store user input alongside an ID we control struct userData
{
public string userFilename;
public Guid id;
}

class Program
{
public static void Main()
{
userData data = new userData();
// user input, saved only as a reference
data.userFilename = "..\test.txt";

// random id as the filename
data.id = Guid.NewGuid();

// restrict all file processing to this directory only
string basePath = "C:\Restricted\";

// resolve the full path, but only use our random generated id
string fullPath = Path.GetFullPath(basePath + data.id);

// verify the path is contained within our basePath
if (!fullPath.StartsWith(basePath)) {
Console.WriteLine("Invalid path specified!");
return;
}
// process / work with file
}
}

For more information on path traversal issues see OWASP: Path_Traversal

OWASP:
  • A01:2021-Broken Access Control
  • A5:2017-Broken Access Control
Improper neutralization of input during web page generation ('Cross-site Scripting') csharp_xss_rule-HtmlElementXss, CWE-79 Severity: Medium

Cross Site Scripting (XSS) is an attack which exploits a web application or system to treat user input as markup or script code. It is important to encode the data depending on the specific context it is used in. There are at least six context types:

  • Inside HTML tags <div>context 1</div>
  • Inside attributes: <div class="context 2"></div>
  • Inside event attributes <button onclick="context 3">button</button>
  • Inside script blocks: <script>var x = "context 4"</script>
  • Unsafe element HTML assignment: element.innerHTML = "context 5"
  • Inside URLs: <iframe src="context 6"></iframe><a href="context 6">link</a>
    User input that is displayed within the application must be encoded, sanitized or validated to ensure it cannot be treated as HTML or executed as Javascript code. Care must also be taken to not mix server-side templating with client-side templating, as the server-side templating will not encode things like {{ 77 }} which may execute client-side templating features.

It is NOT advised to encode user input prior to inserting into a data store. The data will need to be encoded depending on context of where it is output. It is much safer to force the displaying system to handle the encoding and not attempt to guess how it should be encoded.

Consider using built-in framework capabilities for automatically encoding user input. Depending on output context, consider using the following System.Text.Encodings.Web encoders:

For more information on protecting ASP.NET Core applications from XSS see: cross-site-scripting

OWASP:*
  • A03:2021-Injection
  • A1:2017-Injection
Improper neutralization of input during web page generation ('Cross-site Scripting') csharp_xss_rule-ScriptXss, CWE-79 Severity: Medium

Cross Site Scripting (XSS) is an attack which exploits a web application or system to treat user input as markup or script code. It is important to encode the data depending on the specific context it is used in.

User input that is used within the application scripts must be encoded, sanitized or validated to ensure it cannot change the behavior of the Javascript code.

It is NOT advised to encode user input prior to inserting into a data store. The data will need to be encoded depending on context of where it is output. It is much safer to force the displaying system to handle the encoding and not attempt to guess how it should be encoded.

Consider using built-in framework capabilities for automatically encoding user input. Depending on output context, consider using the following System.Text.Encodings.Web encoders:

For more information on protecting ASP.NET Core applications from XSS see: cross-site-scripting

OWASP:
Sensitive cookie without 'HttpOnly' flag csharp_cookies_rule-CookieWithoutHttpOnlyFlag, CWE-1004 Severity: Low

The HttpOnly attribute when set to true protects the cookie value from being accessed by client side JavaScript such as reading the document.cookie values. By enabling this protection, a website that is vulnerable to Cross-Site Scripting (XSS) will be able to block malicious scripts from accessing the cookie value from JavaScript.

Example of protecting an HttpCookie:

// Create an HttpOnly cookie. HttpCookie someCookie = new HttpCookie("SomeCookieName", "SomeValue");
someCookie.HttpOnly = true;

For more information see: system.web.httpcookie.httponly

Session cookies should be configured with the following security directives:

OWASP:
  • A05:2021-Security Misconfiguration
  • A6:2017-Security Misconfiguration
Sensitive cookie in HTTPS session without 'Secure' attribute csharp_cookies_rule-CookieWithoutSSLFlag, CWE-614 Severity: Low

The Secure attribute when set to true protects the cookie value from being being transmitted over clear text communication paths such as HTTP. By enabling this protection, the cookie will only be sent over HTTPS.

Example of protecting an HttpCookie:

// Create an HttpOnly cookie. HttpCookie someCookie = new HttpCookie("SomeCookieName", "SomeValue");
someCookie.Secure = true;

For more information see: system.web.httpcookie.secure

Session cookies should be configured with the following security directives:

OWASP:
  • A05:2021-Security Misconfiguration
  • A6:2017-Security Misconfiguration
URL redirection to untrusted site 'open redirect' csharp_endpoint_rule-UnvalidatedRedirect, CWE-601 Severity: Info

The application may allow open redirects if created using user supplied input. Open redirects are commonly abused in phishing attacks where the original domain or URL looks like a legitimate link, but then redirects a user to a malicious site. An example would be
https://example.com/redirect?url=https://%62%61%64%2e%63%6f%6d%2f%66%61%6b%65%6c%6f%67%69%6e
which, when decoded, turns into bad.com/fakelogin.

Never redirect a client based on user input. It is recommended that the list of target links to redirect a user to are contained server side, and retrieved using a numerical value as an index to return the link to be redirected to. For example, /redirect?id=1 would cause the application to look up the 1 index and return a URL such as https://example.com. This URL would then be used to redirect the user, using the 301 response code and Location header.

For more information on open redirects see OWASP's guide: Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html

OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Weak password requirements csharp_password_rule-PasswordComplexity, CWE-521 Severity: Info

The application's PasswordValidator.RequiredLength property allows passwords to be less than 8 characters. Consider requiring a length of at least 8 or more characters to reduce the chance of passwords being brute forced.

Example of setting the RequiredLength to 8 in ASP.NET Core Identity:

builder.Services.Configure<IdentityOptions>(options =>
{
// Default Password settings.
options.Password.RequireDigit = true;
options.Password.RequireLowercase = true;
options.Password.RequireNonAlphanumeric = true;
options.Password.RequireUppercase = true;
options.Password.RequiredLength = 8;
options.Password.RequiredUniqueChars = 1;
});

For more information on configuring ASP.NET Core Identity see: identity-configuration

OWASP:
  • A07:2021-Identification and Authentication Failures
  • A2:2017-Broken Authentication
ASP.NET input validation disabled csharp_validation_rule-InputValidation, CWE-554 Severity: Info

By using the [ValidateInput(false)] attribute in a controller class, the application will disable request validation for that method. This disables ASP.NET from examining requests for injection attacks such as Cross-Site-Scripting (XSS).

If possible, re-enable validation by using ValidateInput(true). In some cases this may not be possible, in which case ensure how the request data used is validated and this method does not output user input directly into the view.

For more information on protecting ASP.NET Core applications from XSS see: cross-site-scripting

Example of enabling ValidateInput attribute:

class ControllerClass
{
[ValidateInput(true)]
public void SomeActionMethod()
{
}
}

For more information on ASP.NET request validation see OWASP: ASP-NET_Request_Validation

OWASP:
  • A05:2021-Security Misconfiguration
  • A6:2017-Security Misconfiguration

generic

Name Identifiers Description
Use of potentially dangerous function rules_lgpl_oc_other_rule-ios-self-signed-ssl, CWE-676 Severity: Critical

App allows self signed or invalid SSL certificates. App is
vulnerable to MITM attacks. If the app does not verify the
authenticity of the server's SSL certificate, an attacker could
impersonate the server and intercept sensitive data transmitted
between the app and the server. To fix these security issues, you should ensure proper SSL
certificate validation in your Objective-C code. Here's how you
can do it:

- (void)loadSecureURL {
NSURL url = [NSURL URLWithString:@"https://example.com"];
NSURLRequest
request = [NSURLRequest requestWithURL:url];

// Create session configuration
NSURLSessionConfiguration configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
configuration.TLSMinimumSupportedProtocol = kTLSProtocol12;

// Create session with configuration
NSURLSession
session = [NSURLSession sessionWithConfiguration:configuration];

// Create data task
NSURLSessionDataTask task = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
if (error) {
NSLog(@"Error loading URL: %@", error);
// Handle error
} else {
// Handle response
NSLog(@"Response: %@", response);
}
}];

// Start task
[task resume];
}

OWASP:*
  • A06:2021-Vulnerable and Outdated Components
  • A9:2017-Using Components with Known Vulnerabilities
Improper certificate validation rules_lgpl_oc_other_rule-ios-webview-ignore-ssl, CWE-295 Severity: Critical

UIWebView in App ignore SSL errors and accept any SSL Certificate.
App is vulnerable to MITM attacks. If the app does not verify the
authenticity of the server's SSL certificate, an attacker could
impersonate the server and intercept sensitive data transmitted
between the app and the server. To fix these security issues, you should ensure proper SSL certificate
validation in your Objective-C code. Here's how you can do it:

- (void)loadSecureURL {
NSURL url = [NSURL URLWithString:@"https://example.com"];
NSURLRequest
request = [NSURLRequest requestWithURL:url];

// Create session configuration
NSURLSessionConfiguration configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
configuration.TLSMinimumSupportedProtocol = kTLSProtocol12;

// Create session with configuration
NSURLSession
session = [NSURLSession sessionWithConfiguration:configuration];

// Create data task
NSURLSessionDataTask task = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
if (error) {
NSLog(@"Error loading URL: %@", error);
// Handle error
} else {
// Handle response
NSLog(@"Response: %@", response);
}
}];

// Start task
[task resume];
}
OWASP:*
  • A05:2021-Security Misconfiguration
  • A6:2017-Security Misconfiguration

go

Name Identifiers Description
Improper neutralization of special elements used in an SQL command ('SQL Injection') go_sql_rule-concat-sqli, CWE-89 Severity: High

SQL Injection is a critical vulnerability that can lead to data or system compromise. By dynamically generating SQL query strings, user input may be able to influence the logic of the SQL statement. This could lead to an adversary accessing information they should not have access to or in some circumstances, being able to execute OS functionality or code.

Replace all dynamically generated SQL queries with parameterized queries. In situations where dynamic queries must be created, never use direct user input, but instead use a map or dictionary of valid values and resolve them using a user supplied key.

For example, some database drivers do not allow parameterized queries for > or < comparison operators. In these cases, do not use a user supplied > or < value, but rather have the user supply a gt or lt value. The alphabetical values are then used to look up the > and <
values to be used in the construction of the dynamic query. The same goes for other queries where column or table names are required but cannot be parameterized.

Example using parameterized queries with sql.Query:

rows, err := db.Query("SELECT * FROM users WHERE userName = ?", userName)
if err != nil {
return nil, err
}
defer rows.Close()
for rows.Next() {
// ... process rows
}

For more information on SQL Injection see OWASP: SQL_Injection_Prevention_Cheat_Sheet.html

OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Improper neutralization of special elements used in an OS command ('OS Command Injection') go_subproc_rule-subproc, CWE-78 Severity: High

OS command injection is a critical vulnerability that can lead to a full system compromise as it may allow an adversary to pass in arbitrary commands or arguments to be executed.

User input should never be used in constructing commands or command arguments to functions which execute OS commands. This includes filenames supplied by user uploads or downloads.

Ensure your application does not:

  • Use user-supplied information in the process name to execute.
  • Use user-supplied information in an OS command execution function which does not escape shell meta-characters.
  • Use user-supplied information in arguments to OS commands.

The application should have a hardcoded set of arguments that are to be passed to OS commands. If filenames are being passed to these functions, it is recommended that a hash of the filename be used instead, or some other unique identifier. It is strongly recommended that a native library that implements the same functionality be used instead of using OS system commands, due to the risk of unknown attacks against third party commands.

If operating in Windows environments, when specifying the OS command, ensure the application uses the full path information, otherwise the OS may attempt to look up which process to execute and could be vulnerable to untrusted search path vulnerabilities (CWE-426).

Example of safely executing an OS command:

userData := []byte("user data")
// create a temporary file in the application specific directory f, err := ioutil.TempFile("/var/app/restricted", "temp-.dat")
if err != nil {
log.Fatal(err)
}

if _, err := f.Write(userData); err != nil {
log.Fatal(err)
}

if err := f.Close(); err != nil {
log.Fatal(err)
}

// pass the full path to the binary and the name of the temporary file
// instead of any user supplied filename out, err := exec.Command("/bin/cat", f.Name()).Output()
if err != nil {
log.Fatal(err)
}

For more information on OS command injection, see OWASP's guide: OS_Command_Injection_Defense_Cheat_Sheet.html

OWASP:*
  • A03:2021-Injection
  • A1:2017-Injection
Use of inherently dangerous function (unsafe package) go_unsafe_rule-unsafe, CWE-242 Severity: High

The unsafe package in Go allows low-level access to memory management features. This includes pointers and direct access to memory. The Go compiler will no longer be able to enforce type safety when working with the unsafe pointer types.

While powerful, access to these functions can lead to many security related issues
such as:

Unless required, all calls to the unsafe package should be removed.

OWASP:
  • A06:2021-Vulnerable and Outdated Components
  • A9:2017-Using Components with Known Vulnerabilities
Use of a broken or risky cryptographic algorithm go_blocklist_rule-blocklist-des, CWE-327 Severity: Medium

The DES algorithm has not been recommended for over 15 years and was withdrawn from NIST (FIPS
46-3) in 2005. It is recommended that an algorithm that provides message integrity be used instead. Consider using XChaCha20Poly1305 or AES-256-GCM.

For older applications, AES-256-GCM is recommended, however it has many drawbacks:
- Slower than XChaCha20Poly1305
- Smaller nonce value size compared to XChaCha20Poly1305
- Catastrophic failure if nonce values are re-used

Example using
XChaCha20Poly1305:

key := make([]byte, chacha20poly1305.KeySize)
if , err := io.ReadFull(rand.Reader, key); err != nil {
log.Fatal(err)
}

// NewX is a variant that uses longer nonce values for better security aead, err := chacha20poly1305.NewX(key)
if err != nil {
log.Fatal(err)
}

var encrypted = []byte{}
var nonce = []byte{}

// Encryption routine
{
msg := []byte("Some secret message")
nonce = make([]byte, aead.NonceSize())
if
, err := io.ReadFull(rand.Reader, nonce); err != nil {
log.Fatal("failed to generate nonce")
}

encrypted = aead.Seal(nil, nonce, msg, nil)
}

// Decryption routine
{
if len(encrypted) < aead.NonceSize() {
log.Fatal("incorrect ciphertext length")
}

msg, err := aead.Open(nil, nonce, encrypted, nil)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Decrypted: %s\n", msg)
}

Example using AES-256-GCM:

// 32 byte keys will configure AES-256
key := make([]byte, 32)
if , err := io.ReadFull(rand.Reader, key); err != nil {
log.Fatal(err)
}

blockCipher, err := aes.NewCipher(key)
if err != nil {
log.Fatal(err)
}

aead, err := cipher.NewGCM(blockCipher)
if err != nil {
log.Fatal(err)
}

var encrypted = []byte{}
var nonce = []byte{}
// Encryption routine
{
msg := []byte("Some secret message")
// note that the key must be rotated every 2^32 random nonces used otherwise
// cipher text could be repeated
nonce = make([]byte, 12)
if
, err := io.ReadFull(rand.Reader, nonce); err != nil {
log.Fatal(err)
}
encrypted = aead.Seal(nil, nonce, msg, nil)
}

// Decryption routine
{
msg, err := aead.Open(nil, nonce, encrypted, nil)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Decrypted: %s\n", msg)
}
OWASP:
  • A02:2021-Cryptographic Failures
  • A3:2017-Sensitive Data Exposure
Use of a broken or risky cryptographic algorithm go_blocklist_rule-blocklist-md5, CWE-327 Severity: Medium

The MD5 message-digest algorithm has been cryptographically broken and is unsuitable for further use. The MD5 hash algorithm has been found to be vulnerable to producing collisions. This means that two different values, when hashed, can lead to the same hash value. It is recommended that the SHA-3 or BLAKE2 family of algorithms be used for non-password based cryptographic hashes instead. For password based cryptographic hashes, consider using the bcrypt or Argon2id family of cryptographic hashes.

Hashing values using BLAKE2:

fileContents := []byte("some file contents to create hash for")
blake2bHasher, err := blake2b.New512(nil)
if err != nil {
log.Fatal(err)
}
hashedValue := blake2bHasher.Sum(fileContents)
fmt.Printf("%s\n", hex.EncodeToString(hashedValue))

Hashing and securely comparing passwords using
Argon2id:

type argonParameters struct {
variant string
version int
memory uint32
iterations uint32
parallelism uint8
saltLength uint32
keyLength uint32
}

func (a argonParameters) StringFormat(salt, derivedKey []byte) string {
encodedSalt := base64.RawStdEncoding.EncodeToString(salt)
encodedKey := base64.RawStdEncoding.EncodeToString(derivedKey)

return fmt.Sprintf("$argon2id$v=%d$m=%d,t=%d,p=%d$%s$%s",
argon2.Version,
a.memory,
a.iterations,
a.parallelism,
encodedSalt,
encodedKey,
)
}

func main() {
// Initialize Argon2id parameters
p := argonParameters{
memory: 64 * 1024,
iterations: 3,
parallelism: 2,
saltLength: 16,
keyLength: 32,
}

// Generate random salt (to be stored alongside derived hash key)
salt := make([]byte, p.saltLength)
if _, err := io.ReadFull(rand.Reader, salt); err != nil {
log.Fatal(err)
}

usersPassword := []byte("User's Very S3cur3P4ss@rd@#$%")

var derivedKey []byte
// Create key hash derived from user's password
{
derivedKey = argon2.IDKey(usersPassword, salt, p.iterations, p.memory, p.parallelism, p.keyLength)
// store p.StringFormat(...) result in a data store...
fmt.Printf("%s\n", p.StringFormat(salt, derivedKey))
}

// Verify a user's password against key
{
keyToCompare := argon2.IDKey(usersPassword, salt, p.iterations, p.memory, p.parallelism, p.keyLength)

// Use subtle.ConstantTimeCompare(..., ...) to ensure no side channel leaks used in timing attacks
if subtle.ConstantTimeCompare(derivedKey, keyToCompare) == 1 {
fmt.Printf("Passwords match\n")
} else {
fmt.Printf("Passwords do not match\n")
}
}
}

For more information on password storage see OWASP's guide: Password_Storage_Cheat_Sheet.html

OWASP:
  • A02:2021-Cryptographic Failures
  • A3:2017-Sensitive Data Exposure
Use of a broken or risky cryptographic algorithm go_blocklist_rule-blocklist-rc4, CWE-327 Severity: Medium

The RC4 stream-cipher has been cryptographically broken and is unsuitable for use in production. It is recommended that ChaCha20 or Advanced Encryption Standard (AES) be used instead. Consider using XChaCha20Poly1305 or AES-256-GCM.

For older applications, AES-256-GCM is recommended, however it has many drawbacks:
- Slower than XChaCha20Poly1305
- Smaller nonce value size compared to XChaCha20Poly1305
- Catastrophic failure if nonce values are re-used

Example using
XChaCha20Poly1305:

key := make([]byte, chacha20poly1305.KeySize)
if , err := io.ReadFull(rand.Reader, key); err != nil {
log.Fatal(err)
}

// NewX is a variant that uses longer nonce values for better security aead, err := chacha20poly1305.NewX(key)
if err != nil {
log.Fatal(err)
}

var encrypted = []byte{}
var nonce = []byte{}

// Encryption routine
{
msg := []byte("Some secret message")
nonce = make([]byte, aead.NonceSize())
if
, err := io.ReadFull(rand.Reader, nonce); err != nil {
log.Fatal("failed to generate nonce")
}

encrypted = aead.Seal(nil, nonce, msg, nil)
}

// Decryption routine
{
if len(encrypted) < aead.NonceSize() {
log.Fatal("incorrect ciphertext length")
}

msg, err := aead.Open(nil, nonce, encrypted, nil)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Decrypted: %s\n", msg)
}

Example using AES-256-GCM:

// 32 byte keys will configure AES-256
key := make([]byte, 32)
if , err := io.ReadFull(rand.Reader, key); err != nil {
log.Fatal(err)
}

blockCipher, err := aes.NewCipher(key)
if err != nil {
log.Fatal(err)
}

aead, err := cipher.NewGCM(blockCipher)
if err != nil {
log.Fatal(err)
}

var encrypted = []byte{}
var nonce = []byte{}
// Encryption routine
{
msg := []byte("Some secret message")
// note that the key must be rotated every 2^32 random nonces used otherwise
// cipher text could be repeated
nonce = make([]byte, 12)
if
, err := io.ReadFull(rand.Reader, nonce); err != nil {
log.Fatal(err)
}
encrypted = aead.Seal(nil, nonce, msg, nil)
}

// Decryption routine
{
msg, err := aead.Open(nil, nonce, encrypted, nil)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Decrypted: %s\n", msg)
}
OWASP:
  • A02:2021-Cryptographic Failures
  • A3:2017-Sensitive Data Exposure
Use of a broken or risky cryptographic algorithm go_blocklist_rule-blocklist-sha1, CWE-327 Severity: Medium

The SHA-1 message-digest algorithm has been cryptographically broken and is unsuitable for further use. It is recommended that the SHA-3, or BLAKE2 family of algorithms be used for non-password based cryptographic hashes instead. For password based cryptographic hashes, consider using the bcrypt or Argon2id family of cryptographic hashes.

Hashing values using BLAKE2:

fileContents := []byte("some file contents to create hash for")
blake2bHasher, err := blake2b.New512(nil)
if err != nil {
log.Fatal(err)
}
hashedValue := blake2bHasher.Sum(fileContents)
fmt.Printf("%s\n", hex.EncodeToString(hashedValue))

Hashing and securely comparing passwords using
Argon2id:

type argonParameters struct {
variant string
version int
memory uint32
iterations uint32
parallelism uint8
saltLength uint32
keyLength uint32
}

func (a argonParameters) StringFormat(salt, derivedKey []byte) string {
encodedSalt := base64.RawStdEncoding.EncodeToString(salt)
encodedKey := base64.RawStdEncoding.EncodeToString(derivedKey)

return fmt.Sprintf("$argon2id$v=%d$m=%d,t=%d,p=%d$%s$%s",
argon2.Version,
a.memory,
a.iterations,
a.parallelism,
encodedSalt,
encodedKey,
)
}

func main() {
// Initialize Argon2id parameters
p := argonParameters{
memory: 64 * 1024,
iterations: 3,
parallelism: 2,
saltLength: 16,
keyLength: 32,
}

// Generate random salt (to be stored alongside derived hash key)
salt := make([]byte, p.saltLength)
if _, err := io.ReadFull(rand.Reader, salt); err != nil {
log.Fatal(err)
}

usersPassword := []byte("User's Very S3cur3P4ss@rd@#$%")

var derivedKey []byte
// Create key hash derived from user's password
{
derivedKey = argon2.IDKey(usersPassword, salt, p.iterations, p.memory, p.parallelism, p.keyLength)
// store p.StringFormat(...) result in a data store...
fmt.Printf("%s\n", p.StringFormat(salt, derivedKey))
}

// Verify a user's password against key
{
keyToCompare := argon2.IDKey(usersPassword, salt, p.iterations, p.memory, p.parallelism, p.keyLength)

// Use subtle.ConstantTimeCompare(..., ...) to ensure no side channel leaks used in timing attacks
if subtle.ConstantTimeCompare(derivedKey, keyToCompare) == 1 {
fmt.Printf("Passwords match\n")
} else {
fmt.Printf("Passwords do not match\n")
}
}
}

For more information on password storage see OWASP's guide: Password_Storage_Cheat_Sheet.html

OWASP:
  • A02:2021-Cryptographic Failures
  • A3:2017-Sensitive Data Exposure
Use of a broken or risky cryptographic algorithm go_crypto_rule-badtlssettings, CWE-327 Severity: Medium

Usage of a cryptographically insecure cipher suite has been detected. It is recommended that alternative ciphers be used instead. It is strongly recommended that all TLS connections use TLS 1.3 as Go will automatically choose the most secure cipher when negotiating the TLS handshake with client or servers. TLS 1.3 cipher suites are configured to require Perfect Forward Secrecy (PFS). PFS is an important property as it will ensure that past encrypted transmissions could not be decrypted if the TLS certificate was compromised.

Example using TLS 1.3 for a Go server:

cert, err := tls.LoadX509KeyPair("server.crt", "server.key")
if err != nil {
log.Fatal(err)
}

cfg := &tls.Config{Certificates: []tls.Certificate{cert}, MinVersion: tls.VersionTLS13}
srv := &http.Server{
Addr: ":8999",
TLSConfig: cfg,
ReadTimeout: time.Minute,
WriteTimeout: time.Minute,
}
log.Fatal(srv.ListenAndServeTLS("", ""))

If TLS 1.0-1.2 must be used, then the following list of ciphers should be chosen as they support Perfect Forward Secrecy (PFS):

  • TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
  • TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
  • TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
  • TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
  • TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305
  • TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305

Example tls.Config using the recommended cipher suites:

cfg := &tls.Config{
MinVersion: tls.VersionTLS12,
CipherSuites: []uint16{
tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
},
}

For more information on cipher suites in Go see: tls-cipher-suites

OWASP:
  • A02:2021-Cryptographic Failures
  • A3:2017-Sensitive Data Exposure
Key exchange without entity authentication go_crypto_rule-insecure-ignore-host-key, CWE-322 Severity: Medium

The application was found to ignore host keys. Host keys are important as they provide assurance that the client can prove that the host is trusted. By ignoring these host keys, it is impossible for the client to validate the connection is to a trusted host.

For the ssh.ClientConfig HostKeyCallback property, consider using the
knownhosts package that parses OpenSSH's known_hosts key database.

Example configuration connecting to a known, trusted host:

knownHostCallback, err := knownhosts.New("/home/user/.ssh/known_hosts")
if err != nil {
log.Fatal(err)
}

// Create client config using the knownHost callback function config := &ssh.ClientConfig{
...
HostKeyCallback: knownHostCallback,
}

// Connect to ssh server conn, err := ssh.Dial("tcp", "localhost:22", config)
if err != nil {
log.Fatal("unable to connect: ", err)
}
defer conn.Close()
OWASP:
  • A07:2021-Identification and Authentication Failures
  • A2:2017-Broken Authentication
Use of deprecated TLS version go_crypto_rule-tlsversion, CWE-310 Severity: Medium

TLS versions 1.1 and 1.0 were deprecated by the IETF in June 2018 due to
a number of attacks against the vulnerable versions. Use of a deprecated
TLS version may result in the unauthorized retrieval of sensitive
information. It is strongly recommended that all TLS connections use TLS 1.3 as Go will automatically choose the most secure cipher when
negotiating the TLS handshake with client or servers. TLS 1.3 cipher suites
are configured to require Perfect Forward Secrecy (PFS). PFS is an important
property as it will ensure that past encrypted transmissions could not be decrypted if the TLS certificate was compromised.

Example using TLS 1.3 for a Go server:

cert, err := tls.LoadX509KeyPair("server.crt", "server.key")
if err != nil {
log.Fatal(err)
}

cfg := &tls.Config{Certificates: []tls.Certificate{cert},
MinVersion: tls.VersionTLS13}

srv := &http.Server{
Addr: ":8999",
TLSConfig: cfg,
ReadTimeout: time.Minute,
WriteTimeout: time.Minute,
}
log.Fatal(srv.ListenAndServeTLS("cert.pem", "key.pem"))
OWASP:
  • A02:2021-Cryptographic Failures
  • A3:2017-Sensitive Data Exposure
Inadequate encryption strength go_crypto_rule-weakkeystrength, CWE-326 Severity: Medium

The application is generating an RSA key that is less than the recommended 2048 bits. The National Institute of Standards and Technology (NIST) deprecated signing Digital Certificates that contained RSA Public Keys of 1024 bits in December 2010. While
1024-bit RSA keys have not been factored yet, advances in compute may make it possible in the near future.

To generate an RSA key of 2048 pass the number of bits as the second parameter to the rsa.GenerateKey function:

import (
"crypto/rand"
"crypto/rsa"
)

func generate() {
key, err := rsa.GenerateKey(rand.Reader, 2048)
if err != nil {
log.Fatal(err)
}
}
OWASP:
  • A02:2021-Cryptographic Failures
  • A3:2017-Sensitive Data Exposure
Use of cryptographically weak Pseudo-Random Number Generator (PRNG) go_crypto_rule-weakrandsource, CWE-338 Severity: Medium

Go's math/rand is not meant for use in generating random numbers for any cryptographic or security sensitive context. This includes generating random numbers that could be used in user specific identifiers or where the random number that is generated is considered to be secret.

Replace all imports of math/rand with crypto/rand.

OWASP:
  • A02:2021-Cryptographic Failures
  • A3:2017-Sensitive Data Exposure
Incorrect permission assignment for critical resource go_file-permissions_rule-fileperm, CWE-732 Severity: Medium

The application was found setting file permissions to overly permissive values. Consider using the following values if the application user is the only process to access the file:

  • 0400 - read only access to the file
  • 0200 - write only access to the file
  • 0600 - read/write access to the file

Example creating a file with read/write permissions for the application user:

f, err := os.OpenFile("file.txt", os.O_CREATE, 0600)
if err != nil {
log.Fatal(err)
}
defer f.Close()
// continue to work with file here

For all other values please see: File-system_permissions

OWASP:
  • A01:2021-Broken Access Control
  • A5:2017-Broken Access Control
Incorrect permission assignment for critical resource go_file-permissions_rule-mkdir, CWE-732 Severity: Medium

The application was found setting directory permissions to overly permissive values. Consider using the following values if the application user is the only process to access files in the directory specified:
- 0700 - read/write access to the files in the directory

Another common value is 0750 which allows the application user read/write access and group users to read the files contained in the directory.

Example creating a directory with read/write permissions for only the application user:

err := os.Mkdir("directory", 0700)
if err != nil {
log.Fatal(err)
}

For all other values please see: File-system_permissions

OWASP:
  • A01:2021-Broken Access Control
  • A5:2017-Broken Access Control
Improper handling of highly compressed data go_filesystem_rule-decompression-bomb, CWE-409 Severity: Medium

Directly decompressing files or buffers may lead to a potential Denial of Service (DoS)
due to a decompression bomb. Decompression bombs are maliciously compressed files or data that decompresses to extremely large sizes. This can cause the process to run out of memory, or the disk to fill up.

To protect against decompression bombs, an
io.LimitReader(...)
should be used to limit how much can be read during the decompression routine.

Example using io.LimitReader to protect against a decompression bomb:

f, err := os.Open("some.gz")
if err != nil {
log.Fatal(err)
}

r, err := gzip.NewReader(f)
if err != nil {
log.Fatal(err)
}

const oneMegabyte = 1024 * 1024
limitedReader := io.LimitReader(r, oneMegabyte)

// use limitedReader to stop copying after 1 MB if _, err := io.Copy(os.Stdout, limitedReader); err != nil {
log.Fatal(err)
}
OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Improper limitation of a pathname to a restricted directory ('Path Traversal') go_filesystem_rule-fileread, CWE-22 Severity: Medium

The application dynamically constructs file or path information. If the path information comes from user input, it could be abused to read sensitive files, access other users data or aid in exploitation to gain further system access.

User input should never be used in constructing paths or files for interacting with the filesystem. This includes filenames supplied by user uploads or downloads. If possible, consider hashing user input or replacing it with unique values. Additionally, use filepath.Base to only use the filename and not path information. Always validate the full path prior to opening or writing to any file.

Example using filepath.Base, generating a unique filename without using user input to construct filepath information:

type userData struct {
id string
userFilename string
}

func newUserData(userFilename string) userData {
return userData{
id: randomFileID(), // random id as the filename
userFilename: userFilename,
}
}

// randomFileID generates a random id, to be used as a filename func randomFileID() string {
id := make([]byte, 16)
if _, err := io.ReadFull(rand.Reader, id); err != nil {
log.Fatal(err)
}
return hex.EncodeToString(id)
}

func main() {

// user input, saved only as a reference
data := newUserData("../../possibly/malicious")

// restrict all file access to this path
const basePath = "/tmp/"

// resolve the full path, but only use our random generated id
resolvedPath, err := filepath.Join(basePath, filepath.Base(data.id))
if err != nil {
log.Fatal(err)
}

// verify the path is prefixed with our basePath
if !strings.HasPrefix(resolvedPath, basePath) {
log.Fatal("path does not start with basePath")
}
// process / work with file
}

For more information on path traversal issues see OWASP: Path_Traversal

OWASP:
  • A01:2021-Broken Access Control
  • A5:2017-Broken Access Control
Files or directories accessible to external parties go_filesystem_rule-httprootdir, CWE-552 Severity: Medium

The application is potentially exposing the entire filesystem by mounting the root directory / to an HTTP handler function. Anyone who is able to access this HTTP server may be able to access any file that the HTTP server has access to.

Restrict the http.Dir path to only a specific folder instead of the entire filesystem.

Example server only allowing directory listing on a public directory:

const path = "/var/www/html/public"
fs := http.FileServer(http.Dir(path))
log.Fatal(http.ListenAndServe(":9000", fs))
OWASP:
  • A01:2021-Broken Access Control
  • A5:2017-Broken Access Control
Incorrect default permissions go_filesystem_rule-poorwritepermissions, CWE-276 Severity: Medium

The application was found setting file permissions to overly permissive values. Consider using the following values if the application user is the only process to access the file:

  • 0400 - read only access to the file
  • 0200 - write only access to the file
  • 0600 - read/write access to the file

Example writing file contents with read/write permissions for the application user:

dat := []byte("sensitive data")
if err := os.WriteFile("file.txt", dat, 0600); err != nil {
log.Fatal(err)
}

For all other values please see: File-system_permissions

OWASP:
  • A01:2021-Broken Access Control
  • A5:2017-Broken Access Control
Creation of temporary file with insecure permissions go_filesystem_rule-tempfiles, CWE-378 Severity: Medium

The application was found creating files in shared system temporary directories
(/tmp or /var/tmp) without using the os.CreateTemp function. Depending on how the application uses this temporary file, an attacker may be able to create symlinks that point to other files prior to the application creating or writing to the target file, leading to unintended files being created or overwritten.

Example using os.CreateTemp in an application restricted directory:

// assumes /opt/appdir/ is chown'd to the running application user if err := os.MkdirAll("/opt/appdir/restricted", 0700); err != nil {
log.Fatal(err)
}

// create a temporary file in the restricted directory in the form of temp-952569059.txt f, err := os.CreateTemp("/opt/appdir/restricted", "temp-.txt")
if err != nil {
log.Fatal(err)
}

defer f.Close()
// clean up on exit defer os.Remove(f.Name())
// work with file
OWASP:*
  • A01:2021-Broken Access Control
  • A5:2017-Broken Access Control
Improper limitation of a pathname to a restricted directory ('Path Traversal') go_filesystem_rule-ziparchive, CWE-22 Severity: Medium

The application may be vulnerable to a path traversal if it extracts untrusted archive files. This vulnerability is colloquially known as 'Zip Slip'. Archive files may contain folders which, when extracted, may write outside of the intended directory. This is exploited by including path traversal characters such as ../../other/directory to overwrite or place files in system or application directories.

Extra care must be taken when extracting archive files as there are numerous concerns:

  • Limit the size of the zip archive as it may contain "Zip Bombs", files that extract to extremely large sizes.
  • If possible, generate unique filenames instead of using the archives file names, as it may be possible for users to overwrite files if the filenames are the same.
  • Validate file paths are written with a prefixed, known trusted directory.
  • Only process regular files and not symbolic links, as some applications may attempt to read/follow the symbolic link, leading to arbitrary file read / write vulnerabilities.

Example of securely processing an archive file:

r, err := zip.OpenReader("trusted.zip")
if err != nil {
log.Fatal(err)
}

// Ensure archive contains only the expected number of files const expectedFileCount = 10
if len(r.File) > expectedFileCount {
log.Fatalf("too many files in archive: %d\n", len(r.File))
}

// One approach is to sum up all files before attempting to process
// them. const totalAllowedSize = 1024 * 1024 * 10 // 10MB var totalSize uint64
for , f := range r.File {
totalSize += f.UncompressedSize64
}

if totalSize > totalAllowedSize {
log.Fatalf("archive exceeds total allowed size: %d\n", totalSize)
}

// configure a max size per file allowed const maxFileSize = 1024 * 1024 // 1 MB

// set restricted basePath const basePath = "/var/restricted/"

// iterate over the files in the archive for
, f := range r.File {

// Ensure uncompressed size does not exceed our allowed file size
if f.UncompressedSize64 > maxFileSize {
log.Printf("skipping file as it exceeds maxFileSize: %s\n", f.Name)
continue
}

// Ensure file is a regular file and not a symbolic link or has other mode type
// bits set
if !f.Mode().IsRegular() {
log.Printf("skipping non regular file: %s\n", f.Name)
continue
}

// if possible consider not using the name at all, but generating a random id instead.
// If the filename must be used, extract the base name and not folder path information
name := filepath.Base(f.Name)

// Join the file name to the basePath.
resolvedPath := filepath.Join(basePath, name)

// Application must still verify the path is prefixed by the basePath
if !strings.HasPrefix(resolvedPath, basePath) {
log.Fatal("path does not start with basePath")
}

// process / work with file
}

If the application must process directory names as well, use the following code:

// Join the cleaned name to the basePath, note if 'name' starts with ../../ it
// will still allow for traversal, so you must verify the path prefix below resolvedPath := filepath.Join(basePath, filepath.Clean(name))

// Application must still verify the path is prefixed by the basePath if !strings.HasPrefix(resolvedPath, basePath) {
log.Fatal("path does not start with basePath")
}

// process / work with file
OWASP:
  • A01:2021-Broken Access Control
  • A5:2017-Broken Access Control
Server Side Request Forgery (SSRF) go_injection_rule-ssrf, CWE-918 Severity: Medium

Server-Side-Request-Forgery (SSRF) exploits backend systems that initiate requests to third parties. If user input is used in constructing or sending these requests, an attacker could supply malicious data to force the request to other systems or modify request data to cause unwanted actions.

Ensure user input is not used directly in constructing URLs or URIs when initiating requests to third party systems from back end systems. Care must also be taken when constructing payloads using user input. Where possible restrict to known URIs or payloads. Consider using a server side map where key's are used to return URLs such as https://site/goto?key=1 where {key: 1, url: 'http://some.url/', key: 2, url:
'http://...'}
.

If you must use user supplied input for requesting URLs, it is strongly recommended that the HTTP client chosen allows you to customize and block certain IP ranges at the network level. By blocking RFC 1918
addresses or other network address ranges, you can limit the severity of a successful SSRF attack. Care must also be taken to block certain protocol or address formatting such as IPv6.

If you can not block address ranges at the client level, you may want to run the HTTP client as a protected user, or in a protected network where you can apply IP Table or firewall rules to block access to dangerous addresses. Finally, if none of the above protections are available, you could also run a custom HTTP proxy and force all requests through it to handle blocking dangerous addresses.

Example HTTP client that disallows access to loopback and RFC-1918 addresses

// IsDisallowedIP parses the ip to determine if we should allow the HTTP client to continue func IsDisallowedIP(hostIP string) bool {
ip := net.ParseIP(hostIP)
return ip.IsMulticast() || ip.IsUnspecified() || ip.IsLoopback() || ip.IsPrivate()
}

// SafeTransport uses the net.Dial to connect, then if successful check if the resolved
// ip address is disallowed. We do this due to hosts such as localhost.lol being resolvable to
// potentially malicious URLs. We allow connection only for resolution purposes. func SafeTransport(timeout time.Duration) http.Transport {
return &http.Transport{
DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
c, err := net.DialTimeout(network, addr, timeout)
if err != nil {
return nil, err
}
ip, , _ := net.SplitHostPort(c.RemoteAddr().String())
if IsDisallowedIP(ip) {
return nil, errors.New("ip address is not allowed")
}
return c, err
},
DialTLS: func(network, addr string) (net.Conn, error) {
dialer := &net.Dialer{Timeout: timeout}
c, err := tls.DialWithDialer(dialer, network, addr, &tls.Config{})
if err != nil {
return nil, err
}

ip,
, _ := net.SplitHostPort(c.RemoteAddr().String())
if IsDisallowedIP(ip) {
return nil, errors.New("ip address is not allowed")
}

err = c.Handshake()
if err != nil {
return c, err
}

return c, c.Handshake()
},
TLSHandshakeTimeout: timeout,
}
}

func httpRequest(requestUrl string) {
const clientConnectTimeout = time.Second * 10
httpClient := &http.Client{
Transport: SafeTransport(clientConnectTimeout),
}
resp, err := httpClient.Get(requestUrl)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
// work with resp
}

For more information on SSRF see OWASP: Server_Side_Request_Forgery

OWASP:*
  • A10:2021-Server-Side Request Forgery
  • A1:2017-Injection
Improper neutralization of input during web page generation ('Cross-site Scripting') go_injection_rule-template-injection, CWE-79 Severity: Medium

Cross Site Scripting (XSS) is an attack which exploits a web application or system to treat user input as markup or script code. It is important to encode the data depending on the specific context it is used in. There are at least six context types:

  • Inside HTML tags <div>context 1</div>
  • Inside attributes: <div class="context 2"></div>
  • Inside event attributes <button onclick="context 3">button</button>
  • Inside script blocks: <script>var x = "context 4"</script>
  • Unsafe element HTML assignment: element.innerHTML = "context 5"
  • Inside URLs: <iframe src="context 6"></iframe><a href="context 6">link</a>

Script blocks alone have multiple ways they need to be encoded. Extra care must be taken if user input is ever output inside of script tags.

User input that is displayed within the application must be encoded, sanitized or validated to ensure it cannot be treated as HTML or executed as Javascript code. Care must also be taken to not mix server-side templating with client-side templating, as the server-side templating will not encode things like {{ 77 }} which may execute client-side templating features.

It is NOT advised to encode user input prior to inserting into a data store. The data will need to be encoded depending on context of where it is output. It is much safer to force the displaying system to handle the encoding and not attempt to guess how it should be encoded.

Use of the following template types with user input denotes a security risk:

Either remove these types from the application or hardcode as const strings prior to conversion:

testTemplate, err := template.New("testTemplate").Funcs(template.FuncMap{
"SafeHTML": func() template.HTML {
const safeHTML = "<div>hardcoded, safe html</div>"
return template.HTML(safeHTML)
},
}).Parse(&lt;html&gt;&lt;body&gt;{{ SafeHTML }}&lt;/body&gt;)
if err != nil {
log.Fatal(err)
}

if err := testTemplate.Execute(os.Stdout, nil); err != nil {
log.Fatal(err)
}
OWASP:*
  • A03:2021-Injection
  • A1:2017-Injection
Active debug code (pprof enabled) go_leak_rule-pprof-endpoint, CWE-489 Severity: Medium

Go has a built in profiling service that is enabled by starting an HTTP server with
net/http/pprof imported. The /debug/pprof endpoint does not require any authentication and can be accessed by anonymous users. This profiling endpoint can leak sensitive information and should not be enabled in production.

To remediate this, remove the net/http/pprof import from the file.

OWASP:
  • A05:2021-Security Misconfiguration
  • A6:2017-Security Misconfiguration
Integer overflow or wraparound go_memory_rule-integer-overflow, CWE-190 Severity: Medium

Golang's int type size depends on the architecture of where the application is running. For
32-bit systems, int is
32-bit, for 64-bit systems, int will be 64-bit. By calling strconv.Atoi with a large number, the integer may overflow if the int return value is type converted into a smaller type (int32 or int16). This could cause unexpected application behavior depending on how the resultant value is used.

Prior to running any type conversion, check that the value returned from strconv.Atoi will fit in the resulting integer.

Example of checking the return value before type conversion:

bigValue, _ := strconv.Atoi("32768")
if bigValue > math.MaxInt16 {
log.Fatal("value too large to fit in int16")
}
value := int16(bigValue)
fmt.Println(value)

For more information on integer min/max constants see: math

OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Allocation of resources without limits or throttling go_http_rule-http-serve, CWE-770 Severity: Low

Go's net/http serve functions may be vulnerable to resource consumption attacks if timeouts are not properly configured prior to starting the HTTP server. An adversary may open up thousands of connections but never complete sending all data, or never terminate the connections. This may lead to the server no longer accepting new connections.

To protect against this style of resource consumption attack, timeouts should be set in the
net/http server prior to calling the listen or serve functions. What this means is that the default http.ListenAndServe and
http.Serve functions should not be used in a production setting as they are unable to have timeouts configured. Instead a custom http.Server object must be created with the timeouts configured.

Example setting timeouts on a net/http server:

// All values chosen below are dependent on application logic and
// should be tailored per use-case srv := &http.Server{
Addr: "localhost:8000",
// ReadHeaderTimeout is the amount of time allowed to read
// request headers. The connection's read deadline is reset
// after reading the headers and the Handler can decide what
// is considered too slow for the body. If ReadHeaderTimeout
// is zero, the value of ReadTimeout is used. If both are
// zero, there is no timeout.
ReadHeaderTimeout: 15 * time.Second,

// ReadTimeout is the maximum duration for reading the entire
// request, including the body. A zero or negative value means
// there will be no timeout.
//
// Because ReadTimeout does not let Handlers make per-request
// decisions on each request body's acceptable deadline or
// upload rate, most users will prefer to use
// ReadHeaderTimeout. It is valid to use them both.
ReadTimeout: 15 * time.Second,

// WriteTimeout is the maximum duration before timing out
// writes of the response. It is reset whenever a new
// request's header is read. Like ReadTimeout, it does not
// let Handlers make decisions on a per-request basis.
// A zero or negative value means there will be no timeout.
WriteTimeout: 10 * time.Second,

// IdleTimeout is the maximum amount of time to wait for the
// next request when keep-alives are enabled. If IdleTimeout
// is zero, the value of ReadTimeout is used. If both are
// zero, there is no timeout.
IdleTimeout: 30 * time.Second,
}

// For per request timeouts applications can wrap all http.HandlerFunc(...) in
// `http.TimeoutHandler`` and specify a timeout, but note the TimeoutHandler does not
// start ticking until all headers have been read.

// Listen with our custom server with timeouts configured if err := srv.ListenAndServe(); err != nil {
log.Fatal(err)
}

For more information on the http.Server timeouts, see: http

For information on setting request based timeouts, see: http

For more information on the Slowloris attack see: Slowloris_(computer_security)

OWASP:
  • A05:2021-Security Misconfiguration
  • A6:2017-Security Misconfiguration
Binding to an unrestricted IP address go_network_rule-bind-to-all-interfaces, CWE-1327 Severity: Low

Binding to all network interfaces can potentially open up a service to traffic on unintended interfaces, that may not be properly documented or secured. By passing "0.0.0.0" as the address to the Listen family of functions, the application will bind to all interfaces.

Consider passing in the interface ip address through an environment variable, configuration file, or by determining the primary interface(s) IP address.

Example getting the IP address from an environment variable IP_ADDRESS:

addr := os.Getenv("IP_ADDRESS")
listener, err := net.Listen("tcp", addr)
if err != nil {
log.Fatal(err)
}
OWASP:
  • A05:2021-Security Misconfiguration
  • A6:2017-Security Misconfiguration
Incorrect access of indexable resource ('Range Error') go_memory_rule-memoryaliasing, CWE-118 Severity: Info

Go's for ... range statements create an iteration variable for each iteration of the loop. By taking the address of this iteration variable, the value of the address will be re-used and always point to the same location in memory. This can have unexpected behavior if the address is stored or re-used.

This can be fixed by:
- Not referencing the address of the variable
- Re-assigning the iteration variable to a new variable
- Using the address of the indexed variable

Example not referencing the address:

type someStruct struct {
x int
}

for , n := range []someStruct{{1}, {2}, {3}, {4}} {
fmt.Printf("%d\n", n.x)
}

Example reassigning the iteration variable to a new variable:

type someStruct struct {
x int
}

for
, n := range []someStruct{{1}, {2}, {3}, {4}} {
p := n
fmt.Printf("%p\n", &p)
}

Example using the address of the indexed variable:

type someStruct struct {
x int
}

structData := []someStruct{{1}, {2}, {3}, {4}}
for idx := range structData {
fmt.Printf("%p\n", &structData[idx])
}

For more information on how the for ... range statement works see: spec

OWASP:
  • A05:2021-Security Misconfiguration
  • A6:2017-Security Misconfiguration

html

Name Identifiers Description
Improper neutralization of user input rendered in HTML ('XSS') html_django_rule_reflected_xss, CWE-79 Severity: High

Global disabling of autoescape in Django HTML Template with {% autoescape off/None %} can lead to reflected XSS attacks if a user controlled input is used in the template.
Cancelling escaping of a user controlled variable with | escapejs or | safe can lead to XSS attacks, as the variable can contain javascript code and would be executed. Make sure not to use escapejs on user-controlled variables.
Always use quotes ("..." or '...') around template variables in HTML attributes, so that Django's auto-escaping will HTML-escape the value: '{{variable}}'

OWASP:
  • A03:2021-Injection
  • A7:2017-Cross-Site Scripting (XSS)
Improper neutralization of user input rendered in HTML ('XSS') html_generic_rule_reflected_xss, CWE-79 Severity: High

User controlled variable in <script> tags get executed in document.write() or eval() methods, leading to XSS vulnerability.
User controlled variable gets executed with .innerHTML and .outerHTML, leading to XSS vulnerability. User controlled variable in CSS <style> can be executed with :expression().
It can also be executed if written in backsticks ``.
A url in (href|src|action|data|http-equiv|style|background-image) can lead to XSS attacks if containing user controlled input and if not properly sanitized. Make sure to sanitize the user controlled urls in python using django.utils.http.urlencode to mitigate XSS vulnerability.
Before using a user controlled variable in these functions, make sure to escape it in python using django.utils.html.escapejs. Avoid as much as possible using this dangerous methods.

OWASP:
  • A03:2021-Injection
  • A7:2017-Cross-Site Scripting (XSS)
Improper neutralization of user input rendered in HTML ('XSS') html_tornado_rule_reflected_xss, CWE-79 Severity: High

Global disabling of autoescaping in Tornado HTML templates with {% autoescape None %} can lead to XSS attack if the template contains user-controlled input. Avoid global unescaping, prefer disabling locally.
{% raw ... %} and {{! ... }} disable HTML auto escaping. Make sure not to use it on user controlled inputs.

OWASP:
  • A03:2021-Injection
  • A7:2017-Cross-Site Scripting (XSS)

java

Name Identifiers Description
Use of hard-coded password java_password_rule-ConstantDBPassword, CWE-259 Severity: Critical

A potential hard-coded password was identified in a database connection string. Passwords should not be stored directly in code but loaded from secure locations such as a Key Management System (KMS).

The purpose of using a Key Management System is so access can be audited and keys easily rotated in the event of a breach. By hardcoding passwords, it will be extremely difficult to determine when or if, a key is compromised.

The recommendation on which KMS to use depends on the environment the application is running in:

OWASP:
  • A07:2021-Identification and Authentication Failures
  • A2:2017-Broken Authentication
Missing authentication for critical function (database) java_password_rule-EmptyDBPassword, CWE-306 Severity: Critical

The application does not provide authentication when communicating a database server. It is strongly recommended that the database server be configured with authentication and restrict what queries users can execute.

Please see your database server's documentation on how to configure a password.

Additionally, passwords should not be stored directly in code but loaded from secure locations such as a Key Management System (KMS).

The purpose of using a Key Management System is so access can be audited and keys easily rotated in the event of a breach. By hardcoding passwords, it will be extremely difficult to determine when or if, a key is compromised.

The recommendation on which KMS to use depends on the environment the application is running in:

OWASP:
  • A07:2021-Identification and Authentication Failures
  • A2:2017-Broken Authentication
Exposed dangerous method or function rules_lgpl_java_webview_rule-webview-external-storage, CWE-749 Severity: Critical

WebView load files from external storage. Files in external storage can be modified by any application.

Loading files from external storage in a WebView can introduce security risks,
as it allows web content to access potentially sensitive data stored on the
device's external storage. This can lead to unauthorized access to user data,
including personal files, credentials, or other sensitive information, by
malicious web content.

To fix this security issue, you should avoid loading files directly from external
storage in a WebView. Instead, you should use a Content Provider or a secure file
storage mechanism to access files and provide them to the WebView as content.

Here's a general approach to fix this problem:
(1) Use a Content Provider: If you need to load files from external storage in a WebView,
consider using a Content Provider to securely access the files. Content Providers
provide controlled access to files stored on external storage and allow you to define
permissions for accessing them.
(2) Secure File Storage: Store files containing sensitive data in a secure location, such
as internal storage or encrypted storage, and provide access to them through a secure
API. Avoid exposing sensitive files directly to the WebView.
(3) Restrict WebView Access: Configure the WebView to restrict access to external resources
and content. Use methods like setAllowFileAccess() to control file access and
setAllowContentAccess() to control access to content from other origins. Here's an example of how you can use a Content Provider to provide secure access to
files in a WebView:

// Define the URI of the content provider for accessing files Uri contentProviderUri = Uri.parse("content://com.example.myapp.provider/files");
// Load the content from the Content Provider into the WebView webView.loadUrl(contentProviderUri.toString());

In the above code, we define the URI of a Content Provider that provides access to files
stored in the app's external storage. The content is loaded from the Content Provider into
the WebView using loadUrl(), which ensures that access to files is controlled and secure,
preventing unauthorized access to sensitive data.

OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Improper neutralization of CRLF sequences in HTTP headers ('HTTP Response Splitting') java_cookie_rule-HttpResponseSplitting, CWE-113 Severity: High

HTTP Response Splitting is a vulnerability where Carriage Return (CR \r) and Line Feed (LF
\n)
characters are introduced into an HTTP header from user-supplied input. By injecting the
\r\n
character sequence, an adversary could potentially modify how the response is interpreted by the client or any downstream caching services. This could allow an adversary to poison the cache data or execute Cross-Site Scripting (XSS) attacks.

Some Java application servers such as Apache Tomcat as of version
8.0, newer versions of Jetty and other servers that implement the RFC 6265 Standard will disallow \r' and '\n characters characters from being set in cookies. If your application server does not automatically provide this functionality, user-supplied input that is used in cookie keys or values must be validated.

Example of validating cookies to only allow valid characters:

// throws an IllegalArgumentException if the provided value contains invalid characters public void validateRfc6265CookieValue(String value) throws IllegalArgumentException {
char[] chars = value.toCharArray();

// iterate over every character
for (int i = 0; i < chars.length; i++) {
char c = chars[i];

// check for any characters below 0x21 as well as: '"' ',' ';' '\' and 0x7f.
if (c < 0x21 || c == '"' || c == ',' || c == ';' || c == '\' || c == 0x7f) {
throw new IllegalArgumentException("Invalid character in cookie detected:
{0}".format(Integer.toString(c)));
}
}
}

Alternatively, you could use a string escape package such as
Apache Commons Text to escape the input:

public String escapeValue(String value) {
return StringEscapeUtils.escapeJava(value);
}

For more information on response splitting attacks see OWASP: HTTP_Response_Splitting

OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Improper neutralization of CRLF sequences in HTTP headers ('HTTP Response Splitting') java_cookie_rule-RequestParamToHeader, CWE-113 Severity: High

HTTP Response Splitting is a vulnerability where Carriage Return (CR \r) and Line Feed (LF
\n)
characters are introduced into an HTTP header from user-supplied input. By injecting the
\r\n
character sequence, an adversary could potentially modify how the response is interpreted by the client or any down stream caching services. This could allow an adversary to poison the cache data or execute Cross-Site Scripting (XSS) attacks.

Some Java application servers such as Apache Tomcat will automatically encode characters from being set in response headers as a space 0x20 character. If your application server does not automatically provide this functionality, user-supplied input that is used in header keys or values must be validated.

Example of validating headers to only allow valid characters:

// throws an IllegalArgumentException if the provided value contains invalid characters public void validateHeader(String value) throws IllegalArgumentException {
char[] chars = value.toCharArray();

// iterate over every character
for (int i = 0; i < chars.length; i++) {
char c = chars[i];

// check for any characters below 0x21 as well as: '"' ',' ';' '\' and 0x7f.
if (c < 0x21 || c == '"' || c == ',' || c == ';' || c == '\' || c == 0x7f) {
throw new IllegalArgumentException("Invalid character in cookie detected:
{0}".format(Integer.toString(c)));
}
}
}

Alternatively, you could use a string escape package such as
Apache Commons Text to escape the input:

public String escapeValue(String value) {
return StringEscapeUtils.escapeJava(value);
}

For more information on response splitting attacks see OWASP: HTTP_Response_Splitting

OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Improper neutralization of special elements used in an OS command ('OS Command Injection') java_inject_rule-CommandInjection, CWE-78 Severity: High

OS command injection is a critical vulnerability that can lead to a full system compromise as it may allow an adversary to pass in arbitrary commands or arguments to be executed.

User input should never be used in constructing commands or command arguments to functions which execute OS commands. This includes filenames supplied by user uploads or downloads.

Ensure your application does not:

  • Use user-supplied information in the process name to execute.
  • Use user-supplied information in an OS command execution function which does not escape shell meta-characters.
  • Use user-supplied information in arguments to OS commands.

The application should have a hardcoded set of arguments that are to be passed to OS commands. If filenames are being passed to these functions, it is recommended that a hash of the filename be used instead, or some other unique identifier. It is strongly recommended that a native library that implements the same functionality be used instead of using OS system commands, due to the risk of unknown attacks against third party commands.

When specifying the OS command, ensure the application uses the full path information, otherwise the OS may attempt to look up which process to execute and could be vulnerable to untrusted search path vulnerabilities (CWE-426).

Example of safely executing an OS command:

public static void executeCommand(String userFileData) throws java.io.IOException {
// Generate a random filename, do not use user input
String fileName = UUID.randomUUID().toString();
// Create a Buffered/FileWriter
BufferedWriter writer = new BufferedWriter(new FileWriter(fileName));
// Write the user content to our random file
writer.write(userFileData);
// Close the file to flush contents
writer.close();
// Create the process builder with a hardcoded path to the binary, and our randomly generated filename
ProcessBuilder processBuilder = new ProcessBuilder("/opt/app/path", fileName);
// Start the process
Process process = processBuilder.start();
// Handle/redirect output of process here
// ...
}

For more information on OS command injection, see OWASP's guide: OS_Command_Injection_Defense_Cheat_Sheet.html

OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Files or directories accessible to external parties java_inject_rule-FileDisclosureRequestDispatcher, CWE-552 Severity: High

The HttpRequest.getRequestDispatcher()'s include and forward methods will return any file that is resolvable within the web application context. This includes the web.xml
file, any compiled classes, jsp files, and additional JAR or WAR libraries that are accessible.

Never pass user-supplied input directly to any of these methods. Use a lookup table or hardcode which views or paths the user should be directed to. Another option is to use a simple HTTP redirect by returning an empty response body with a 301 status code and a Location redirect header. In Java servlets, this can be done by using the response.sendRedirect(...) method.

Example using a redirect instead of a RequestDispatcher:

// Create a look up table or pull from a data source HashMap<String, String> lookupTable = new HashMap<>();
lookupTable.put("key1", "/Resource1");
lookupTable.put("key2", "/Resource2");
// Get user input String userInput = request.getParameter("key");
// Look up resource to redirect to from the user input String redirectValue = lookupTable.getOrDefault(userInput, "/Resource1");
// Redirect the user response.sendRedirect(redirectValue);
OWASP:
  • A01:2021-Broken Access Control
  • A5:2017-Broken Access Control
Files or directories accessible to external parties java_inject_rule-FileDisclosureSpringFramework, CWE-552 Severity: High

The org.springframework.web.servlet.ModelAndView class may potentially allow access to restricted files if called with user-supplied input.

The ModelAndView class looks up a view by name to resolve a .jsp
file. If this view name comes from user-supplied input, it could be abused to attempt to return a JSP view that the user should not have access to.

Use a lookup table or hardcode which views or paths the user should be directed to.

Example using a lookup table to resolve a view from a Spring MVC application:

@RequestMapping(value="/mvc", method=RequestMethod.GET)
public ModelAndView mvc(HttpServletRequest request, HttpServletResponse response, Model model)
{
// Create a look up table or pull from a data source
HashMap<String, String> lookupTable = new HashMap<>();
lookupTable.put("key1", "view1");
lookupTable.put("key2", "view2");
// Get user input
String userInput = request.getParameter("key");
// Look up view from the user input
String viewValue = lookupTable.getOrDefault(userInput, "Resource1");
// return the new model and view
return new ModelAndView(viewValue);
}

Example using a redirect instead of a RequestDispatcher in Spring:

@RequestMapping(value="/mvc", method=RequestMethod.GET)
public void mvc(HttpServletRequest request, HttpServletResponse response, Model model)
{
// Create a look up table or pull from a data source
HashMap<String, String> lookupTable = new HashMap<>();
lookupTable.put("key1", "view1");
lookupTable.put("key2", "view2");
// Get user input
String userInput = request.getParameter("key");
// Look up resource to redirect to from the user input
String redirectValue = lookupTable.getOrDefault(userInput, "/Resource1");
// return the new model and view
response.sendRedirect(redirectValue);
}
OWASP:
  • A01:2021-Broken Access Control
  • A5:2017-Broken Access Control
Expression injection (OGNL) java_inject_rule-OgnlInjection, CWE-917 Severity: High

The Object Graph Navigation Language (OGNL) is an expression language that allows access to Java objects and properties stored in an ActionContext. Usage of these low-level functions is discouraged because they can effectively execute strings as code, leading to remote code execution vulnerabilities. Consider using struts tags when processing user-supplied input and templates.

Much like the Struts security guide recommending to not use raw ${} EL expressions, do not call or use the following OGNL packages with user-supplied input:

  • com.opensymphony.xwork2.ognl
  • com.opensymphony.xwork2.util
  • com.opensymphony.xwork2.util.reflection
  • org.apache.struts2.util.StrutsUtil

For more information on Struts2 security see:

OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Missing authentication for critical function (LDAP) java_ldap_rule-AnonymousLDAP, CWE-306 Severity: High

The application does not provide authentication when communicating an LDAP server. It is strongly recommended that the LDAP server be configured with authentication and restrict what queries users can execute.

Example code that authenticates with a remote LDAP server and encodes any user-supplied input:

// Create a properties to hold the ldap connection details Properties props = new Properties();
// Use the com.sun.jndi.ldap.LdapCtxFactory factory provider props.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
// The LDAP server URL props.put(Context.PROVIDER_URL, "ldap://ldap.example.org:3889");
// User details for the connection props.put(Context.SECURITY_PRINCIPAL, "cn=admin,dc=example,dc=org");
// LDAP account password String ldapAccountPassword = getAccountPasswordFromSecureStoreOrKMS();
// Pass in the LDAP password props.put(Context.SECURITY_CREDENTIALS, ldapAccountPassword);

// Create the LDAPContext InitialDirContext ldapContext = new InitialDirContext(props);
// Example using SUBTREE_SCOPE SearchControls SearchControls searchControls = new SearchControls();
searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);

// Get user input for query String userQuery = someUserInput;
// Use searchArguments to hold the user-supplied input Object[] searchArguments = new Object[]{userQuery};
// Hardcode the BaseDN, use the {0} format specifier to use the searchArguments array value, and pass in the search controls.
// searchArguments automatically encode NamingEnumeration answer = ldapContext.search("dc=example,dc=org", "(cn={0})", searchArguments, searchControls);
// Process the response answer while (answer.hasMoreElements()) {
...
}

For information on enabling authentication, please see your LDAP server's documentation.

For more information on LDAP Injection see OWASP: LDAP_Injection_Prevention_Cheat_Sheet.html

OWASP:
  • A07:2021-Identification and Authentication Failures
  • A2:2017-Broken Authentication
Use of hard-coded password java_password_rule-HardcodePassword, CWE-259 Severity: High

A potential hard-coded password was identified in a hard-coded string. Passwords should not be stored directly in code but loaded from secure locations such as a Key Management System (KMS).

The purpose of using a Key Management System is so access can be audited and keys easily rotated in the event of a breach. By hardcoding passwords, it will be extremely difficult to determine when or if, a key is compromised.

The recommendation on which KMS to use depends on the environment the application is running in:

OWASP:
  • A07:2021-Identification and Authentication Failures
  • A2:2017-Broken Authentication
Improper control of generation of code ('Code Injection') java_script_rule-ScriptInjection, CWE-94 Severity: High

The application executes an argument using a ScriptEngine's eval method. This may allow for direct OS commands to be executed as it's possible to pass in strings such as java.lang.Runtime.getRuntime().exec('/bin/sh ...');.

Never pass user-supplied input directly to the eval function. If possible hardcode all JavasScript code or use a lookup table to resolve user input to known values. If none of these techniques are possible, use javax.script.Bindings to pass input to the script engine.

Example using Binding to safely pass in string values:

// Get ECMAScript engine ScriptEngine engine = new ScriptEngineManager().getEngineByName("ECMAScript");

// User input, consisting of first and last name String userFirstName = "John";
String userLastName = "Snow";

// Create bindings to pass into our script, forcing the values to be String. Bindings bindings = engine.createBindings();
bindings.put("fname", new String(userFirstName));
bindings.put("lname", new String(userLastName));

// Example script that concatenates a greeting with the user-supplied input first/last name String script = "var greeting='Hello ';" +
// fname and lname variables will be resolved by our bindings defined above
"greeting += fname + ' ' + lname;" +
// prints greeting
"greeting";

try {
// Execute the script, passing in the bindings
Object bindingsResult = engine.eval(script, bindings);
// Work with result
// ...
} catch (ScriptException e) {
// Handle exception
e.printStackTrace();
}
OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Improper neutralization of special elements used in an expression language statement ('Expression Language Injection') java_script_rule-SpringSpelExpressionParser, CWE-917 Severity: High

The application was found calling SpringFramework's SpelExpressionParser.parseExpression. Calling this method directly with user-supplied input may allow an adversary to execute arbitrary Java code including OS system commands.

Never call parseExpression or parseRaw directly with user-supplied input. Consider alternate methods such as a lookup table to take user input and resolve hardcoded values.

Later versions of SpringFramework introduced a SimpleEvaluationContext which can be used to access bound data when calling the getValue result of parseExpression. This
SimpleEvaluationContext has a reduced set of functionality and can restrict data binding to read-only or read-write contexts. An adversary could still access public properties or fields on custom types that have been provided to the evaluation context. Use with caution.

Example using SimpleEvaluationContext with a read-write data binding context:

@RequestMapping(value="/spel", method=RequestMethod.POST)
public String spel(@Validated User user, Model model) {
// Create the Expression Parser
SpelExpressionParser parser = new SpelExpressionParser();
// Parse the expression
Expression parsedExpression = parser.parseExpression(model.getPossiblyUnsafeData());
// Create the read-write data binding context
SimpleEvaluationContext context = SimpleEvaluationContext.forReadWriteDataBinding().build();
// Execute the expression, passing in the read-write context
Object result = parsedExpression.getValue(context);
// work with the result
// ...
return "user";
}

For more information on SimpleEvaluationContext see: SimpleEvaluationContext.html

OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Improper control of generation of code ('Code Injection') java_templateinjection_rule-TemplateInjection, CWE-94 Severity: High

The application may allow control over a template string. Providing user input directly in the template by dynamically creating template strings may allow an adversary to execute arbitrary Java code, including OS system commands.

For Velocity, never call evaluate with user-supplied input in the template string. Use a
VelocityContext
object instead to data-bind user-supplied information as it will be treated as an underlying data type and not template code.

Example using Apache Velocity's VelocityContext and escape tools to pass in user-supplied data to a template:

// Create a tool manager ToolManager manager = new ToolManager(true);
// Create a context from the tool manager Context context = manager.createContext();
// For demonstration purposes, alternatively configure from a properties file context.put("esc", new EscapeTool());
// For demonstration purposes, create an output buffer StringWriter stringWriter = new StringWriter();
// Get userInput String userInput = "potentially malicious data";
// Use the context to pass in the userInput value context.put("userInput", userInput);
// Pass in the context, the output buffer, a logtag (demo), and the template with userInput
// making sure to escape it if in the context of HTML. Velocity.evaluate(context, stringWriter, "demo", "Hello $esc.html($userInput)");
// Work with the output buffer
// ...

For other templating engines, please see your framework's documentation.

OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Deserialization of untrusted data java_xml_rule-XmlDecoder, CWE-502 Severity: High

Deserialization attacks exploit the process of reading serialized data and turning it back into an object. By constructing malicious objects and serializing them, an adversary may attempt to:

  • Inject code that is executed upon object construction, which occurs during the deserialization process.
  • Exploit mass assignment by including fields that are not normally a part of the serialized data but are read in during deserialization.

Consider safer alternatives such as serializing data in the JSON format. Ensure any format chosen allows the application to specify exactly which object types are allowed to be deserialized. Additionally, when deserializing, never deserialize to base object types like Object and only cast to the exact object type that is expected.

To protect against mass assignment, only allow deserialization of the specific fields that are required. If this is not easily done, consider creating an intermediary type that can be serialized with only the necessary fields exposed.

Do note that XMLEncoder and XMLDecoder are not recommended. If the application must use this serialization method, use a custom ClassLoader to prevent loading of arbitrary classes:

XMLDecoder decoder = new XMLDecoder(inputStream, null, null, new ClassLoader() {
@Override
protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
if (!name.equals(NameOfBeanHere.class.getName()) &&
!name.equals(XMLDecoder.class.getName())) {
throw new RuntimeException("Unauthorized deserialization attempt: " + name);
}

return super.loadClass(name, resolve);
}
});

For more information on XML security see OWASP's guide: XML_External_Entity_Prevention_Cheat_Sheet.html

For more details on deserialization attacks in general, see OWASP's guide: Deserialization_Cheat_Sheet.html

It should be noted that tools exist to automatically create exploit code for these vulnerabilities.

OWASP:
  • A08:2021-Software and Data Integrity Failures
  • A8:2017-Insecure Deserialization
Inadequate encryption strength java_crypto_rule-BlowfishKeySize, CWE-326 Severity: Medium

The Blowfish encryption algorithm was meant as a drop-in replacement for DES and was created in
1993. Smaller key sizes may make the ciphertext vulnerable to birthday attacks. While no known attacks against Blowfish exist, it should never be used to encrypt files over 4GB in size. If possible consider using AES as the instance of KeyGenerator instead of Blowfish.

To remediate the small key size, pass a value such as 256 to the KeyGenerator.init(keySize)
method.

Example setting a larger key size and changing to KeyGenerator to AES:

public static void aesKeyGenerator() throws java.security.NoSuchAlgorithmException {
// Use the AES algorithm for key generation
KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");

// Set the key size here
keyGenerator.init(256);

// get the raw bytes of the key
byte[] key = keyGenerator.generateKey().getEncoded();

// pass the key bytes to create a SecretKeySpec
SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES");
}

Example setting a larger key size for Blowfish:

public static void blowFishKeyGenerator() throws java.security.NoSuchAlgorithmException {
// Use the Blowfish algorithm for key generation
KeyGenerator keyGenerator = KeyGenerator.getInstance("Blowfish");

// Set the key size here
keyGenerator.init(256);

// get the raw bytes of the key
byte[] key = keyGenerator.generateKey().getEncoded();

// pass the key bytes to create a SecretKeySpec
SecretKeySpec secretKeySpec = new SecretKeySpec(key, "Blowfish");
}

For more information on Java Cryptography see: java-cryptography-architecture-jca-reference-guide.html

OWASP:
  • A02:2021-Cryptographic Failures
  • A3:2017-Sensitive Data Exposure
Inadequate encryption strength java_crypto_rule-CipherDESInsecure, CWE-326 Severity: Medium

DES, TripleDES and RC2 are all considered broken or insecure cryptographic algorithms. Newer algorithms apply message integrity to validate ciphertext has not been tampered with. Consider using ChaCha20Poly1305 instead as it is easier and faster than the alternatives such as AES-256-GCM.

For older applications that don't have support for ChaCha20Poly1305,
AES-256-GCM is recommended, however it has many drawbacks:
- Slower than ChaCha20Poly1305.
- Catastrophic failure if nonce values are reused.

Example using ChaCha20Poly1305:

public encrypt() throws Exception {
chaChaEncryption("Secret text to encrypt".getBytes(StandardCharsets.UTF_8));
}

public SecureRandom getSecureRandomDRBG() throws NoSuchAlgorithmException {
// Use DRBG according to http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-90Ar1.pdf
return SecureRandom.getInstance("DRBG",
// Security strength in bits (default is 128)
DrbgParameters.instantiation(256,
// Set prediction resistance and re-seeding
DrbgParameters.Capability.PR_AND_RESEED,
// Set the personalization string (optional, not necessary)
"some_personalization_string".getBytes()
)
);
}

public Cipher getChaCha20Poly1305(int mode, byte[] ivKey, byte[] secretKey) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException {
// Get a DRBG random number generator instance
SecureRandom random = getSecureRandomDRBG();
// Create a ChaCha20-Poly1305 cipher instance
Cipher chaChaCipher = Cipher.getInstance("ChaCha20-Poly1305/None/NoPadding");
// Create our parameterSpec using our ivKey
AlgorithmParameterSpec parameterSpec = new IvParameterSpec(ivKey);
// Create a SecretKeySpec using our secretKey
SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey, "ChaCha20");
// Initialize and return the cipher for the provided mode
chaChaCipher.init(mode, secretKeySpec, parameterSpec, random);
return chaChaCipher;
}

public void chaChaEncryption(byte[] plainText) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException {
// Get a DRBG random number generator instance
SecureRandom random = getSecureRandomDRBG();
// Create secretKey
byte[] secretKey = new byte[32];
random.nextBytes(secretKey);
// Create an IV Key
byte[] ivKey = new byte[12];
random.nextBytes(ivKey);

// Create a chaCha encryption cipher instance
Cipher chaChaEncryptor = getChaCha20Poly1305(Cipher.ENCRYPT_MODE, ivKey, secretKey);

// Encrypt the text using ChaCha20Poly1305
byte[] cipherText = null;
try {
cipherText = chaChaEncryptor.doFinal(plainText);
} catch (IllegalBlockSizeException | BadPaddingException e) {
System.out.println("failed to encrypt text");
return;
}
System.out.println("encrypted: " + Base64.getEncoder().encodeToString(cipherText));

// Create a chaCha decryption cipher instance
Cipher chaChaDecryptor = getChaCha20Poly1305(Cipher.DECRYPT_MODE, ivKey, secretKey);

// Decrypt the text
byte[] decryptedText = null;
try {
decryptedText = chaChaDecryptor.doFinal(cipherText);
} catch (IllegalBlockSizeException | BadPaddingException e) {
System.out.println("failed to decrypt text");
return;
}
System.out.println("decrypted: " + new String(decryptedText, StandardCharsets.UTF_8));
}

For more information on Java Cryptography see: java-cryptography-architecture-jca-reference-guide.html

OWASP:
  • A02:2021-Cryptographic Failures
  • A3:2017-Sensitive Data Exposure
Use of a broken or risky cryptographic algorithm java_crypto_rule-CipherDESedeInsecure, CWE-327 Severity: Medium

DES, TripleDES and RC2 are all considered broken or insecure cryptographic algorithms. Newer algorithms apply message integrity to validate ciphertext has not been tampered with. Consider using ChaCha20Poly1305 instead as it is easier and faster than the alternatives such as AES-256-GCM.

For older applications that don't have support for ChaCha20Poly1305,
AES-256-GCM is recommended, however it has many drawbacks:
- Slower than ChaCha20Poly1305.
- Catastrophic failure if nonce values are reused.

Example using ChaCha20Poly1305:

public encrypt() throws Exception {
chaChaEncryption("Secret text to encrypt".getBytes(StandardCharsets.UTF_8));
}

public SecureRandom getSecureRandomDRBG() throws NoSuchAlgorithmException {
// Use DRBG according to http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-90Ar1.pdf
return SecureRandom.getInstance("DRBG",
// Security strength in bits (default is 128)
DrbgParameters.instantiation(256,
// Set prediction resistance and re-seeding
DrbgParameters.Capability.PR_AND_RESEED,
// Set the personalization string (optional, not necessary)
"some_personalization_string".getBytes()
)
);
}

public Cipher getChaCha20Poly1305(int mode, byte[] nonceKey, byte[] secretKey) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException {
// Get a DRBG random number generator instance
SecureRandom random = getSecureRandomDRBG();
// Create a ChaCha20-Poly1305 cipher instance
Cipher chaChaCipher = Cipher.getInstance("ChaCha20-Poly1305/None/NoPadding");
// Create our parameterSpec using our nonceKey
AlgorithmParameterSpec parameterSpec = new IvParameterSpec(nonceKey);
// Create a SecretKeySpec using our secretKey
SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey, "ChaCha20");
// Initialize and return the cipher for the provided mode
chaChaCipher.init(mode, secretKeySpec, parameterSpec, random);
return chaChaCipher;
}

public void chaChaEncryption(byte[] plainText) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException {
// Get a DRBG random number generator instance
SecureRandom random = getSecureRandomDRBG();
// Create secretKey
byte[] secretKey = new byte[32];
random.nextBytes(secretKey);
// Create an IV nonceKey
byte[] nonceKey = new byte[12];
random.nextBytes(nonceKey);
// Create a chaCha encryption cipher instance
Cipher chaChaEncryptor = getChaCha20Poly1305(Cipher.ENCRYPT_MODE, nonceKey, secretKey);
// Encrypt the text using ChaCha20Poly1305
byte[] cipherText = null;
try {
cipherText = chaChaEncryptor.doFinal(plainText);
} catch (IllegalBlockSizeException | BadPaddingException e) {
System.out.println("failed to encrypt text");
return;
}
System.out.println("encrypted: " + Base64.getEncoder().encodeToString(cipherText));
// Create a chaCha decryption cipher instance
Cipher chaChaDecryptor = getChaCha20Poly1305(Cipher.DECRYPT_MODE, nonceKey, secretKey);
// Decrypt the text
byte[] decryptedText = null;
try {
decryptedText = chaChaDecryptor.doFinal(cipherText);
} catch (IllegalBlockSizeException | BadPaddingException e) {
System.out.println("failed to decrypt text");
return;
}
System.out.println("decrypted: " + new String(decryptedText, StandardCharsets.UTF_8));
}

For more information on Java Cryptography see: java-cryptography-architecture-jca-reference-guide.html

OWASP:
  • A02:2021-Cryptographic Failures
  • A3:2017-Sensitive Data Exposure
Use of a broken or risky cryptographic algorithm java_crypto_rule-CipherECBMode, CWE-327 Severity: Medium

Cryptographic algorithms provide many different modes of operation, only some of which provide message integrity. Without message integrity it could be possible for an adversary to attempt to tamper with the ciphertext which could lead to compromising the encryption key. Newer algorithms apply message integrity to validate ciphertext has not been tampered with.

Instead of using an algorithm that requires configuring a cipher mode, an algorithm that has built-in message integrity should be used. Consider using ChaCha20Poly1305 or
AES-256-GCM instead.

For older applications that don't have support for ChaCha20Poly1305, AES-256-GCM is recommended, however it has many drawbacks:
- Slower than ChaCha20Poly1305.
- Catastrophic failure if nonce values are reused.

Example using ChaCha20Poly1305:

public encrypt() throws Exception {
chaChaEncryption("Secret text to encrypt".getBytes(StandardCharsets.UTF_8));
}

public SecureRandom getSecureRandomDRBG() throws NoSuchAlgorithmException {
// Use DRBG according to http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-90Ar1.pdf
return SecureRandom.getInstance("DRBG",
// Security strength in bits (default is 128)
DrbgParameters.instantiation(256,
// Set prediction resistance and re-seeding
DrbgParameters.Capability.PR_AND_RESEED,
// Set the personalization string (optional, not necessary)
"some_personalization_string".getBytes()
)
);
}

public Cipher getChaCha20Poly1305(int mode, byte[] ivKey, byte[] secretKey) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException {
// Get a DRBG random number generator instance
SecureRandom random = getSecureRandomDRBG();
// Create a ChaCha20-Poly1305 cipher instance
Cipher chaChaCipher = Cipher.getInstance("ChaCha20-Poly1305/None/NoPadding");
// Create our parameterSpec using our ivKey
AlgorithmParameterSpec parameterSpec = new IvParameterSpec(ivKey);
// Create a SecretKeySpec using our secretKey
SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey, "ChaCha20");
// Initialize and return the cipher for the provided mode
chaChaCipher.init(mode, secretKeySpec, parameterSpec, random);
return chaChaCipher;
}

public void chaChaEncryption(byte[] plainText) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException {
// Get a DRBG random number generator instance
SecureRandom random = getSecureRandomDRBG();
// Create secretKey
byte[] secretKey = new byte[32];
random.nextBytes(secretKey);
// Create an IV Key
byte[] ivKey = new byte[12];
random.nextBytes(ivKey);

// Create a chaCha encryption cipher instance
Cipher chaChaEncryptor = getChaCha20Poly1305(Cipher.ENCRYPT_MODE, ivKey, secretKey);

// Encrypt the text using ChaCha20Poly1305
byte[] cipherText = null;
try {
cipherText = chaChaEncryptor.doFinal(plainText);
} catch (IllegalBlockSizeException | BadPaddingException e) {
System.out.println("failed to encrypt text");
return;
}
System.out.println("encrypted: " + Base64.getEncoder().encodeToString(cipherText));

// Create a chaCha decryption cipher instance
Cipher chaChaDecryptor = getChaCha20Poly1305(Cipher.DECRYPT_MODE, ivKey, secretKey);

// Decrypt the text
byte[] decryptedText = null;
try {
decryptedText = chaChaDecryptor.doFinal(cipherText);
} catch (IllegalBlockSizeException | BadPaddingException e) {
System.out.println("failed to decrypt text");
return;
}
System.out.println("decrypted: " + new String(decryptedText, StandardCharsets.UTF_8));
}

For more information on Java Cryptography see: java-cryptography-architecture-jca-reference-guide.html

OWASP:
  • A02:2021-Cryptographic Failures
  • A3:2017-Sensitive Data Exposure
Use of a broken or risky cryptographic algorithm java_crypto_rule-CipherIntegrity, CWE-327 Severity: Medium

Cryptographic algorithms provide many different modes of operation, only some of which provide message integrity. Without message integrity it could be possible for an adversary to attempt to tamper with the ciphertext which could lead to compromising the encryption key. Newer algorithms apply message integrity to validate ciphertext has not been tampered with.

Instead of using an algorithm that requires configuring a cipher mode, an algorithm that has built-in message integrity should be used. Consider using ChaCha20Poly1305 or
AES-256-GCM instead.

For older applications that don't have support for ChaCha20Poly1305, AES-256-GCM is recommended, however it has many drawbacks:
- Slower than ChaCha20Poly1305.
- Catastrophic failure if nonce values are reused.

Example using ChaCha20Poly1305:

public encrypt() throws Exception {
chaChaEncryption("Secret text to encrypt".getBytes(StandardCharsets.UTF_8));
}

public SecureRandom getSecureRandomDRBG() throws NoSuchAlgorithmException {
// Use DRBG according to http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-90Ar1.pdf
return SecureRandom.getInstance("DRBG",
// Security strength in bits (default is 128)
DrbgParameters.instantiation(256,
// Set prediction resistance and re-seeding
DrbgParameters.Capability.PR_AND_RESEED,
// Set the personalization string (optional, not necessary)
"some_personalization_string".getBytes()
)
);
}

public Cipher getChaCha20Poly1305(int mode, byte[] ivKey, byte[] secretKey) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException {
// Get a DRBG random number generator instance
SecureRandom random = getSecureRandomDRBG();
// Create a ChaCha20-Poly1305 cipher instance
Cipher chaChaCipher = Cipher.getInstance("ChaCha20-Poly1305/None/NoPadding");
// Create our parameterSpec using our ivKey
AlgorithmParameterSpec parameterSpec = new IvParameterSpec(ivKey);
// Create a SecretKeySpec using our secretKey
SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey, "ChaCha20");
// Initialize and return the cipher for the provided mode
chaChaCipher.init(mode, secretKeySpec, parameterSpec, random);
return chaChaCipher;
}

public void chaChaEncryption(byte[] plainText) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException {
// Get a DRBG random number generator instance
SecureRandom random = getSecureRandomDRBG();
// Create secretKey
byte[] secretKey = new byte[32];
random.nextBytes(secretKey);
// Create an IV Key
byte[] ivKey = new byte[12];
random.nextBytes(ivKey);

// Create a chaCha encryption cipher instance
Cipher chaChaEncryptor = getChaCha20Poly1305(Cipher.ENCRYPT_MODE, ivKey, secretKey);

// Encrypt the text using ChaCha20Poly1305
byte[] cipherText = null;
try {
cipherText = chaChaEncryptor.doFinal(plainText);
} catch (IllegalBlockSizeException | BadPaddingException e) {
System.out.println("failed to encrypt text");
return;
}
System.out.println("encrypted: " + Base64.getEncoder().encodeToString(cipherText));

// Create a chaCha decryption cipher instance
Cipher chaChaDecryptor = getChaCha20Poly1305(Cipher.DECRYPT_MODE, ivKey, secretKey);

// Decrypt the text
byte[] decryptedText = null;
try {
decryptedText = chaChaDecryptor.doFinal(cipherText);
} catch (IllegalBlockSizeException | BadPaddingException e) {
System.out.println("failed to decrypt text");
return;
}
System.out.println("decrypted: " + new String(decryptedText, StandardCharsets.UTF_8));
}

For more information on Java Cryptography see: java-cryptography-architecture-jca-reference-guide.html

OWASP:
  • A02:2021-Cryptographic Failures
  • A3:2017-Sensitive Data Exposure
Use of a broken or risky cryptographic algorithm java_crypto_rule-CipherPaddingOracle, CWE-327 Severity: Medium

Cryptographic block ciphers can be configured to pad individual blocks if there is not enough input data to match the size of the block. This specific mode of CBC used in combination with PKCS5Padding is susceptible to padding oracle attacks. An adversary could potentially decrypt the message if the system exposed the difference between plaintext with invalid padding or valid padding. The distinction between valid and invalid padding is usually revealed through distinct error messages being returned for each condition.

Consider switching to a more secure cipher that doesn't require padding and builds in message authentication integrity directly into the algorithm.

Consider using ChaCha20Poly1305 or
AES-256-GCM instead.

For older applications that don't have support for ChaCha20Poly1305, AES-256-GCM is recommended, however it has many drawbacks:
- Slower than ChaCha20Poly1305.
- Catastrophic failure if nonce values are reused.

Example using ChaCha20Poly1305:

public encrypt() throws Exception {
chaChaEncryption("Secret text to encrypt".getBytes(StandardCharsets.UTF_8));
}

public SecureRandom getSecureRandomDRBG() throws NoSuchAlgorithmException {
// Use DRBG according to http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-90Ar1.pdf
return SecureRandom.getInstance("DRBG",
// Security strength in bits (default is 128)
DrbgParameters.instantiation(256,
// Set prediction resistance and re-seeding
DrbgParameters.Capability.PR_AND_RESEED,
// Set the personalization string (optional, not necessary)
"some_personalization_string".getBytes()
)
);
}

public Cipher getChaCha20Poly1305(int mode, byte[] ivKey, byte[] secretKey) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException {
// Get a DRBG random number generator instance
SecureRandom random = getSecureRandomDRBG();
// Create a ChaCha20-Poly1305 cipher instance
Cipher chaChaCipher = Cipher.getInstance("ChaCha20-Poly1305/None/NoPadding");
// Create our parameterSpec using our ivKey
AlgorithmParameterSpec parameterSpec = new IvParameterSpec(ivKey);
// Create a SecretKeySpec using our secretKey
SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey, "ChaCha20");
// Initialize and return the cipher for the provided mode
chaChaCipher.init(mode, secretKeySpec, parameterSpec, random);
return chaChaCipher;
}

public void chaChaEncryption(byte[] plainText) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException {
// Get a DRBG random number generator instance
SecureRandom random = getSecureRandomDRBG();
// Create secretKey
byte[] secretKey = new byte[32];
random.nextBytes(secretKey);
// Create an IV Key
byte[] ivKey = new byte[12];
random.nextBytes(ivKey);

// Create a chaCha encryption cipher instance
Cipher chaChaEncryptor = getChaCha20Poly1305(Cipher.ENCRYPT_MODE, ivKey, secretKey);

// Encrypt the text using ChaCha20Poly1305
byte[] cipherText = null;
try {
cipherText = chaChaEncryptor.doFinal(plainText);
} catch (IllegalBlockSizeException | BadPaddingException e) {
System.out.println("failed to encrypt text");
return;
}
System.out.println("encrypted: " + Base64.getEncoder().encodeToString(cipherText));

// Create a chaCha decryption cipher instance
Cipher chaChaDecryptor = getChaCha20Poly1305(Cipher.DECRYPT_MODE, ivKey, secretKey);

// Decrypt the text
byte[] decryptedText = null;
try {
decryptedText = chaChaDecryptor.doFinal(cipherText);
} catch (IllegalBlockSizeException | BadPaddingException e) {
System.out.println("failed to decrypt text");
return;
}
System.out.println("decrypted: " + new String(decryptedText, StandardCharsets.UTF_8));
}

For more information on padding oracle attacks see: Padding_oracle_attack

For more information on Java Cryptography see: java-cryptography-architecture-jca-reference-guide.html

OWASP:
  • A02:2021-Cryptographic Failures
  • A3:2017-Sensitive Data Exposure
Use of a broken or risky cryptographic algorithm java_crypto_rule-CustomMessageDigest, CWE-327 Severity: Medium

The application was found implementing a custom java.security.MessageDigest. It is strongly recommended that a standard Digest algorithm be chosen instead as implementing a digest by hand is error-prone. The National Institute of Standards and Technology (NIST) recommends the use of SHA-224, SHA-256, SHA-384, SHA-512, SHA-512/224, or SHA-512/256.

Example of creating a SHA-384 hash:

// Create a MessageDigest using the SHA-384 algorithm MessageDigest sha384Digest = MessageDigest.getInstance("SHA-384");
// Call update with your data sha384Digest.update(input);
// Only call digest once all data has been fed into the update sha384digest instance byte[] output = sha384Digest.digest();
// output base64 encoded version of the hash System.out.println("hash: " + Base64.getEncoder().encodeToString(output));
OWASP:
  • A04:2021-Insecure Design
  • A6:2017-Security Misconfiguration
Inadequate encryption strength java_crypto_rule-HazelcastSymmetricEncryption, CWE-326 Severity: Medium

The network communications for Hazelcast is configured to use a deprecated symmetric cipher. Consider using TLS/SSL when establishing communications across the Hazelcast cluster.

For more information on configuring TLS/SSL for Hazelcast see: tls-ssl

OWASP:
  • A02:2021-Cryptographic Failures
  • A3:2017-Sensitive Data Exposure
Inadequate encryption strength java_crypto_rule-InsufficientKeySizeRsa, CWE-326 Severity: Medium

The application is generating an RSA key that is less than the recommended 2048 bits. The National Institute of Standards and Technology (NIST) deprecated signing Digital Certificates that contained RSA Public Keys of 1024 bits in December 2010. While
1024-bit RSA keys have not been factored yet, advances in compute may make it possible in the near future.

Consider upgrading to the newer asymmetric algorithm such as Ed25519 which handles the complexities of generating key pairs and choosing correct key sizes for you:

public static KeyPair generateEd25519() throws NoSuchAlgorithmException {
// Choose Ed25519 for KeyPairGenerator Instance
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("Ed25519");
// Generate a KeyPair and return
return keyPairGenerator.generateKeyPair();
}

Otherwise use a key size greater than 2048 when generating RSA keys:

public static KeyPair generateRSA() throws NoSuchAlgorithmException {
// Choose RSA for KeyPairGenerator Instance
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
// Initialize with 2048 key size
keyPairGenerator.initialize(2048);
// Generate a KeyPair and return
return keyPairGenerator.generateKeyPair();
}

For more information on Ed25519 see:

For more information on Java Cryptography see: java-cryptography-architecture-jca-reference-guide.html

OWASP:
  • A02:2021-Cryptographic Failures
  • A3:2017-Sensitive Data Exposure
Use of a broken or risky cryptographic algorithm java_crypto_rule-NullCipher, CWE-327 Severity: Medium

The application was found creating a NullCipher instance. NullCipher implements the
Cipher interface by returning ciphertext identical to the supplied plaintext. This means any data passed to the doFinal(...) or update(...) methods will not actually encrypt the input.

Remove the NullCipher reference and replace with a legitimate Cipher instance such as
ChaCha20-Poly1305

Example using ChaCha20Poly1305:

public encrypt() throws Exception {
chaChaEncryption("Secret text to encrypt".getBytes(StandardCharsets.UTF_8));
}

public SecureRandom getSecureRandomDRBG() throws NoSuchAlgorithmException {
// Use DRBG according to http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-90Ar1.pdf
return SecureRandom.getInstance("DRBG",
// Security strength in bits (default is 128)
DrbgParameters.instantiation(256,
// Set prediction resistance and re-seeding
DrbgParameters.Capability.PR_AND_RESEED,
// Set the personalization string (optional, not necessary)
"some_personalization_string".getBytes()
)
);
}

public Cipher getChaCha20Poly1305(int mode, byte[] ivKey, byte[] secretKey) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException {
// Get a DRBG random number generator instance
SecureRandom random = getSecureRandomDRBG();
// Create a ChaCha20-Poly1305 cipher instance
Cipher chaChaCipher = Cipher.getInstance("ChaCha20-Poly1305/None/NoPadding");
// Create our parameterSpec using our ivKey
AlgorithmParameterSpec parameterSpec = new IvParameterSpec(ivKey);
// Create a SecretKeySpec using our secretKey
SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey, "ChaCha20");
// Initialize and return the cipher for the provided mode
chaChaCipher.init(mode, secretKeySpec, parameterSpec, random);
return chaChaCipher;
}

public void chaChaEncryption(byte[] plainText) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException {
// Get a DRBG random number generator instance
SecureRandom random = getSecureRandomDRBG();
// Create secretKey
byte[] secretKey = new byte[32];
random.nextBytes(secretKey);
// Create an IV Key
byte[] ivKey = new byte[12];
random.nextBytes(ivKey);

// Create a chaCha encryption cipher instance
Cipher chaChaEncryptor = getChaCha20Poly1305(Cipher.ENCRYPT_MODE, ivKey, secretKey);

// Encrypt the text using ChaCha20Poly1305
byte[] cipherText = null;
try {
cipherText = chaChaEncryptor.doFinal(plainText);
} catch (IllegalBlockSizeException | BadPaddingException e) {
System.out.println("failed to encrypt text");
return;
}
System.out.println("encrypted: " + Base64.getEncoder().encodeToString(cipherText));

// Create a chaCha decryption cipher instance
Cipher chaChaDecryptor = getChaCha20Poly1305(Cipher.DECRYPT_MODE, ivKey, secretKey);

// Decrypt the text
byte[] decryptedText = null;
try {
decryptedText = chaChaDecryptor.doFinal(cipherText);
} catch (IllegalBlockSizeException | BadPaddingException e) {
System.out.println("failed to decrypt text");
return;
}
System.out.println("decrypted: " + new String(decryptedText, StandardCharsets.UTF_8));
}

For more information on Java Cryptography see: java-cryptography-architecture-jca-reference-guide.html

OWASP:
  • A02:2021-Cryptographic Failures
  • A3:2017-Sensitive Data Exposure
Use of RSA algorithm without OAEP java_crypto_rule-RsaNoPadding, CWE-780 Severity: Medium

The software uses the RSA algorithm but does not incorporate Optimal Asymmetric Encryption Padding (OAEP). By not enabling padding, the algorithm maybe vulnerable to chosen plaintext attacks.

To enable OAEP mode, pass RSA/ECB/OAEPWithSHA-256AndMGF1Padding to the Cipher.getInstance
method.

Example encrypting and decrypting a message using RSA with OAEP:

public static void encryptWithRSA() throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException {
// Generate an RSA Public and Private Key Pair
KeyPair keyPair = generateRSAKeys();
// Create a Cipher instance using RSA, ECB with OAEP
Cipher rsaEncryptor = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding");
// Initialize to ENCRYPT_MODE with the public key
rsaEncryptor.init(Cipher.ENCRYPT_MODE, keyPair.getPublic());
// Encrypt our secret message
byte[] cipherText = rsaEncryptor.doFinal("Some secret message".getBytes(StandardCharsets.UTF_8));

// Create a Cipher instance using RSA, ECB with OAEP
Cipher rsaDecryptor = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding");
// Initialize to DECRYPT_MODE with the private key
rsaDecryptor.init(Cipher.DECRYPT_MODE, keyPair.getPrivate());
// Decrypt the secret message
byte[] plainText = rsaDecryptor.doFinal(cipherText);
// Debug output
System.out.println(new String(plainText));
}

More information on Optimal asymmetric encryption padding: Optimal_asymmetric_encryption_padding

For more information on Java Cryptography see: java-cryptography-architecture-jca-reference-guide.html

OWASP:
  • A02:2021-Cryptographic Failures
  • A3:2017-Sensitive Data Exposure
Use of a broken or risky cryptographic algorithm (SHA1 / MD5) java_crypto_rule-WeakMessageDigest, CWE-327 Severity: Medium

The application was found using an insecure or risky digest or signature algorithm. Both MD5
and SHA1 hash algorithms have been found to be vulnerable to producing collisions. This means that two different values, when hashed, can lead to the same hash value. If the application is trying to use these hash methods for storing passwords, then it is recommended to switch to a password hashing algorithm such as Argon2id or PBKDF2. strongly recommended that a standard Digest algorithm be chosen instead as implementing a digest by hand is error-prone.

Example of creating a SHA-384 hash:

// Create a MessageDigest using the SHA-384 algorithm MessageDigest sha384Digest = MessageDigest.getInstance("SHA-384");
// Call update with your data sha384Digest.update(input);
// Only call digest once all data has been fed into the update sha384digest instance byte[] output = sha384Digest.digest();
// output base64 encoded version of the hash System.out.println("hash: " + Base64.getEncoder().encodeToString(output));

For more information on secure password storage see OWASP: Password_Storage_Cheat_Sheet.html

OWASP:
  • A04:2021-Insecure Design
  • A6:2017-Security Misconfiguration
Improper certificate validation java_crypto_rule-WeakTLSProtocol-DefaultHttpClient, CWE-295 Severity: Medium

The org.apache.http.impl.client.DefaultHttpClient does not verify the hostnames upon connection.

This allows for an adversary who is in between the application and the target host to intercept potentially sensitive information or transmit malicious data.

Do not use the org.apache.http.impl.client.DefaultHttpClient(); as it is deprecated. Instead use the new java.net.http.HttpClient that was introduced in Java 9.

Example connecting to a host that will automatically do TLS validation:

// Create a new java.net.http.HttpClient HttpClient httpClient = HttpClient.newHttpClient();
// Create a HttpRequest builder HttpRequest request = HttpRequest.newBuilder()
// Create a URI for a website which requires TLS
.uri(URI.create("https://www.example.com/"))
// Build the request
.build();

// Use the httpClient to send the request and use an HttpResponse.BodyHandlers String type HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
// Debug print System.out.println(response);
OWASP:
  • A02:2021-Cryptographic Failures
  • A3:2017-Sensitive Data Exposure
Improper certificate validation java_crypto_rule-WeakTLSProtocol-SSLContext, CWE-295 Severity: Medium

Avoid initializing SSLContext with insecure protocols like SSL, SSLv2, or SSLv3. These protocols are outdated and do not validate certificates by default. Additionally, these older SSL versions have many known security issues.

Instead, use secure protocols like TLSv1.2 or TLSv1.3.

SSLContext context = SSLContext.getInstance("TLSv1.3");
For more information on see OWASP:
01-Testing_for_Weak_SSL_TLS_Ciphers_Insufficient_Transport_Layer_Protection
OWASP:
  • A02:2021-Cryptographic Failures
  • A3:2017-Sensitive Data Exposure
Inadequate encryption strength java_crypto_rule-WeakTLSProtocolVersion, CWE-326 Severity: Medium

The application was found enabling insecure TLS protocol versions. When enabling protocol versions for an SSLContext, only the following versions should be allowed:
- TLSv1.2
- TLSv1.3
- DTLSv1.2
- DTLSv1.3

To mitigate potential security risks, it is strongly advised to enforce TLS 1.2 as the minimum protocol version and disallow older versions such as TLS 1.0. Do note that newer versions of Java do not even support TLS 1.0 and will throw NoSuchAlgorithmException. Versions of TLS prior to 1.2 could expose the connection to downgrade attacks, where an adversary intercepts the connection and alters the requested protocol version to be a less secure one.

In many scenarios, relying on the default system configuration does not meet compliance standards. This is due to the application being deployed across diverse systems with varying configurations and Java versions. While the default value may be secure on modern and up-to-date systems, it may not hold true for older systems. Consequently, it is highly recommended to explicitly define a secure configuration in all cases.

Example configuring an SSLContext with TLSv1.2:

// Create an SSLContext with TLSv1.2 explicitly SSLContext tlsContext = SSLContext.getInstance("TLSv1.2"); // or TLSv1.3, DTLSv1.2, DTLSv1.3

// Alternatively, set the enabled protocols SSLContext serverSslContext = SSLContext.getInstance("TLS");
SSLEngine serverEngine = serverSslContext.createSSLEngine();
// Calling setEnabledProtocols will override the original context's configured protocol version serverEngine.setEnabledProtocols(new String[]{ "TLSv1.2" });
For more information on SSLContext see:
SSLContext.html
For more information on MiTM attacks see:
Manipulator-in-the-middle_attack
OWASP:
  • A02:2021-Cryptographic Failures
  • A3:2017-Sensitive Data Exposure
Improper certificate validation java_endpoint_rule-HostnameVerifier, CWE-295 Severity: Medium

The HostnameVerifier has been set to always return true. This effectively
disables the validation of server or client certificates. This could allow an
adversary who is in between the application and the target host to launch a Man
in the middle attack (MITM) i.e intercept potentially sensitive information or
inject malicious content into the communication stream.

To mitigate this vulnerability and enhance the security of your application, it is
strongly advised to adhere to the default HostnameVerifier settings. This ensures
that the validation mechanism remains intact, providing a crucial layer of security
against unauthorized interception and data manipulation.

Implementing the default HostnameVerifier can be achieved with the following code
snippet:

// Use the default HostnameVerifier HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
connection.setHostnameVerifier(HttpsURLConnection.getDefaultHostnameVerifier());

For more information on TLS security, refer the following OWASP documentation: Transport_Layer_Protection_Cheat_Sheet.html

OWASP:
  • A05:2021-Security Misconfiguration
  • A6:2017-Security Misconfiguration
Improper certificate validation java_endpoint_rule-X509TrustManager, CWE-295 Severity: Medium

The X509TrustManager has been configured to return null. This effectively disables the validation of server or client certificates. This could allow an adversary who is in
between the application and the target host to launch a Man in the middle attack (MITM) i.e
intercept potentially sensitive information or inject malicious content into the
communication stream.

Consider using the
default TrustManager instead of implementing a custom one. If you must override the default verification process, implement proper TrustManager verification for
checkServerTrusted and checkClientTrusted by throwing CertificateException if
the certificate is invalid.

For most applications, using the default TrustManager provided by the Java runtime is
sufficient and recommended. Following is an example using the built in TrustManagerFactory
to manage validating certificate chains:

// Use the default TrustManagerFactory TrustManagerFactory trustManagerFactory =
TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
// Use default system KeyStore, alternatively pass in your own keystore. trustManagerFactory.init((KeyStore) null);
// Create SSLContext for TLS connections SSLContext tlsContext = SSLContext.getInstance("TLS");
// Initialize the tlsContext with our trust manager and a SecureRandom number generator. tlsContext.init(null, trustManagerFactory.getTrustManagers(), new SecureRandom());

For more information on TLS security, refer the following OWASP documentation: Transport_Layer_Protection_Cheat_Sheet.html

OWASP:
  • A05:2021-Security Misconfiguration
  • A6:2017-Security Misconfiguration
Improper neutralization of argument delimiters in a command ('Argument Injection') java_inject_rule-HttpParameterPollution, CWE-88 Severity: Medium

The application was found including unvalidated user input into a URL, which could lead to HTTP Parameter Pollution (HPP) or worse, Server Side Request Forgery (SSRF). This could allow an adversary to override the value of a URL or a request parameter. HTTP Parameter Pollution
(HPP) attacks consist of injecting encoded query string delimiters into other existing parameters. If a web application does not properly sanitize the user input, an adversary may modify the logic of these requests to other applications.

To remediate this issue, never allow user input directly into creation of a URL or URL parameter. Consider using a map to look up user-supplied information and return exact values to be used in the generation of requests.

Example using a map to look up a key to be used in a HTTP request:

HashMap<String, String> lookupTable = new HashMap<>();
lookupTable.put("key1", "value1");
lookupTable.put("key2", "value2");
String userInput = request.getParameter("key");

// Create a CloseableHttpClient, ideally any requests issued should be done
// out-of-band from the servlet request itself (such as using a separate thread/scheduler system)
try (final CloseableHttpClient httpClient = HttpClients.createDefault()) {
// Lookup the value from our user input from our lookupTable
String value = lookupTable.getOrDefault(userInput, "value1");
// Construct the url, with the hardcoded url and only pass in the value from the lookupTable,
// not direct user input
final HttpGet httpget = new HttpGet("https://example.com/getId?key="+value);
// Execute the request
CloseableHttpResponse clientResponse = httpClient.execute(httpget);
// Read the response
byte[] responseData = clientResponse.getEntity().getContent().readAllBytes();
// Handle the response
// ...
}

If using a map is not possible, the user-supplied input must be encoded prior to use, and never allow full URLs:

// Get user input String userInput = request.getParameter("key");
// Encode the string using java.net.URLEncoder with the UTF-8 character set String encodedString = java.net.URLEncoder.encode(userInput, StandardCharsets.UTF_8);
// Create a CloseableHttpClient, ideally any requests issued should be done
// out-of-band from the servlet request itself (such as using a separate thread/scheduler system)
try (final CloseableHttpClient httpClient = HttpClients.createDefault()) {
// Construct the url, with the hardcoded url and only pass in the encoded value, never a full URL
final HttpGet httpget = new HttpGet("https://example.com/getId?key="+encodedString);
// Execute the request
CloseableHttpResponse clientResponse = httpClient.execute(httpget);
// Read the response
byte[] responseData = clientResponse.getEntity().getContent().readAllBytes();
// handle the response
}

For more information on SSRF see OWASP: Server_Side_Request_Forgery_Prevention_Cheat_Sheet.html

For more information on HTTP Parameter Pollution see: HTTP_parameter_pollution

OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Improper neutralization of special elements used in an LDAP query ('LDAP Injection') java_inject_rule-LDAPInjection, CWE-90 Severity: Medium

LDAP injection attacks exploit LDAP queries to influence how data is returned by the LDAP server.

Later versions of Java's InitialDirContext.search introduced a four argument method, one of which is the filterArg parameter. The filterArg will be automatically encoded when querying the LDAP server. If this method signature is not available, the application must encode the LDAP strings manually.

More details on the four argument search method can be found here: InitialDirContext.html

To encode the string manually, it is recommended that all input passed to LDAP querying systems encode the following values:

  • Any occurrence of the null character must be escaped as “\00”.
  • Any occurrence of the open parenthesis character must be escaped as “\28”.
  • Any occurrence of the close parenthesis character must be escaped as “\29”.
  • Any occurrence of the asterisk character must be escaped as “\2a”.
  • Any occurrence of the backslash character must be escaped as “\5c”.

Example function that safely encodes user-supplied input to be used in an LDAP query.

public static String encodeLDAPString(String input) {
// Note the character is replaced first
CharSequence[] chars = new CharSequence[] { "\", "\0", "(", ")", "" };
CharSequence[] encoded = new CharSequence[] { "\5c", "\00", "\28", "\29", "\2a" };
// Iterate over each character sequence, replacing the raw value with an encoded version of it
for (int i = 0; i < chars.length; i++)
{
// re-assign to input
input = input.replace(chars[i], encoded[i]);
}
// return our modified input string
return input;
}

Example code that using the filterArgs parameter which automatically encodes for us:

// Create a properties to hold the ldap connection details Properties props = new Properties();
// Use the com.sun.jndi.ldap.LdapCtxFactory factory provider props.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
// The LDAP server URL props.put(Context.PROVIDER_URL, "ldap://ldap.example.org:3889");
// User details for the connection props.put(Context.SECURITY_PRINCIPAL, "cn=admin,dc=example,dc=org");
// LDAP account password String ldapAccountPassword = getAccountPasswordFromSecureStoreOrKMS();
// Pass in the LDAP password props.put(Context.SECURITY_CREDENTIALS, ldapAccountPassword);

// Create the LDAPContext InitialDirContext ldapContext = new InitialDirContext(props);
// Example using SUBTREE_SCOPE SearchControls SearchControls searchControls = new SearchControls();
searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);

// Get user input for query String userQuery = someUserInput;
// Use searchArguments to hold the user-supplied input Object[] searchArguments = new Object[]{userQuery};
// Hardcode the BaseDN, use the {0} format specifier to use the searchArguments array value, and pass in the search controls.
// searchArguments automatically encode NamingEnumeration answer = ldapContext.search("dc=example,dc=org", "(cn={0})", searchArguments, searchControls);
// Process the response answer while (answer.hasMoreElements()) {
...
}

For more information on LDAP Injection see OWASP: LDAP_Injection_Prevention_Cheat_Sheet.html

OWASP:*
  • A03:2021-Injection
  • A1:2017-Injection
Improper limitation of a pathname to a restricted directory ('Path Traversal') java_inject_rule-SpotbugsPathTraversalAbsolute, CWE-22 Severity: Medium

The application dynamically constructs file or path information. If the path information comes from user input, it could be abused to read sensitive files, access other users' data, or aid in exploitation to gain further system access.

User input should never be used in constructing paths or files for interacting with the filesystem. This includes filenames supplied by user uploads or downloads. If possible, consider hashing user input or replacing it with unique values and use Path.resolve to resolve and validate the path information prior to processing any file functionality.

Example using Path.resolve and not allowing direct user input:

// Class to store our user data along with a randomly generated file name public static class UserData {
private String userFileNameUnsafe;
private String fileName;
public UserData(String userFileName) {
this.userFileNameUnsafe = userFileName;
// Generate a random ID for the filename
this.fileName = UUID.randomUUID().toString();
}
public String getUserFileNameUnsafe() { return userFileNameUnsafe; };
public String getFileName() { return fileName; };
}

public static void main(String[] args) throws Exception {
// User input, saved only as a reference
UserData userData = new UserData("..\test.txt");
// Restrict all file processing to this directory only
String base = "/var/app/restricted";
Path basePath = Paths.get(base);
// Resolve the full path, but only use our random generated filename
Path fullPath = basePath.resolve(userData.getFileName());
// verify the path is contained within our basePath
if (!fullPath.startsWith(base)) {
throw new Exception("Invalid path specified!");
}
// process / work with file
}

For more information on path traversal issues see OWASP: Path_Traversal

OWASP:
  • A01:2021-Broken Access Control
  • A5:2017-Broken Access Control
Incorrect permission assignment for critical resource java_perm_rule-DangerousPermissions, CWE-732 Severity: Medium

The application was found to permit the RuntimePermission of createClassLoader,
ReflectPermission of suppressAccessChecks, or both.

By granting the RuntimePermission of createClassLoader, a compromised application could instantiate their own class loaders and load arbitrary classes.

By granting the ReflectPermission of suppressAccessChecks an application will no longer check Java language access checks on fields and methods of a class. This will effectively grant access to protected and private members.

For more information on RuntimePermission see: RuntimePermission.html

For more information on ReflectPermission see: ReflectPermission.html

OWASP:
  • A01:2021-Broken Access Control
  • A5:2017-Broken Access Control
Incorrect permission assignment for critical resource java_perm_rule-OverlyPermissiveFilePermissionInline, CWE-732 Severity: Medium

The application was found setting file permissions to overly permissive values. Consider using the following values if the application user is the only process to access the file:

  • r-- - read only access to the file
  • w-- - write only access to the file
  • rw- - read/write access to the file

Example setting read/write permissions for only the owner of a Path:

// Get a reference to the path Path path = Paths.get("/tmp/somefile");
// Create a PosixFilePermission set from java.nio.file.attribute Set<PosixFilePermission> permissions =
java.nio.file.attribute.PosixFilePermissions.fromString("rw-------");
// Set the permissions java.nio.file.Files.setPosixFilePermissions(path, permissions);

For all other values please see: File-system_permissions

OWASP:
  • A01:2021-Broken Access Control
  • A5:2017-Broken Access Control
Improper validation of certificate with host mismatch java_smtp_rule-InsecureSmtp, CWE-297 Severity: Medium

The Apache commons mail client by default does not enable TLS server identity. This allows for an adversary who is in between the application and the target host to intercept potentially sensitive information or transmit malicious data.

Enable checking server identity by calling Email.setSSLCheckServerIdentity(true)

Example email client that enables TLS and server identity:

// Create an email client Email email = new SimpleEmail();
// Configure the email hostname email.setHostName("smtp.mail.example.com");
// Set the port email.setSmtpPort(465);
// Securely retrieve username and password values String username = getUserNameFromKMSorSecretStore();
String password = getPasswordFromKMSorSecretStore();
// Configure the Authenticator DefaultAuthenticator auth = new DefaultAuthenticator(username, password);
// Set the authenticator email.setAuthenticator(auth);
// Ensure we use SSL on connect email.setSSLOnConnect(true);
// Ensure we validate server identity email.setSSLCheckServerIdentity(true);
// configure the rest of the email email.setFrom("x@example.com");
email.setSubject("TestMail");
email.setMsg("This is a test mail ... :-)");
email.addTo("y@example.com");
email.send();
OWASP:
  • A02:2021-Cryptographic Failures
  • A3:2017-Sensitive Data Exposure
Server-Side Request Forgery (SSRF) java_ssrf_rule-SSRF, CWE-918 Severity: Medium

Server-Side-Request-Forgery (SSRF) exploits backend systems that initiate requests to third parties. If user input is used in constructing or sending these requests, an attacker could supply malicious data to force the request to other systems or modify request data to cause unwanted actions.

Ensure user input is not used directly in constructing URLs or URIs when initiating requests to third party systems from back end systems. Care must also be taken when constructing payloads using user input. Where possible restrict to known URIs or payloads. Consider using a server-side map where keys are used to return URLs such as https://site/goto?key=1 where {key: 1, url: 'http://some.url/', key: 2, url:
'http://...'}
.

If you must use user-supplied input for requesting URLs, it is strongly recommended that the HTTP client chosen allows you to customize and block certain IP ranges at the network level. By blocking RFC 1918
addresses or other network address ranges, you can limit the severity of a successful SSRF attack. Care must also be taken to block certain protocol or address formatting such as IPv6.

If you cannot block address ranges at the client level, you may want to run the HTTP client as a protected user, or in a protected network where you can apply IP Table or firewall rules to block access to dangerous addresses. Finally, if none of the above protections are available, you could also run a custom HTTP proxy and force all requests through it to handle blocking dangerous addresses.

Example using a map to look up a key to be used in a HTTP request:

HashMap<String, String> lookupTable = new HashMap<>();
lookupTable.put("key1", "https://example.com/");
lookupTable.put("key2", "https://safeurl.com/");
String userInput = request.getParameter("key");

// Create a CloseableHttpClient, ideally any requests issued should be done
// out-of-band from the servlet request itself (such as using a separate thread/scheduler system)
try (final CloseableHttpClient httpClient = HttpClients.createDefault()) {
// Lookup the value from our user input from our lookupTable
String value = lookupTable.getOrDefault(userInput, "https://example.com/");
// Construct the url, with the hardcoded url and only pass in the value from the lookupTable,
// not direct user input
final HttpGet httpget = new HttpGet(value);
// Execute the request
CloseableHttpResponse clientResponse = httpClient.execute(httpget);
// Read the response
byte[] responseData = clientResponse.getEntity().getContent().readAllBytes();
// Handle the response
// ...
}

If using a map is not possible, the user-supplied input must be encoded prior to use, and never allow full URLs:

// Get user input String userInput = request.getParameter("key");
// Encode the string using java.net.URLEncoder with the UTF-8 character set String encodedString = java.net.URLEncoder.encode(userInput, StandardCharsets.UTF_8);
// Create a CloseableHttpClient, ideally any requests issued should be done
// out-of-band from the servlet request itself (such as using a separate thread/scheduler system)
try (final CloseableHttpClient httpClient = HttpClients.createDefault()) {
// Construct the url, with the hardcoded url and only pass in the encoded value, never a full URL
final HttpGet httpget = new HttpGet("https://example.com/getId?key="+encodedString);
// Execute the request
CloseableHttpResponse clientResponse = httpClient.execute(httpget);
// Read the response
byte[] responseData = clientResponse.getEntity().getContent().readAllBytes();
// handle the response
}

For more information on SSRF see OWASP: Server_Side_Request_Forgery_Prevention_Cheat_Sheet.html

OWASP:
  • A10:2021-Server-Side Request Forgery
  • A1:2017-Injection
Use of externally-controlled format string java_strings_rule-FormatStringManipulation, CWE-134 Severity: Medium

The application allows user input to control format string parameters. By passing invalid format string specifiers an adversary could cause the application to throw exceptions or possibly leak internal information depending on application logic.

Never allow user-supplied input to be used to create a format string. Replace all format string arguments with hardcoded format strings containing the necessary specifiers.

Example of using String.format safely:

// Get untrusted user input String userInput = request.getParameter("someInput");
// Ensure that user input is not included in the first argument to String.format String.format("Hardcoded string expecting a string: %s", userInput);
// ...
OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Weak authentication java_xml_rule-SAMLIgnoreComments, CWE-1390 Severity: Medium

SAML parses attestations as an XML document. By processing XML comments, comment fields can end up modifying the interpretation of input fields. This could allow an adversary to insert an XML comment to break up the attestation's username or other fields, allowing an attacker to bypass authorization or authentication checks.

To remediate this issue, when using org.opensaml.xml.parse.BasicParserPool ensure
setIgnoreComments(false) is not called.

The default value of ignoreComments is true, which is safe.

Ref:
BasicParserPool.html

For more information on how this issue can be exploited see: a-breakdown-of-the-new-saml-authentication-bypass-vulnerability

For more information on SAML security see OWASP: SAML_Security_Cheat_Sheet.html

OWASP:
  • A01:2021-Broken Access Control
  • A5:2017-Broken Access Control
XML injection (aka Blind XPath injection) java_xml_rule-XsltTransform, CWE-91 Severity: Medium

The application performs XSLT translation with potentially malicious input. An adversary who is able to influence the loaded XSL document could call XSL functions or exploit External XML Entity (XXE) attacks that allow file retrieval or force the parser to connect to arbitrary servers to exfiltrate files. It is strongly recommended that an alternative approach is used to work with XML data.

For increased security, never process user-supplied XSL style sheets. If XSLT processing is absolutely necessary, ensure that FEATURE_SECURE_PROCESSING is enabled prior to processing the XSLT file:

// Create a new TransformerFactory instance TransformerFactory transformerFactory = TransformerFactory.newInstance();
// Enable the FEATURE_SECURE_PROCESSING feature transformerFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
// Read in the XML Source Source xmlSource = new StreamSource(new FileInputStream("hardcoded.xml"));
// Read in the XSL template file Source xslSource = new StreamSource(new FileInputStream("hardcoded.xsl"));
/// Create the transformer object to do the transformation Transformer transformer = transformerFactory.newTransformer(xslSource);
// Create a Result object for output Result result = new StreamResult(System.out);
// Execute the transformation process transformer.transform(xmlSource, result);

For more information on XML security see OWASP's guide: XML_External_Entity_Prevention_Cheat_Sheet.html

For more information on the secure processing feature see:
features.html
OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Improper neutralization of input during web page generation ('Cross-site Scripting') java_xss_rule-WicketXSS, CWE-79 Severity: Medium

The application is disabling Wicket's string escaping functionality by calling
setEscapeModelStrings(false). This could lead to Cross Site Scripting (XSS) if used with user-supplied input. XSS is an attack which exploits
a web application or system to treat user input as markup or script code. It is important to encode the data depending on the specific context it is used in. There are at least six context types:

  • Inside HTML tags <div>context 1</div>
  • Inside attributes: <div class="context 2"></div>
  • Inside event attributes <button onclick="context 3">button</button>
  • Inside script blocks: <script>var x = "context 4"</script>
  • Unsafe element HTML assignment: element.innerHTML = "context 5"
  • Inside URLs: <iframe src="context 6"></iframe><a href="context 6">link</a>

Script blocks alone have multiple ways they need to be encoded. Extra care must be taken if user input is ever output inside of script tags.

User input that is displayed within the application must be encoded, sanitized or validated to ensure it cannot be treated as HTML or executed as JavaScript code. Care must also be taken to not mix server-side templating with client-side templating, as the server-side templating will not encode things like {{ 77 }} which may execute client-side templating features.

It is NOT advised to encode user input prior to inserting into a data store. The data will need to be encoded depending on context of where it is output. It is much safer to force the displaying system to handle the encoding and not attempt to guess how it should be encoded.

Use Wicket's built in escaping feature by calling Component.setEscapeModelStrings(true);

For more information on Wicket components see:
Component.html
For more information on XSS see OWASP:
Cross_Site_Scripting_Prevention_Cheat_Sheet.html
OWASP:*
  • A03:2021-Injection
  • A1:2017-Injection
Improper neutralization of input during web page generation ('Cross-site Scripting') java_xss_rule-XSSReqParamToServletWriter, CWE-79 Severity: Medium

The application is returning user-supplied data from an HTTP request directly into an HTTP response output writer. This could lead to Cross Site Scripting (XSS) if the input were malicious script code and the application server is not properly validating the output.

XSS is an attack which exploits a web application or system to treat user input as markup or script code. It is important to encode the data depending on the specific context it is used in. There are at least six context types:

  • Inside HTML tags <div>context 1</div>
  • Inside attributes: <div class="context 2"></div>
  • Inside event attributes <button onclick="context 3">button</button>
  • Inside script blocks: <script>var x = "context 4"</script>
  • Unsafe element HTML assignment: element.innerHTML = "context 5"
  • Inside URLs: <iframe src="context 6"></iframe><a href="context 6">link</a>

Script blocks alone have multiple ways they need to be encoded. Extra care must be taken if user input is ever output inside of script tags.

User input that is displayed within the application must be encoded, sanitized or validated to ensure it cannot be treated as HTML or executed as Javascript code. Care must also be taken to not mix server-side templating with client-side templating, as the server-side templating will not encode things like {{ 77 }} which may execute client-side templating features.

It is NOT advised to encode user input prior to inserting into a data store. The data will need to be encoded depending on context of where it is output. It is much safer to force the displaying system to handle the encoding and not attempt to guess how it should be encoded.

If possible do not use user input directly in the output to the response writer.

If the application must output user-supplied input, it will need to encode the data depending on the output context.

Consider using Apache Commons TextStringEscapeUtils methods for various context. Please note there is no way to safely output script code in most circumstances, regardless of encoding. If calling the HTTP response writer directly, ensure that the Content-Type is set to text/plain so it will not be accidentally interpreted by HTML by modern browsers.

// Get user input String htmlInput = request.getParameter("userInput");
// Encode the input using the Html4 encoder String htmlEncoded = StringEscapeUtils.escapeHtml4(htmlInput);
// Force the HTTP response to be content type of text/plain so it is not interpreted as HTML response.setContentType("text/plain");
// Ensure UTF-8
response.setCharacterEncoding("UTF-8");
// Write response response.getWriter().write(htmlEncoded);
For more information on XSS see OWASP:
Cross_Site_Scripting_Prevention_Cheat_Sheet.html
OWASP:*
  • A03:2021-Injection
  • A1:2017-Injection
Improper restriction of XML external entity reference ('XXE') java_xxe_rule-XMLRdr, CWE-611 Severity: Medium

External XML entities are a feature of XML parsers that allow documents to contain references to other documents or data. This feature can be abused to read files, communicate with external hosts, exfiltrate data, or cause a Denial of Service (DoS).

The XMLReaderFactory has been deprecated. It is recommended that
SAXParserFactory
be used instead. Additionally when using the SAXParser it must be configured to disallow doctypes, which will protect against the majority of XXE attacks.

Example creating a SAXParser with disallowing the doctypes feature enabled:

// Create a SAXParserFactory SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
// Enable the feature which disallows <!DOCTYPE declarations which includes referencing external entities. saxParserFactory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
// Create a new parser from this factory SAXParser parser = saxParserFactory.newSAXParser();
// Parse the XML file, passing in a DefaultHandler (which also includes an empty entityResolve method)
parser.parse(new FileInputStream(new File("bad.xml")), new DefaultHandler());

For more information on XML security see OWASP's guide: XML_External_Entity_Prevention_Cheat_Sheet.html

OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Improper certificate validation" rules_lgpl_java_webview_rule-ignore-ssl-certificate-errors, CWE-295 Severity: Medium

Insecure WebView Implementation. leading to a security problem known as SSL certificate
validation bypass. This occurs when the app fails to properly validate SSL certificates,
allowing potentially malicious or spoofed certificates to be accepted, leading to a
Man-in-the-Middle (MitM) attack where an attacker intercepts and manipulates communication
between the app and the server.

To fix this security issue, you should properly handle SSL errors and only proceed with
the connection if the SSL certificate is valid and trusted. Here's an example code in Java:

public class MyWebViewClient extends WebViewClient {      
@Override
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
// Check the SSL error type
switch (error.getPrimaryError()) {
case SslError.SSL_UNTRUSTED:
// Certificate is untrusted
// Handle the error appropriately, such as showing an error message
break;
case SslError.SSL_EXPIRED:
// Certificate has expired
// Handle the error appropriately
break;
case SslError.SSL_IDMISMATCH:
// Certificate hostname mismatch
// Handle the error appropriately
break;
case SslError.SSL_NOTYETVALID:
// Certificate is not yet valid
// Handle the error appropriately
break;
}
// Cancel the connection
// This prevents the WebView from loading the content
handler.cancel();
}
}
OWASP:
  • A02:2021-Cryptographic Failures
  • A3:2017-Sensitive Data Exposure
Active debug code rules_lgpl_java_webview_rule-webview-debugging, CWE-489 Severity: Medium

Remote WebView debugging is enabled. This allows an attacker with debugging access to interact with the webview and steal or corrupt data. To fix these security issues, it is recommended to disable remote
debugging and restrict file access in the WebView.
Here's how you can do it:

WebView webView = new WebView(context);

// Disable remote debugging if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
WebView.setWebContentsDebuggingEnabled(false);
}

// Restrict file access from file URLs webView.getSettings().setAllowFileAccessFromFileURLs(false);

// Load a web page webView.loadUrl("https://example.com");
OWASP:
  • A05:2021-Security Misconfiguration
  • A6:2017-Security Misconfiguration
External control of file name or path rules_lgpl_java_webview_rule-webview-set-allow-file-access, CWE-73 Severity: Medium

WebView File System Access is enabled. An attacker able to inject
script into a WebView, could exploit the opportunity to unauthorized
access to sensitive user data or system files.

To fix this security issue, you should disable file access in the
WebView or restrict it to specific directories.
An example:

// Create a WebView instance WebView webView = new WebView(context);
// Disable file access in the WebView webView.getSettings().setAllowFileAccess(false);
OWASP:
  • A01:2021-Broken Access Control
  • A5:2017-Broken Access Control
XML injection (aka Blind XPath injection) scala_xml_rule-XsltTransform, CWE-91 Severity: Medium

It is possible to attach malicious behavior to those style sheets. Therefore, if an attacker can control the content or the source of the style sheet, he might be able to trigger remote code execution.

OWASP:
Sensitive cookie in HTTPS session without 'Secure' attribute java_cookie_rule-CookieInsecure, CWE-614 Severity: Low

The Secure attribute when set to true protects the cookie value from being being transmitted over clear text communication paths such as HTTP. By enabling this protection, the cookie will only be sent over HTTPS.

Example of protecting a Cookie:

// Create an Secure cookie. Cookie someCookie = new Cookie("SomeCookieName", "SomeValue");
// Set Secure flag to true someCookie.setSecure(true);

For more information see: cookie

Session cookies should be configured with the following security directives:

OWASP:
  • A05:2021-Security Misconfiguration
  • A6:2017-Security Misconfiguration
Permissive cross-domain policy with untrusted domains java_cors_rule-PermissiveCORSInjection, CWE-942 Severity: Low

This application potentially allows user-supplied input into the value of the
Access-Control-Allow-Origin response header. This header is part of the
Cross-Origin Resource Sharing CORS specification. By allowing user input to specify which domains can communicate with this server, an adversary could exploit a weakness in this server to force clients to send credentials (such as session identifiers) to the adversary's server.

For the above attack to work, the application would need to suffer from an additional vulnerability, such as Cross-Site Scripting (XSS).

To remediate this issue, do not use user-supplied information when calling
HttpServletResponse.setHeader or HttpServletResponse.addHeader
for the Access-Control-Allow-Origin header's value. Instead, hardcode the allowed domain(s)
and reference them in a lookup table:
Example allowing dynamic but safe domains in Access-Control-Allow-Origin:

  // this data should be in the class constructor or taken from a trusted datasource
Map<String, String> allowedDomains = new HashMap();
allowedDomains.put("sub1", "sub1.example.com");
allowedDomains.put("sub2", "sub2.example.com");

// extract the allowedDomain parameters value as a key to look up which domain to provide via the allowedDomains map
// if not found, sets sub1 as the default
String headerValue = allowedDomains.getOrDefault(request.getParameter("allowedDomain"), allowedDomains.get("sub1"));

// add the header with our trusted sub1.example.com or sub2.example.com domains.
response.addHeader("Access-Control-Allow-Origin", headerValue);
}

For more information on Access-Control-Allow-Origin see: Access-Control-Allow-Origin

OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Improper neutralization of special elements used in a command java_smtp_rule-SmtpClient, CWE-77 Severity: Low

The application was found calling MimeMessage methods without encoding new line characters. Much like HTTP, Simple Mail Transfer Protocol (SMTP) is a text based protocol that uses headers to convey additional directives for how email messages should be treated. An adversary could potentially cause email messages to be sent to unintended recipients by abusing the CC or BCC headers if they were able to inject them.

To mitigate this issue, \r\n (CRLF) character sequences must be escaped or encoded prior to being used in any of the MimeMessage methods.

Example that escapes values that come from user input with
Apache Commons Text:

// Create a MimeMessage with a javax.mail.Session Message message = new MimeMessage(session);
// Set the from address message.setFrom(new InternetAddress("source@example.com"));
// Set the to address message.setRecipients(Message.RecipientType.TO,new InternetAddress[] {new InternetAddress("destination@example.com")});
// Example user input String subject = "potentially malicious data";
String headerValue = "potentially malicious data";
// Use Apache Commons Text StringEscapeUtils.escapeJava to encode \r\n to \r\n. message.setSubject(StringEscapeUtils.escapeJava(subject));
// Use Apache Commons Text StringEscapeUtils.escapeJava to encode \r\n to \r\n. message.addHeader("HeaderName", StringEscapeUtils.escapeJava(header));
// Use Apache Commons Text StringEscapeUtils.escapeJava to encode \r\n to \r\n. message.setDescription(StringEscapeUtils.escapeJava("some description"));
// Use Apache Commons Text StringEscapeUtils.escapeJava to encode \r\n to \r\n. message.setDisposition(StringEscapeUtils.escapeJava("some disposition"));
// Set the mail body text message.setText("Some email content.");
// Send the message
OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
External control of system or configuration setting java_unsafe_rule-ExternalConfigControl, CWE-15 Severity: Low

The application was found using user-supplied input in a java.sql.Connection's
setCatalog call. This could allow an adversary to supply a different database for the lifetime of the connection. Allowing external control of system settings can disrupt service or cause an application to behave in unexpected, and potentially malicious ways. Most likely this would only cause an error by providing a nonexistent catalog name.

It is recommended to not use user-supplied input when selecting the database for an applications database connection.

OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Permissive Cross-domain Policy with Untrusted Domains scala_cors_rule-PermissiveCORSInjection, CWE-942 Severity: Low

Prior to HTML5, Web browsers enforced the Same Origin Policy which ensures that in order for JavaScript to access the contents of a Web page, both the JavaScript and the Web page must originate from the same domain. Without the Same Origin Policy, a malicious website could serve up JavaScript that loads sensitive information from other websites using a client's credentials, cull through it, and communicate it back to the attacker. HTML5 makes it possible for JavaScript to access data across domains if a new HTTP header called Access-Control-Allow-Origin is defined. With this header, a Web server defines which other domains are allowed to access its domain using cross-origin requests. However, caution should be taken when defining the header because an overly permissive CORS policy will allow a malicious application to communicate with the victim application in an inappropriate way, leading to spoofing, data theft, relay and other attacks.

OWASP:
URL redirection to untrusted site ('Open Redirect') java_endpoint_rule-UnvalidatedRedirect, CWE-601 Severity: Info

Unvalidated redirects occur when an application redirects a user to a destination URL specified by a user supplied parameter that is not validated. Such vulnerabilities can be used to facilitate phishing attacks.

To avoid open redirect vulnerabilities in Java, one effective strategy is to only allow redirection to URLs that are pre-defined in a safe list. This safe list can be implemented using a collection like a Map, List, or Dictionary, where you store all the valid URLs or URL patterns. When a redirect request is made, you can check if the requested URL is in this safe list before proceeding
with the redirection. For example:

  protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
private List<String> safeUrls = new ArrayList<>();
safeUrls.add("/home");
safeUrls.add("/user/profile");
safeUrls.add("/dashboard");

String redirectUrl = request.getParameter("url");

if (safeUrls.contains(redirectUrl)) {
response.sendRedirect(redirectUrl);
} else {
response.sendRedirect("/errorPage");
}
}"
OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Improper limitation of a pathname to a restricted directory ('Path Traversal') java_file_rule-FileUploadFileName, CWE-22 Severity: Info

The filename provided by the FileUpload API can be tampered with which could lead to unauthorized access or file inclusion vulnerabilities. To mitigate this risk, it is essential to conduct rigorous validation of the filenames provided by clients. This validation should ensure that the filename adheres to a predefined structure, is devoid of potentially dangerous characters
(such as forward slashes / and backslashes ), and corresponds to an authorized file only.

For example, as a remediation strategy, the application could:
1. Sanitize Filenames: Create a function to sanitize filenames by removing
or replacing unauthorized characters, including path traversal sequences (../ or ..).
2. Allowlist Validation: Implement a allowlist approach, allowing only filenames
that match a specific pattern or are part of a predefined list.
3. Use Server-Generated Filenames: Rather than relying on client-provided filenames,
generate unique names server-side for storing files.
4. Verify File Paths: Ensure files are being saved in the correct,
intended directory, and prevent redirection to unauthorized directories.

Example remediation:

  public class FileUploadHandler {

protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {

Part filePart = request.getPart("file");
String fileName = filePart.getSubmittedFileName();

// removes any path information from the filename
String sanitizedFileName = sanitizeFileName(fileName);
if (!isFileNameAllowed(sanitizedFileName)) {
throw new SecurityException("Invalid file name");
}

// Generate a unique file name for storage
String storedFileName = UUID.randomUUID().toString() + ".txt";

Path targetPath = Paths.get("uploads").resolve(storedFileName);
Files.copy(fileContent, targetPath, StandardCopyOption.REPLACE_EXISTING);
}

private String sanitizeFileName(String fileName) {
return Paths.get(fileName).getFileName().toString();
}

private boolean isFileNameAllowed(String fileName) {
return fileName.matches("[a-zA-Z0-9._-]+");
}
}
OWASP:
  • A01:2021-Broken Access Control
  • A5:2017-Broken Access Control
Improper limitation of a pathname to a restricted directory ('Path Traversal') java_file_rule-FilenameUtils, CWE-22 Severity: Info

The filename provided by the FileUpload API can be tampered with by the client to reference unauthorized files. The provided filename should be properly validated to ensure it's properly structured, contains no unauthorized path characters (e.g., / ), and refers to an authorized file.

The application was found to take a parameter from user input to construct a path name. If an unfiltered parameter is passed to this file API, files from an arbitrary filesystem location could be read. When data from an unstrusted source is untrusted source is used to construct a file path, an attacker could potentially gain access to restrcited files locations outside the relevant context.

For example, if the application tries to access the users profile picture based on their user name by concatenating the username to the filepath:

"images/userprofiles/" + username

The expected result of this would be "images/userprofiles/alice", however an attacker could use a malicious input such as "../../../etc/passwd" to gain access to and/or manipulate sensitive information

Assume all input is malicious. Use an "accept known good" input validation strategy.

Inputs can be sanitized by using the getName() method with concat() method to remove the
potentially malicious path traversal and limit the scope to a restricted directory. Or
input can also be sanitized by using resolve() method alongwith startsWith() method to
verify that the base path of the file is safe and expected.

Example of limiting path traversal using getName:

protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

String input = req.getHeader("input");

input = getName(input);

String safePath = concat(basePath, input);

// Read the contents of the file
File file = new File(safePath);
}
OWASP:
  • A01:2021-Broken Access Control
  • A5:2017-Broken Access Control
Improper neutralization of special elements used in an expression language statement ('Expression Language Injection') java_inject_rule-ELInjection, CWE-917 Severity: Info

This rule identifies potential Expression Language (EL) injection vulnerabilities within Java applications.
The rule targets use of createValueExpression, createMethodExpression, ELProcessor.eval, getValue,
and setValue methods, particularly when input to these methods is not a hardcoded string, indicating dynamic
evaluation of potentially untrusted input.

createValueExpression creates a ValueExpression object which gets evaluated upon calling methods like
getValue() and setValue() or a Lambda invoke() i.e. it evaluates the expression passed to the
createValueExpression method.

Similarly, createMethodExpression creates a MethodExpression object which gets evaluated upon calling
methods like invoke() and getMethodInfo().
ELProcessor.eval, getValue(), and setValue() methods all evaluate their expressions which are passed
as parameters.

Calling these method directly with user-supplied input may allow an adversary to execute arbitrary Java
code, including OS system commands. Never call these methods directly with user-supplied input. Consider
alternate methods such as a lookup table to take user input and resolve hardcoded values.

Secure example:

import javax.el.ELProcessor;
import java.util.Set;

public class SafeELHandling {
private static final Set<String> ALLOWED_VALUES = Set.of("value1", "value2", "value3");

public void processInput(String userInput) {
// Validate user input against the allowlist
if (!ALLOWED_VALUES.contains(userInput)) {
throw new IllegalArgumentException("Invalid input");
}

ELProcessor elProcessor = new ELProcessor();
elProcessor.defineBean("userInput", userInput);

// Example EL expression using the safe, predefined input
String result = (String) elProcessor.eval(userInput);
}
}
OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Incorrect type conversion or cast java_strings_rule-BadHexConversion, CWE-704 Severity: Info

The application is using Integer.toHexString on a digest array buffer which may lead to an incorrect version of values.

Consider using the java.util.HexFormat object introduced in Java 17. For older Java applications consider using the javax.xml.bind.DatatypeConverter.

Example using HexFormat to create a human-readable string:

// Create a MessageDigest using the SHA-384 algorithm MessageDigest sha384Digest = MessageDigest.getInstance("SHA-384");
// Call update with your data sha384Digest.update("some input".getBytes(StandardCharsets.UTF_8));
// Only call digest once all data has been fed into the update sha384digest instance byte[] output = sha384Digest.digest();
// Create a JDK 17 HexFormat object HexFormat hex = HexFormat.of();
// Use formatHex on the byte array to create a string (note that alphabet characters are lowercase)
String hexString = hex.formatHex(output);

For more information on DatatypeConverter see: DatatypeConverter.html

OWASP:
  • A05:2021-Security Misconfiguration
  • A6:2017-Security Misconfiguration
Collapse of data into unsafe value java_strings_rule-ModifyAfterValidation, CWE-182 Severity: Info

The application was found matching a variable during a regular expression pattern match, and then calling string modification functions after validation has occurred. This is usually indicative of a poor input validation strategy as an adversary may attempt to exploit the removal of characters.

For example a common mistake in attempting to remove path characters to protect against path traversal is to match '../' and then remove any matches. However, if an adversary were to include in their input: '....//' then the replace method would replace the first ../ but cause the leading .. and trailing / to join into the final string of ../, effectively bypassing the check.

To remediate this issue always perform string modifications before any validation of a string. It is strongly recommended that strings be encoded instead of replaced or removed prior to validation.

Example replaces .. before validation. Do note this is still not a recommended method for protecting against directory traversal, always use randomly generated IDs or filenames instead:

// This is ONLY for demonstration purpose, never use untrusted input
// in paths, always use randomly generated filenames or IDs. String input = "test../....//dir";
// Use replaceAll not replace input = input.replaceAll("\.\.", "");
// Input would be test///dir at this point
// Create a pattern to match on Pattern pattern = Pattern.compile("\.\.");
// Create a matcher Matcher match = pattern.matcher(input);
// Call find to see if .. is still in our string if (match.find()) {
throw new Exception(".. detected");
}
// Use the input (but do not modify the string)
System.out.println(input + " safe");

For more information see Carnegie Mellon University's Secure Coding Guide: IDS11-J.+Perform+any+string+modifications+before+validation

OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Incorrect behavior order: validate before canonicalize java_strings_rule-NormalizeAfterValidation, CWE-180 Severity: Info

The application was found matching a variable during a regular expression pattern match, and then calling a Unicode normalize function after validation has occurred. This is usually indicative of a poor input validation strategy as an adversary may attempt to exploit the normalization process.

To remediate this issue, always perform Unicode normalization before any validation of a string.

Example of normalizing a string before validation:

// User input possibly containing malicious unicode String userInput = "\uFE64" + "tag" + "\uFE65";
// Normalize the input userInput = Normalizer.normalize(userInput, Normalizer.Form.NFKC);
// Compile our regex pattern looking for < or > characters Pattern pattern = Pattern.compile("[<>]");
// Create a matcher from the userInput Matcher matcher = pattern.matcher(userInput);
// See if the matcher matches if (matcher.find()) {
// It did so throw an error
throw new Exception("found banned characters in input");
}

For more information see Carnegie Mellon University's Secure Coding Guide: IDS01-J.+Normalize+strings+before+validating+them

OWASP:
  • A03:2021-Injection
  • A1:2017-Injection

javascript

Name Identifiers Description
Improper neutralization of special elements used in an SQL command (SQL Injection) rules_lgpl_javascript_database_rule-node-knex-sqli-injection, CWE-89 Severity: Critical

Untrusted input concatinated with raw SQL query using knex raw() or whereRaw() functions can result in SQL Injection.

OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Improper neutralization of special elements in data query logic rules_lgpl_javascript_database_rule-node-nosqli-injection, CWE-943 Severity: Critical

Untrusted user input in findOne() function can result in NoSQL Injection.

OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Improper neutralization of special elements in data query logic rules_lgpl_javascript_database_rule-node-nosqli-js-injection, CWE-943 Severity: Critical

Untrusted user input in MongoDB $where operator can result in NoSQL JavaScript Injection.

OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Improper neutralization of special elements used in an SQL command (SQL Injection) rules_lgpl_javascript_database_rule-node-sqli-injection, CWE-89 Severity: Critical

Untrusted input concatinated with raw SQL query can result in SQL Injection.

OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Selection of Less-Secure Algorithm During Negotiation (Algorithm Downgrade) rules_lgpl_javascript_database_rule-sequelize-weak-tls, CWE-757 Severity: Critical

'The Sequelize connection string indicates that an older version of TLS is in use. TLS1.0 and TLS1.1 are deprecated and should be used. By default, Sequelize use TLSv1.2 but it''s recommended to use TLS1.3. Not applicable to SQLite database.'

OWASP:
  • A02:2021-Cryptographic Failures
  • A3:2017-Sensitive Data Exposure
Cleartext Transmission of Sensitive Information rules_lgpl_javascript_electronjs_rule-electron-allow-http, CWE-319 Severity: Critical

Application can load content over HTTP and that makes the app vulnerable to Man in the middle attacks.

OWASP:
  • A05:2021-Security Misconfiguration
  • A6:2017-Security Misconfiguration
Origin validation error rules_lgpl_javascript_electronjs_rule-electron-disable-websecurity, CWE-346 Severity: Critical

Disabling webSecurity will disable the same-origin policy and allows the execution of insecure code from any domain.

OWASP:
  • A05:2021-Security Misconfiguration
  • A6:2017-Security Misconfiguration
Least privilege violation rules_lgpl_javascript_electronjs_rule-electron-experimental-features, CWE-272 Severity: Critical

Experimental features are not expected to be in production ready applications.

OWASP:
  • A05:2021-Security Misconfiguration
  • A6:2017-Security Misconfiguration
Use of incorrectly-resolved name or reference rules_lgpl_javascript_eval_rule-eval-require, CWE-706 Severity: Critical

Passing untrusted user input directly into the require() function without proper
validation or sanitization can possibly cause a vulnerability known as remote code execution (RCE).
An attacker could manipulate the input to load and execute arbitrary code from external sources,
potentially leading to severe security breaches such as data theft, system compromise,
or unauthorized access. To mitigate this risk, it's crucial to validate and sanitize user input thoroughly before passing it to functions like require(), ensuring that only trusted and safe inputs are utilized.

Following is an example of secure validation against allowlist to prevent the vulnerability:

// Define a list of explicitly allowed packages for require const allowedPkgs = [
'package1',
'package2',
'package3'
];

app.get("/eval/require/7", async (req, res) => {
var isAllowed = allowedPkgs.includes(req.query.name);
if (isAllowed) {
// ok: rules_lgpl_javascript_eval_rule-eval-require
var cp = require(req.query.name);
cp.exec('ls', (error, stdout, stderr) => {
console.log("exec output : \n", stdout)
});
}
res.send("Please check console logs.");
});
OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Improper control of generation of code (Code Injection) rules_lgpl_javascript_eval_rule-sandbox-code-injection, CWE-94 Severity: Critical

Unrusted data in sandbox can result in code injection.

OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Improper control of generation of code (Code Injection) rules_lgpl_javascript_eval_rule-server-side-template-injection, CWE-94 Severity: Critical

Untrusted user input in templating engine's compile() function can result in Remote Code Execution via server side template injection.

OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Improper control of generation of code (Code Injection) rules_lgpl_javascript_eval_rule-vm-code-injection, CWE-94 Severity: Critical

Untrusted user input reaching vm can result in code injection.

OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Improper control of generation of code (Code Injection) rules_lgpl_javascript_eval_rule-vm-compilefunction-injection, CWE-94 Severity: Critical

Untrusted user input in vm.compileFunction() can result in code injection.

OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Improper control of generation of code (Code Injection) rules_lgpl_javascript_eval_rule-vm-runincontext-injection, CWE-94 Severity: Critical

Untrusted user input in vm.runInContext() can result in code injection.

OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Improper control of generation of code (Code Injection) rules_lgpl_javascript_eval_rule-vm-runinnewcontext-injection, CWE-94 Severity: Critical

Untrusted user input in vm.runInNewContext() can result in code injection.

OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Improper control of generation of code (Code Injection) rules_lgpl_javascript_eval_rule-vm2-code-injection, CWE-94 Severity: Critical

Untrusted user input reaching vm2 can result in code injection.

OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Improper control of generation of code (Code Injection) rules_lgpl_javascript_eval_rule-vm2-context-injection, CWE-94 Severity: Critical

Untrusted user input reaching vm2 sandbox can result in context injection.

OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Improper neutralization of special elements used in an OS command ('OS Command Injection') rules_lgpl_javascript_exec_rule-shelljs-os-command-exec, CWE-78 Severity: Critical

User controlled data in 'shelljs.exec()' can result in Remote OS Command Execution.

OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Improper neutralization of HTTP headers for scripting syntax rules_lgpl_javascript_headers_rule-generic-header-injection, CWE-644 Severity: Critical

Untrusted user input in response header will result in HTTP Header Injection or Response Splitting Attacks.

OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Insufficiently protected credentials rules_lgpl_javascript_jwt_rule-jwt-express-hardcoded, CWE-522 Severity: Critical

Hardcoded JWT secret or private key was found. Hardcoding secrets like JWT signing keys poses a significant security risk.
If the source code ends up in a public repository or is compromised, the secret is exposed. Attackers could then use the secret to
generate forged tokens and access the system. Store it properly in an environment variable.

Here are some recommended safe ways to access JWT secrets:
- Use environment variables to store the secret and access it in code instead of hardcoding. This keeps it out of source control.
- Use a secrets management service to securely store and tightly control access to the secret. Applications can request the secret at runtime.
- For local development, use a .env file that is gitignored and access the secret from process.env.

sample code snippet of accessing JWT secret from env variables

router.route("/auth-route-1").get(
jwt({ secret: process.env.secret, algorithms: ['HS256'] }),
(req, res) => {
res.send('Token is valid');
}
);
OWASP:
  • A02:2021-Cryptographic Failures
  • A3:2017-Sensitive Data Exposure
Use of a broken or risky cryptographic algorithm rules_lgpl_javascript_jwt_rule-node-jwt-none-algorithm, CWE-327 Severity: Critical

Use of {algorithm:'none'} detected with jsonwebtoken.
Using none as the algorithm for jsonwebtoken can directly impact the integrity of the information transfer through the JWT token. Consider using a secure algorithm to sign your JWT token such as HMAC or RSA. Some safe usage examples:

let token = jwt.sign({user:"user1"}, 'secret', {algorithm: 'HS256'});  

Using a secure algorithm can protect the integrity of the token information.
Avoid using none as the algorithm when signing jwt tokens since it can violate the integrity of the JWT information.

OWASP:
  • A02:2021-Cryptographic Failures
  • A3:2017-Sensitive Data Exposure
URL redirection to untrusted site 'open redirect' rules_lgpl_javascript_redirect_rule-express-open-redirect, CWE-601 Severity: Critical

Passing untrusted user input in redirect() can result in an open redirect vulnerability. This could be abused by malicious actors to trick users into
being redirected to websites under their control to capture authentication information.

To prevent open redirect vulnerabilities:

  • Always validate and sanitize user inputs, especially URL parameters
    or query strings that may influence the flow of the application.
  • Use allowlists (lists of permitted URLs) to validate redirect targets
    against known, trusted URLs before performing the redirect.
  • Avoid directly using user input for redirecting. If unavoidable, ensure
    strict validation against an allowlist.

Following is an example of secure validation against allowlist to prevent the vulnerability:
<br/> // Define a list of explicitly allowed URLs for redirection<br/> const allowedUrls = [<br/> 'https://www.example.com/page1',<br/> 'https://www.example.com/page2',<br/> 'https://secure.example.com/page3'<br/> ];</p><p>app.get('/redirect/:url', (req, res) =&gt; {<br/> const url = decodeURIComponent(req.params.url);<br/> const isAllowed = allowedUrls.includes(url);<br/> if (isAllowed) {<br/> // If the URL is allowed, proceed with the redirect<br/> res.redirect(url);<br/> } else {<br/> res.status(400).send('Invalid redirect URL');<br/> }<br/> });<br/>

OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
URL redirection to untrusted site 'open redirect' rules_lgpl_javascript_redirect_rule-express-open-redirect2, CWE-601 Severity: Critical

Passing untrusted user input in redirect() can result in an open redirect vulnerability. This could be abused by malicious actors to trick users into
being redirected to websites under their control to capture authentication information.

To prevent open redirect vulnerabilities:

  • Always validate and sanitize user inputs, especially URL parameters
    or query strings that may influence the flow of the application.
  • Use allowlists (lists of permitted URLs) to validate redirect targets
    against known, trusted URLs before performing the redirect.
  • Avoid directly using user input for redirecting. If unavoidable, ensure
    strict validation against an allowlist.

Following is an example of secure validation against allowlist to prevent the vulnerability:
<br/> // Define a list of explicitly allowed URLs for redirection<br/> const allowedUrls = [<br/> 'https://www.example.com/page1',<br/> 'https://www.example.com/page2',<br/> 'https://secure.example.com/page3'<br/> ];</p><p>app.get('/redirect/:url', (req, res) =&gt; {<br/> const url = decodeURIComponent(req.params.url);<br/> const isAllowed = allowedUrls.includes(url);<br/> if (isAllowed) {<br/> // If the URL is allowed, proceed with the redirect<br/> res.location(url).status(302).end();<br/> } else {<br/> res.status(400).send('Invalid redirect URL');<br/> }<br/> });<br/>

OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Server-side request forgery (SSRF) rules_lgpl_javascript_ssrf_rule-phantom-ssrf, CWE-918 Severity: Critical

'If unverified user data can reach the phantom methods it can result in Server-Side Request Forgery vulnerabilities.

'

OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Server-side request forgery (SSRF) rules_lgpl_javascript_ssrf_rule-playwright-ssrf, CWE-918 Severity: Critical

If unverified user data can reach the puppeteer methods it can result in Server-Side Request Forgery vulnerabilities.

OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Server-side request forgery (SSRF) rules_lgpl_javascript_ssrf_rule-puppeteer-ssrf, CWE-918 Severity: Critical

If unverified user data can reach the puppeteer methods it can result in Server-Side Request Forgery vulnerabilities.

OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Server-side request forgery (SSRF) rules_lgpl_javascript_ssrf_rule-wkhtmltopdf-ssrf, CWE-918 Severity: Critical

User controlled URL reached to wkhtmltopdf can result in Server Side Request Forgery (SSRF).

OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Improper restriction of recursive entity references in DTDs (XML Entity Expansion) rules_lgpl_javascript_xml_rule-node-entity-expansion, CWE-776 Severity: Critical

User controlled data in XML Parsers can result in XML Internal Entity Processing vulnerabilities like in DoS.

OWASP:
  • A05:2021-Security Misconfiguration
  • A4:2017-XML External Entities (XXE)
Improper neutralization of data within XPath expressions (XPath Injection) rules_lgpl_javascript_xml_rule-node-xpath-injection, CWE-643 Severity: Critical

Passing untrusted user input in xpath.parse() can result in XPATH injection vulnerability. This could be abused by malicious actors to execute expressions on on XML files to capture unauthorized information. To prevent XPATH injection vulnerabilities:

  • Always validate and sanitize user inputs, especially parameters or query strings that may influence the flow of the application.
  • Avoid directly using user input for parsing. If unavoidable, ensure strict validation against an allowlist.
  • Use allowlists (lists of permitted expressions) to validate user input
    against known, trusted expressions before performing the parse.

Following is an example of secure validation against allowlist to prevent the vulnerability:

// Define a list of explicitly allowed expressions for parsing const allowedExpr = [
'expression1',
'expression2',
'expression3'
];

app.get('/xml/xpath/1', (req, res) => {
var expression = req.params.exp;
var isAllowed = allowedExpr.includes(expression);
let xml_string = fs.readFileSync("books.xml", "utf8");
var doc = new dom().parseFromString(xml_string, 'text/xml');
if (isAllowed) {
// If the expression is allowed, proceed with the parsing
var evaluator = xpath.parse("//"+expression);
var nodes = evaluator.select({ node: doc });
res.send(nodes[0].firstChild.data);
} else {
res.status(400).send('Invalid expression');
}
});
OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Improper restriction of XML external entity reference rules_lgpl_javascript_xml_rule-node-xxe, CWE-611 Severity: Critical

User controlled data in XML parsers can result in XML External or Internal Entity (XXE) Processing vulnerabilities

OWASP:
  • A05:2021-Security Misconfiguration
  • A4:2017-XML External Entities (XXE)
Improper restriction of XML external entity reference rules_lgpl_javascript_xml_rule-xxe-expat, CWE-611 Severity: Critical

Make sure that unverified user data can not reach the XML Parser, as it can result in XML External or Internal Entity (XXE) Processing vulnerabilities.

OWASP:
  • A05:2021-Security Misconfiguration
  • A4:2017-XML External Entities (XXE)
Command injection using exec() from child_process rule-js-ts-child-process-exec-injection, CWE-78 Severity: High

A Remote Command Injection vulnerability was found using Express or Node.js. A user-controlled input was directly used in exec() function from child_process. This gives the user shell access.

Avoid using user-controlled variables in exec(), or use a whitelist to verify it. Alternatively, use spawn function from 'child_process'.

OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Improper certificate validation rules_lgpl_javascript_database_rule-sequelize-tls-cert-validation, CWE-295 Severity: High

The Sequelize connection string indicates that TLS certificate validation
of database server is disabled. This is equivalent to not having TLS. An
attacker can present any invalid certificate and Sequelize will make database
connection ignoring certificate errors. This setting make the connection susceptible to man in the middle (MITM) attacks. Not applicable to SQLite database.

OWASP:
  • A02:2021-Cryptographic Failures
  • A3:2017-Sensitive Data Exposure
Improper neutralization of directives in dynamically evaluated code ('Eval Injection') rules_lgpl_javascript_eval_rule-eval-nodejs, CWE-95 Severity: High

User controlled data in eval() or similar functions may result in Server Side Injection or Remote Code Injection

OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Use of hard-coded credentials rules_lgpl_javascript_jwt_rule-hardcoded-jwt-secret, CWE-798 Severity: High

Hardcoded JWT secret or private key was found. Hardcoding secrets like JWT signing keys poses a significant security risk.
If the source code ends up in a public repository or is compromised, the secret is exposed. Attackers could then use the secret to
generate forged tokens and access the system. Store it properly in an environment variable.

Here are some recommended safe ways to access JWT secrets:
- Use environment variables to store the secret and access it in code instead of hardcoding. This keeps it out of source control.
- Use a secrets management service to securely store and tightly control access to the secret. Applications can request the secret at runtime.
- For local development, use a .env file that is gitignored and access the secret from process.env.

sample code snippet of accessing JWT secret from env variables

 const token = jwt.sign(payload, process.env.SECRET, { algorithm: 'HS256' });
OWASP:
  • A02:2021-Cryptographic Failures
  • A3:2017-Sensitive Data Exposure
Insufficiently protected credentials rules_lgpl_javascript_jwt_rule-jwt-exposed-credentials, CWE-522 Severity: High

The application is storing a password in the JWT token payload. Storing
passwords in JWT token payloads is an insecure practice that can lead to
compromised credentials.

The password transmitted in the JWT payload is not encrypted and therefore
visible to anyone who intercepts the token. It is recommended to avoid storing
sensitive information like passwords in JWTs. Instead, reference user identifiers
that map to credentials stored securely on the server.This helps to mitigate the
risk of exposing passwords through JWT tokens that could be intercepted or leaked.

Secure code example of secure JWT signing:

router.route("/jsonwebtoken/1").get((req, res) => {
// any payload without passwords or any other sensitive data will be secure
const payload = { user_id: 123, username: 'john_doe' };
const token = jwt.sign(payload, secretKey, { algorithm: 'HS256' });
console.log('Generated Token:', token);
res.send({ token })
})
OWASP:
  • A02:2021-Cryptographic Failures
  • A3:2017-Sensitive Data Exposure
Insufficiently protected credentials rules_lgpl_javascript_jwt_rule-jwt-exposed-data, CWE-522 Severity: High

The object is passed strictly to jose.JWT.sign(...). Make sure that sensitive information is not exposed through JWT token payload.

OWASP:
  • A02:2021-Cryptographic Failures
  • A3:2017-Sensitive Data Exposure
Insufficiently protected credentials rules_lgpl_javascript_jwt_rule-jwt-not-revoked, CWE-522 Severity: High

No token revoking configured for express-jwt. A leaked token could still be used and unable to be revoked. Consider using function as the isRevoked option.

OWASP:
  • A02:2021-Cryptographic Failures
  • A3:2017-Sensitive Data Exposure
Server-side request forgery (SSRF) rules_lgpl_javascript_ssrf_rule-node-ssrf, CWE-918 Severity: High

This application allows user-controlled URLs to be passed directly to HTTP client libraries.
This can result in Server-Side Request Forgery (SSRF). SSRF refers to an attack where the attacker can abuse functionality on
the server to force it to make requests to other internal systems within your
infrastructure that are not directly exposed to the internet.
This allows the attacker to access internal resources they do not have direct access to.

Some risks of SSRF are:

  • Access and manipulation of internal databases, APIs, or administrative panels
  • Ability to scan internal network architecture and services
  • Can be used to pivot attacks into the internal network
  • Circumvent network segregation and firewall rules

To avoid this, try using hardcoded HTTP request calls or a whitelisting object to
check whether the user input is trying to access allowed resources or not.

Here is an example:

var whitelist = [
"https://example.com",
"https://example.com/sample"
]

app.get('/ssrf/node-ssrf/axios/safe/3', function (req, res) {
if(whitelist.includes(req.query.url)){
axios.get(url, {})
.then(function (response) {
console.log(response);
})
.catch(function (response) {
console.log(response);
})
}
});

For more information on SSRF see OWASP: Server_Side_Request_Forgery_Prevention_Cheat_Sheet.html

OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Out-of-bounds read javascript_buf_rule-buffer-noassert-read, CWE-125 Severity: Medium

The application is using Buffer API methods with the noAssert
parameter set to true for the read buffer methods. This disables
the bounds checking and could result in reading beyond the end of
the buffer, leading to potential memory corruption and security
vulnerabilities. When noAssert is set to true, the methods
do not perform bounds checking, allowing the offset to be beyond
the end of the buffer. This can lead to out-of-bounds memory access,
causing undefined behavior, crashes, or potential security exploits.

To mitigate the issue, ensure that the noAssert parameter is not
set to true. Always use bounds checking to prevent out-of-bounds
memory access. Validate the offset before performing read operations
on the buffer.

Secure Code Example:

  const buffer = Buffer.alloc(10); // Allocate a buffer of 10 bytes

function safeBufferMethods(buf) {
const safeOffset = 5; // An offset within the bounds of the buffer

// Secure read methods
if (safeOffset < buf.length) {
buf.readUInt8(safeOffset);
buf.readUInt16LE(safeOffset);
buf.readUInt16BE(safeOffset);
buf.readUInt32LE(safeOffset);
buf.readUInt32BE(safeOffset);
buf.readInt8(safeOffset);
buf.readInt16LE(safeOffset);
buf.readInt16BE(safeOffset);
buf.readInt32LE(safeOffset);
buf.readInt32BE(safeOffset);
buf.readFloatLE(safeOffset);
buf.readFloatBE(safeOffset);
buf.readDoubleLE(safeOffset);
buf.readDoubleBE(safeOffset);
}
}
try {
safeBufferMethods(buffer);
} catch (error) {
console.error('Caught an error:', error);
}
OWASP:
  • A05:2021-Security Misconfiguration
  • A6:2017-Security Misconfiguration
Out-of-bounds write javascript_buf_rule-buffer-noassert-write, CWE-787 Severity: Medium

The application is using Buffer API methods with the noAssert
parameter set to true for the write buffer methods. This disables
the bounds checking and could result in writing beyond the end of
the buffer, leading to potential memory corruption and security
vulnerabilities. When noAssert is set to true, the methods
do not perform bounds checking, allowing the offset to be beyond
the end of the buffer. This can lead to out-of-bounds memory access,
causing undefined behavior, crashes, or potential security exploits.

To mitigate the issue, ensure that the noAssert parameter is not
set to true. Always use bounds checking to prevent out-of-bounds
memory access. Validate the offset before performing write operations
on the buffer.

Secure Code Example:

  const buffer = Buffer.alloc(10); // Allocate a buffer of 10 bytes

function safeBufferMethods(buf) {
const safeOffset = 5; // An offset within the bounds of the buffer

// Secure write methods
if (safeOffset < buf.length) {
buf.writeUInt8(0, safeOffset);
buf.writeUInt16LE(0, safeOffset);
buf.writeUInt16BE(0, safeOffset);
buf.writeUInt32LE(0, safeOffset);
buf.writeUInt32BE(0, safeOffset);
buf.writeInt8(0, safeOffset);
buf.writeInt16LE(0, safeOffset);
buf.writeInt16BE(0, safeOffset);
buf.writeInt32LE(0, safeOffset);
buf.writeInt32BE(0, safeOffset);
buf.writeFloatLE(0, safeOffset);
buf.writeFloatBE(0, safeOffset);
buf.writeDoubleLE(0, safeOffset);
buf.writeDoubleBE(0, safeOffset);
}
}

try {
safeBufferMethods(buffer);
} catch (error) {
console.error('Caught an error:', error);
}
OWASP:
  • A05:2021-Security Misconfiguration
  • A6:2017-Security Misconfiguration
Observable timing discrepancy javascript_timing_rule-possible-timing-attacks, CWE-208 Severity: Medium

The application was found executing string comparisons using one of ===, !, or !=
against security sensitive values. String comparisons like this are not constant time, meaning the first character found not to match in the two strings will immediately exit the conditional statement. This allows an adversary to calculate or observe small timing differences depending on the strings passed to this comparison. This potentially allows an adversary the ability to brute force a string that will match the expected value by monitoring different character values.

To remediate this issue, use the crypto.timingSafeEqual method when comparing strings.

Example using crypto.timingSafeEqual to safely compare strings:

function constantTimeIsPasswordEqual(userInput) {
// Retrieve the password from a secure data store such as a KMS or Hashicorp's vault.
const password = getPasswordFromSecureDataStore();
// Use crypto timingSafeEqual to ensure the comparison is done in constant time.
return crypto.timingSafeEqual(Buffer.from(userInput, 'utf-8'), Buffer.from(password,
'utf-8'));
}
For more information on constant time comparison see:
crypto.html
OWASP:
  • A02:2021-Cryptographic Failures
  • A3:2017-Sensitive Data Exposure
Use of a broken or risky cryptographic algorithm rules_lgpl_javascript_crypto_rule-node-aes-ecb, CWE-327 Severity: Medium

AES with ECB mode is deterministic in nature and not suitable for encrypting large amount of repetitive data.

OWASP:
  • A02:2021-Cryptographic Failures
  • A3:2017-Sensitive Data Exposure
Use of a broken or risky cryptographic algorithm rules_lgpl_javascript_crypto_rule-node-aes-noiv, CWE-327 Severity: Medium

AES algorithms requires an initialization vector (IV). Providing no or null IV in some implementation results to a 0 IV. Use of a deterministic IV makes dictionary attacks easier.

OWASP:
  • A02:2021-Cryptographic Failures
  • A3:2017-Sensitive Data Exposure
Use of cryptographically weak pseudo-random number generator (PRNG) rules_lgpl_javascript_crypto_rule-node-insecure-random-generator, CWE-338 Severity: Medium

This rule identifies use of cryptographically weak random number generators. Using cryptographically weak random number generators like crypto.pseudoRandomBytes()
and Math.random() for security-critical tasks can expose systems to significant
vulnerabilities. Attackers might predict the generated random numbers, compromising
the integrity and confidentiality of cryptographic operations. This could lead to
breaches where sensitive data is accessed or manipulated, authentication mechanisms
are bypassed, or secure communications are intercepted, ultimately undermining the
security of the entire system or application.

Mitigation strategy:
Replace the use of these cryptographically weak random number generators with
crypto.randomBytes(), a method provided by Node.js's crypto module that
generates cryptographically secure random numbers. This method should be used
for all operations requiring secure randomness, such as generating keys, tokens,
or any cryptographic material.

Secure Code Example:

const crypto = require('crypto');
const secureBytes = crypto.randomBytes(256);
console.log(Secure random bytes: ${secureBytes.toString('hex')});
OWASP:
  • A02:2021-Cryptographic Failures
  • A3:2017-Sensitive Data Exposure
Use of weak hash rules_lgpl_javascript_crypto_rule-node-md5, CWE-328 Severity: Medium

The MD5 hashing algorithm is considered cryptographically weak and
vulnerable to collision attacks, where two different inputs generate
the same output hash. When used for hashing sensitive data, attackers
can exploit this weakness to generate collisions, allowing them to bypass
security checks or masquerade malicious data as legitimate. This
vulnerability is particularly critical in authentication mechanisms,
digital signatures, SSL/TLS certificates, and data integrity checks.

Remediation:
To mitigate this vulnerability, replace the MD5 hashing algorithm with
stronger cryptographic hash functions, such as SHA-256 or SHA-3. These
algorithms offer significantly improved security and are resistant to
collision attacks, making them suitable for cryptographic purposes in
modern applications.

Secure Code example :

const crypto = require('crypto');
const hash = crypto.createHash('sha256').update('sensitive data').digest('hex');
console.log(hash);
OWASP:
  • A02:2021-Cryptographic Failures
  • A3:2017-Sensitive Data Exposure
Use of weak hash rules_lgpl_javascript_crypto_rule-node-sha1, CWE-328 Severity: Medium

The SHA-1 hashing algorithm is no longer considered secure for cryptographic applications due to its vulnerability to collision attacks, where two different inputs produce the same output hash. SHA-1's susceptibility to collision attacks undermines the security of cryptographic operations, allowing attackers to forge signatures or manipulate data without detection. This poses significant risks in authentication systems, data integrity validations, and secure communications.

Remediation: To mitigate this vulnerability, replace the SHA1 hashing
algorithm with stronger cryptographic hash functions, such as SHA-256
or SHA-3. These algorithms offer significantly improved security and
are resistant to collision attacks, making them suitable for cryptographic
purposes in modern applications.

Secure Code example:

const crypto = require('crypto');  
const hash = crypto.createHash('sha256').update('sensitive data').digest('hex');
console.log(hash);
OWASP:
  • A02:2021-Cryptographic Failures
  • A3:2017-Sensitive Data Exposure
Observable timing discrepancy rules_lgpl_javascript_crypto_rule-node-timing-attack, CWE-208 Severity: Medium

'String comparisons using ''==='', ''!'', ''!='' and '''' is vulnerable to timing attacks. More info: '

OWASP:
  • A02:2021-Cryptographic Failures
  • A3:2017-Sensitive Data Exposure
Improper Certificate Validation rules_lgpl_javascript_crypto_rule-node-tls-reject, CWE-295 Severity: Medium

The application sets NODE_TLS_REJECT_UNAUTHORIZED to '0', which instructs Node.js to disable TLS/SSL certificate validation.
This configuration allows the application to accept self-signed certificates or certificates from untrusted authorities,
undermining the TLS security model. Disabling TLS/SSL certificate validation compromises the integrity and confidentiality
of data in transit between the client and server. It makes the application vulnerable to man-in-the-middle (MITM) attacks,
where an attacker could intercept or alter the data being exchanged.

Mitigation Strategy:
Do not disable TLS/SSL certificate validation in production environments. Ensure that NODE_TLS_REJECT_UNAUTHORIZED is
set to '1' or is removed entirely from the production configuration (as the default configuration of validating SSL
certificate is safe).

Secure Code Example:

const https = require('https')
process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = '1'
const req = https.request(options, res => {
let data = ''
res.on('data', chunk => {
data += chunk
})
res.on('end', () => {
console.log('Response Body:', data)
})
})
req.end()
OWASP:
  • A05:2021-Security Misconfiguration
  • A6:2017-Security Misconfiguration
Use of a broken or risky cryptographic algorithm rules_lgpl_javascript_crypto_rule-node-weak-crypto, CWE-327 Severity: Medium

A weak or broken cryptographic algorithm was identified. Using these functions will introduce vulnerabilities or downgrade the security of your application.

OWASP:
  • A02:2021-Cryptographic Failures
  • A3:2017-Sensitive Data Exposure
Cleartext transmission of sensitive information rules_lgpl_javascript_database_rule-sequelize-tls, CWE-319 Severity: Medium

'The Sequelize connection string indicates that database server does not use TLS. Non TLS connections are susceptible to man in the middle (MITM) attacks.'

OWASP:
  • A02:2021-Cryptographic Failures
  • A3:2017-Sensitive Data Exposure
Unchecked input for loop condition rules_lgpl_javascript_dos_rule-layer7-object-dos, CWE-606 Severity: Medium

This application is looping over user controlled objects, which can lead to a layer 7 denial of service vulnerability.

A layer 7 denial of service attack refers to overloading the application layer of the OSI model, typically layer 7.
This can happen when user-controlled input such as objects, arrays, strings, etc. are iterated or looped over without proper validation or limits in place.

For example, if a user can control the size of an array or object passed into the application,
they could create an extremely large input that gets looped over. This would consume excessive CPU cycles or memory,
potentially crashing or slowing down the application.

To prevent this, limits should be set on the number of iterations, input sizes, recursion depth, etc.

Sample case of secure array looped over with user-controlled input

// Potential DoS if req.body.list.length is large. app.post('/dos/layer7-object-dos/for-loop/1', function (req, res) {
var list = req.body.list;
for (let i = 0; i <= 10; i++) {
if(!list[i]){
// return;
}
}
res.send("res")
});

Implementing protections against layer 7 denial of service attacks is important for securing modern web applications and APIs.

OWASP:
  • A05:2021-Security Misconfiguration
  • A6:2017-Security Misconfiguration
Incorrect regular expression rules_lgpl_javascript_dos_rule-regex-dos, CWE-185 Severity: Medium

Ensure that the regex used to compare with user supplied input is safe from regular expression denial of service.

OWASP:
  • A05:2021-Security Misconfiguration
  • A6:2017-Security Misconfiguration
Least privilege violation rules_lgpl_javascript_electronjs_rule-electron-blink-integration, CWE-272 Severity: Medium

Blink's expirimental features are enabled in this application. Some of the features may affect the security of the application.

OWASP:
  • A05:2021-Security Misconfiguration
  • A6:2017-Security Misconfiguration
Improperly controlled modification of object prototype attributes ('Prototype Pollution') rules_lgpl_javascript_electronjs_rule-electron-context-isolation, CWE-1321 Severity: Medium

Disabling context isolation can introduce Prototype Pollution vulnerabilities.

OWASP:
  • A05:2021-Security Misconfiguration
  • A6:2017-Security Misconfiguration
Least privilege violation rules_lgpl_javascript_electronjs_rule-electron-nodejs-integration, CWE-272 Severity: Medium

Node integration exposes node.js APIs to the electron app and this can introduce remote code execution vulnerabilities to the application if the app is vulnerable to Cross Site Scripting (XSS).

OWASP:
  • A05:2021-Security Misconfiguration
  • A6:2017-Security Misconfiguration
Sensitive cookie without 'HttpOnly' flag rules_lgpl_javascript_headers_rule-cookie-session-no-httponly, CWE-1004 Severity: Medium

'Session middleware settings: httpOnly is explicitly set to false. It ensures that sensitive cookies cannot be accessed by client side JavaScript and helps to protect against cross-site scripting attacks.'

OWASP:
  • A07:2021-Identification and Authentication Failures
  • A2:2017-Broken Authentication
Sensitive cookie with improper SameSite attribute rules_lgpl_javascript_headers_rule-cookie-session-no-samesite, CWE-1275 Severity: Medium

'Default session middleware settings: sameSite attribute is not configured to strict or lax. These configurations provides protection against Cross Site Request Forgery attacks.'

OWASP:
  • A07:2021-Identification and Authentication Failures
  • A2:2017-Broken Authentication
Sensitive cookie in HTTPS session without 'Secure' attribute rules_lgpl_javascript_headers_rule-cookie-session-no-secure, CWE-614 Severity: Medium

'Default session middleware settings: secure not set. It ensures the browser only sends the cookie over HTTPS.'

OWASP:
  • A07:2021-Identification and Authentication Failures
  • A2:2017-Broken Authentication
Origin validation error rules_lgpl_javascript_headers_rule-express-cors, CWE-346 Severity: Medium

Access-Control-Allow-Origin response header is set to "". This will disable CORS Same Origin Policy restrictions.

OWASP:*
  • A05:2021-Security Misconfiguration
  • A6:2017-Security Misconfiguration
Origin validation error rules_lgpl_javascript_headers_rule-generic-cors, CWE-346 Severity: Medium

Access-Control-Allow-Origin response header is set to "". This will disable CORS Same Origin Policy restrictions.

OWASP:*
  • A05:2021-Security Misconfiguration
  • A6:2017-Security Misconfiguration
Improperly implemented security check for standard rules_lgpl_javascript_headers_rule-header-xss-generic, CWE-358 Severity: Medium

X-XSS-Protection header is set to 0. This will disable the browser's XSS Filter.

OWASP:
  • A05:2021-Security Misconfiguration
  • A6:2017-Security Misconfiguration
Improperly implemented security check for standard rules_lgpl_javascript_headers_rule-header-xss-lusca, CWE-358 Severity: Medium

X-XSS-Protection header is set to 0. This will disable the browser's XSS Filter.

OWASP:
  • A05:2021-Security Misconfiguration
  • A6:2017-Security Misconfiguration
Improperly implemented security check for standard rules_lgpl_javascript_headers_rule-helmet-feature-disabled, CWE-358 Severity: Medium

One or more Security Response header is explicitly disabled in Helmet.

OWASP:
  • A05:2021-Security Misconfiguration
  • A6:2017-Security Misconfiguration
Use of less trusted source rules_lgpl_javascript_headers_rule-host-header-injection, CWE-348 Severity: Medium

Using untrusted Host header for generating dynamic URLs can result in web cache and or password reset poisoning.

OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Server-side request forgery (SSRF) rules_lgpl_javascript_ssrf_rule-wkhtmltoimage-ssrf, CWE-918 Severity: Medium

This rule detects instances where user-controlled URLs are passed directly to the generate function of wkhtmltoimage library. This practice can lead to Server Side Request Forgery (SSRF) vulnerabilities, where an attacker can induce the server to make requests to arbitrary URLs. This can potentially expose internal services within the network or lead to information disclosure.

To mitigate this vulnerability, ensure that URLs are safe and intended for
public access. Implementing allowlists for acceptable domains or schemes can
significantly reduce the risk of SSRF. Additionally, consider using server-side
proxy services that restrict the outgoing requests to trusted domains and
resources.

Secure Code Example:

const wkhtmltoimage = require('wkhtmltoimage');

// Define an allowlist of domains const allowedDomains = ['example.com', 'trusted-source.com'];

app.post('/generate-image', (req, res) => {
const userInputUrl = req.body.url;
const parsedUrl = new URL(userInputUrl);

// Check if the domain is in the allowlist
if (allowedDomains.includes(parsedUrl.hostname)) {
wkhtmltoimage.generate(userInputUrl, { output: 'output.jpg' },
function (err, stream) {
if (err) {
return res.status(500).send('Error generating image');
}
// Send a success response or the image itself
res.status(200).send('Image generated successfully');
});
} else {
res.status(400).send('URL is not allowed due to security policies.');
}
});
OWASP:
  • A10:2021-Server-Side Request Forgery
  • A1:2017-Injection
Improper limitation of a pathname to a restricted directory ('Path Traversal') rules_lgpl_javascript_traversal_rule-admzip-path-overwrite, CWE-22 Severity: Medium

Insecure ZIP archive extraction using adm-zip can result in arbitrary path over write and can result in code injection.

OWASP:
  • A01:2021-Broken Access Control
  • A5:2017-Broken Access Control
Relative path traversal rules_lgpl_javascript_traversal_rule-express-lfr, CWE-23 Severity: Medium

This application is using untrusted user input in express render() function. Rendering templates with untrusted user input enables arbitrary file read
vulnerabilities when using templating engines like Handlebars (hbs).

An attacker can craft malicious input that traverses the filesystem and exposes sensitive files.
Consider sanitizing and validating all user input before passing it to render() to prevent arbitrary file reads.

Sample safe use of express.render function

app.get("/traversal/2", async (req, res) => {
var indexPath = "index";
res.render(indexPath, { title: "Index Page" })
});

For more details see: Path_Traversal

OWASP:
  • A01:2021-Broken Access Control
  • A5:2017-Broken Access Control
Relative path traversal rules_lgpl_javascript_traversal_rule-express-lfr-warning, CWE-23 Severity: Medium

Untrusted user input in express render() function can result in arbitrary file read if hbs templating is used.

OWASP:
  • A01:2021-Broken Access Control
  • A5:2017-Broken Access Control
Relative path traversal rules_lgpl_javascript_traversal_rule-generic-path-traversal, CWE-23 Severity: Medium

This application is using untrusted user input with the readFile() and readFileSync() functions.
This can lead to directory traversal attacks, as reading files with untrusted input enables arbitrary file access. An attacker could craft malicious input that traverses the file system and exposes sensitive files.
Please consider sanitizing and validating all user input before passing it to readFile() or readFileSync() to prevent unwanted file reads. Here is an example of a safer usage in readFileAsync():

app.get('/foo', function (req, res) {
var fileName = config.dirName + '/' + data;
fs.readFileAsync("fileName")
.then(function (data) {
res.download(fileName, downloadFileName);
})
})

For more details see: Path_Traversal

OWASP:
  • A01:2021-Broken Access Control
  • A5:2017-Broken Access Control
Improper limitation of a pathname to a restricted directory ('Path Traversal') rules_lgpl_javascript_traversal_rule-join-resolve-path-traversal, CWE-22 Severity: Medium

'Path constructed with user input can result in Path Traversal. Ensure that user input does not reach join() or resolve(). '

OWASP:
  • A01:2021-Broken Access Control
  • A5:2017-Broken Access Control
Improper limitation of a pathname to a restricted directory ('Path Traversal') rules_lgpl_javascript_traversal_rule-tar-path-overwrite, CWE-22 Severity: Medium

Insecure TAR archive extraction can result in arbitrary path over write and can result in code injection.

OWASP:
  • A01:2021-Broken Access Control
  • A5:2017-Broken Access Control
Improper limitation of a pathname to a restricted directory ('Path Traversal') rules_lgpl_javascript_traversal_rule-zip-path-overwrite, CWE-22 Severity: Medium

This application is extracting ZIP archives without sanitizing paths or writing files to a dedicated extraction directory.
This allows attackers to overwrite sensitive files or inject malicious code by manipulating TAR archive contents.

To fix, sanitize all paths from ZIP archives before writing extracted files using path.basename and path.join.

Example of extracting tar files safely:

app.get("/extract", async (req, res) => {
fs.createReadStream(zipPath)
.pipe(unzipper.Parse())
.on('entry', entry => {
const directory = 'assets/tar/extracted/';
const filename = entry.path;
entry.pipe(fs.createWriteStream(path.join(directory, filename)));
});
});

Write extracted files only to a dedicated extraction directory, not the global filesystem. Limit extracts to allowed file type.

See OWASP Path Traversal (https://owasp.org/www-community/attacks/Path_Traversal) and Unrestricted Upload of File with
Dangerous Type (https://owasp.org/www-community/vulnerabilities/Unrestricted_File_Upload) for more details.

OWASP:
  • A01:2021-Broken Access Control
  • A5:2017-Broken Access Control
Improper neutralization of input during web page generation ('Cross-site Scripting') rules_lgpl_javascript_xss_rule-express-xss, CWE-79 Severity: Medium

This application accepts user input directly from the client side without validation.
This could lead to Cross Site Scripting (XSS) if the input contains malicious script code and
the application server does not properly escape or sanitize the output.

Consider encoding input data before sending it to the client side.

// safe method of sending user input data router.get('/safe/1', (req, res) => {
var name = encodeURI(req.query.name);
res.send(name);
})

XSS is an attack that exploits a web application or system to treat user input as markup or script code.
It is important to encode the data depending on the specific context in which it is used.

OWASP:
  • A03:2021-Injection
  • A7:2017-Cross-Site Scripting (XSS)
Improper neutralization of script-related HTML tags in a web page (basic XSS) rules_lgpl_javascript_xss_rule-handlebars-noescape, CWE-80 Severity: Medium

This application is compiling strings with Handlebars.compile using an insecure option of {noEscape: true}. This configuration bypasses the default behavior of
Handlebars, which is to escape input values to prevent Cross-Site Scripting (XSS)
attacks.
XSS attacks are a type of security breach that occurs when an attacker manages to
inject malicious scripts into web pages viewed by other users. These scripts can then
execute in the context of the victim's session, allowing the attacker to bypass access
controls and potentially access sensitive information or perform actions on behalf of the

user. It is important to encode the data depending on the specific context it is used in.

By default, Handlebars.compile escapes input values to prevent XSS attacks.
Consider using Handlebars.compile with default settings or set {noEscape: false}
to force encoding of input data.

Example of using Handlebars.compile safely:

var template = "This is {{target}}";
var out = Handlebars.compile(template)({target: req.query.message});
res.send(out);
OWASP:
  • A03:2021-Injection
  • A7:2017-Cross-Site Scripting (XSS)
Improper neutralization of input during web page generation (Cross-site Scripting) rules_lgpl_javascript_xss_rule-handlebars-safestring, CWE-79 Severity: Medium

This application is using a vulnerable method Handlebars.SafeString(...). Handlebars SafeString method does not escape the data passed through it.
Untrusted user input passing through SafeString method can make the application
vulnerable to Cross-Site Scripting (XSS) attacks.

XSS attacks are a type of security breach that occurs when an attacker manages to
inject malicious scripts into web pages viewed by other users. These scripts can then
execute in the context of the victim's session, allowing the attacker to bypass access
controls and potentially access sensitive information or perform actions on behalf of the

user. It is important to encode the data depending on the specific context it is used in.

Consider using the Handlebars.escapeExpression method to escape user input while
constructing SafeString to avoid potential security concerns. Following is a secure code
example.

  var returnObj = new Handlebars.SafeString("<h1>Handlebars safe string</h1>" +  Handlebars.escapeExpression(req.query.message))
res.send(returnObj.string)
OWASP:
  • A03:2021-Injection
  • A7:2017-Cross-Site Scripting (XSS)
Improper neutralization of input during web page generation ('Cross-site Scripting') rules_lgpl_javascript_xss_rule-squirrelly-autoescape, CWE-79 Severity: Medium

This application is rendering HTML with vulnerable
configurations by setting Sqrl.autoEscaping(false) in squirrelly.

This could lead to Cross Site Scripting (XSS) if the input is malicious
script code and the application server is not properly validating the output.

// safe use of squirrelly render var myTemplate = "<p>My Message is: {{message}}</p>"
Sqrl.Render(myTemplate, {message: req.query.message})

XSS is an attack that exploits a web application or system to treat user input as markup or script code.
It is important to encode the data depending on the specific context it is used in.

By default, squirrelly autoEscaping(true) escapes input values to prevent XSS attacks.
Consider using squirrelly with default autoEscaping settings.

OWASP:
  • A03:2021-Injection
  • A7:2017-Cross-Site Scripting (XSS)
Improper encoding or escaping of output rules_lgpl_javascript_xss_rule-xss-disable-mustache-escape, CWE-116 Severity: Medium

Markup escaping disabled. This can be used with some template engines to escape disabling of HTML entities, which can lead to XSS attacks.

OWASP:
  • A03:2021-Injection
  • A7:2017-Cross-Site Scripting (XSS)
Improper neutralization of script-related HTML tags in a web page (basic XSS) rules_lgpl_javascript_xss_rule-xss-serialize-javascript, CWE-80 Severity: Medium

This application is serializing Javascript objects with vulnerable
configurations by setting {unsafe: true} in serialize-javascript.

This could lead to Cross Site Scripting (XSS) if the input was malicious
script code and the application server is not properly validating the output.

// safe use of serialize-javascript const jsObj = serialize({
foo: htmlResponse
}
);

XSS is an attack which exploits a web application or system to treat user input as markup or script code.
It is important to encode the data depending on the specific context it is used in.

By default, serialize-javascript encodes input values to prevent XSS attacks.
Consider using serialize-javascript with default settings or set {unsafe: false} to encode input data.

OWASP:
  • A03:2021-Injection
  • A7:2017-Cross-Site Scripting (XSS)
Insufficiently protected credentials rules_lgpl_javascript_headers_rule-cookie-session-default, CWE-522 Severity: Info

Consider changing the default session cookie name. An attacker can use it to fingerprint the server and target attacks accordingly.

OWASP:
  • A07:2021-Identification and Authentication Failures
  • A2:2017-Broken Authentication
Insufficiently protected credentials rules_lgpl_javascript_headers_rule-cookie-session-no-domain, CWE-522 Severity: Info

'Default session middleware settings: domain not set. It indicates the domain of the cookie; use it to compare against the domain of the server in which the URL is being requested. If they match, then check the path attribute next.'

OWASP:
  • A07:2021-Identification and Authentication Failures
  • A2:2017-Broken Authentication
Insufficient session expiration rules_lgpl_javascript_headers_rule-cookie-session-no-maxage, CWE-613 Severity: Info

'Session middleware settings: maxAge not set. Use it to set expiration date for cookies.'

OWASP:
  • A07:2021-Identification and Authentication Failures
  • A2:2017-Broken Authentication
Insufficiently protected credentials rules_lgpl_javascript_headers_rule-cookie-session-no-path, CWE-522 Severity: Info

'Default session middleware settings: path not set. It indicates the path of the cookie; use it to compare against the request path. If this and domain match, then send the cookie in the request.'

OWASP:
  • A07:2021-Identification and Authentication Failures
  • A2:2017-Broken Authentication

javascript, typescript

Name Identifiers Description
Deserialization of Untrusted Data rules_lgpl_javascript_eval_rule-grpc-insecure-connection, CWE-502 Severity: Critical

Found an insecure gRPC connection. This creates a connection without encryption to a gRPC client/server. A malicious attacker could tamper with the gRPC message, which could compromise the machine.

OWASP:
  • A08:2021-Software and Data Integrity Failures
  • A8:2017-Insecure Deserialization
Deserialization of Untrusted Data rules_lgpl_javascript_eval_rule-node-deserialize, CWE-502 Severity: Critical

User controlled data in 'unserialize()' or 'deserialize()' function can result in Object Injection or Remote Code Injection.

OWASP:
  • A08:2021-Software and Data Integrity Failures
  • A8:2017-Insecure Deserialization
Deserialization of Untrusted Data rules_lgpl_javascript_eval_rule-serializetojs-deserialize, CWE-502 Severity: Critical

User controlled data in 'unserialize()' or 'deserialize()' function can result in Object Injection or Remote Code Injection.

OWASP:
  • A08:2021-Software and Data Integrity Failures
  • A8:2017-Insecure Deserialization
Deserialization of Untrusted Data rules_lgpl_javascript_eval_rule-yaml-deserialize, CWE-502 Severity: Critical

User controlled data in 'yaml.load()' function can result in Remote Code Injection.

OWASP:
  • A08:2021-Software and Data Integrity Failures
  • A8:2017-Insecure Deserialization
Improper neutralization of directives in dynamically evaluated code ('Eval Injection') javascript_eval_rule-eval-with-expression, CWE-95 Severity: High

The application was found calling the eval function OR Function()
constructor OR setTimeout() OR setInterval() methods. If the

variables or strings or functions passed to these methods contains user-supplied input, an adversary could attempt to execute arbitrary

JavaScript

code. This could lead to a full system compromise in Node applications or Cross-site Scripting

(XSS) in web applications.

To remediate this issue, remove all calls to above methods and consider alternative methods for

executing

the necessary business logic. There is almost no safe method of calling eval or other above stated sinks with

user-supplied input.

Instead, consider alternative methods such as using property accessors to dynamically access

values.

Example using property accessors to dynamically access an object's property:

</p><p>// Define an object</p><p>const obj = {key1: 'value1', key2: 'value2'};</p><p>// Get key dynamically from user input</p><p>const key = getUserInput();</p><p>// Check if the key exists in our object and return it, or a default empty string</p><p>const value = (obj.hasOwnProperty(key)) ? obj[key] : '';</p><p>// Work with the value</p><p>

For more information on why not to use eval, and alternatives see:

eval!

Other References:

Function

setTimeout

setInterval

OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Allocation of resources without limits or throttling javascript_buf_rule-detect-new-buffer, CWE-770 Severity: Medium

The application was found calling the new Buffer constructor which has been deprecated since Node 8. By passing in a non-literal value, an adversary could allocate large amounts of memory.

Other issues also exist with the Buffer constructor:
- Older versions would return uninitialized memory, which could contain sensitive information
- Unable to easily determine what a Buffer contained if passed a non-literal value

To remediate this issue, use Buffer.alloc or Buffer.from instead to allocate a new
Buffer.

Example using Buffer.alloc instead of new Buffer(...):

// Create a new buffer using Buffer.from const buf = Buffer.from([1, 2, 3, 4]);
// Work with buf
For more information on migrating to Buffer.from()/Buffer.alloc() see:
buffer-constructor-deprecation
OWASP:
  • A06:2021-Vulnerable and Outdated Components
  • A9:2017-Using Components with Known Vulnerabilities
Regular expression with non-literal value javascript_dos_rule-non-literal-regexp, CWE-185 Severity: Medium

The RegExp constructor was called with a non-literal value. If an adversary were able to supply a malicious regex, they could cause a Regular Expression Denial of Service (ReDoS)
against the application. In Node applications, this could cause the entire application to no longer be responsive to other users' requests.

To remediate this issue, never allow user-supplied regular expressions. Instead, the regular
expression should be hardcoded. If this is not possible, consider using an alternative regular expression engine such as node-re2. RE2 is a safe alternative
that does not support backtracking, which is what leads to ReDoS.

Example using re2 which does not support backtracking (Note: it is still recommended to never use user-supplied input):

// Import the re2 module const RE2 = require('re2');

function match(userSuppliedRegex, userInput) {
// Create a RE2 object with the user supplied regex, this is relatively safe
// due to RE2 not supporting backtracking which can be abused to cause long running
// queries
var re = new RE2(userSuppliedRegex);
// Execute the regular expression against some userInput
var result = re.exec(userInput);
// Work with the result
}
For more information on Regular Expression DoS see:
Regular_expression_Denial_of_Service_-_ReDoS
OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Improper limitation of a pathname to a restricted directory ('Path Traversal') javascript_pathtraversal_rule-non-literal-fs-filename, CWE-22 Severity: Medium

The application dynamically constructs file or path information. If the path information comes from user-supplied input, it could be abused to read sensitive files, access other users' data, or aid in exploitation to gain further system access.

User input should never be used in constructing paths or files for interacting with the filesystem. This includes filenames supplied by user uploads or downloads. If possible, consider hashing user input or using unique values and use path.normalize to resolve and validate the path information prior to processing any file functionality.

Example using path.normalize and not allowing direct user input:

// User input, saved only as a reference
// id is a randomly generated UUID to be used as the filename const userData = {userFilename: userSuppliedFilename, id: crypto.randomUUID()};
// Restrict all file processing to this directory only const basePath = '/app/restricted/';

// Create the full path, but only use our random generated id as the filename const joinedPath = path.join(basePath, userData.id);
// Normalize path, removing any '..'
const fullPath = path.normalize(joinedPath);
// Verify the fullPath is contained within our basePath if (!fullPath.startsWith(basePath)) {
console.log("Invalid path specified!");
}
// Process / work with file
// ...

For more information on path traversal issues see OWASP: Path_Traversal

OWASP:
  • A01:2021-Broken Access Control
  • A5:2017-Broken Access Control
Use of cryptographically weak pseudo-random number generator (PRNG) javascript_random_rule-pseudo-random-bytes, CWE-338 Severity: Medium

Depending on the context, generating weak random numbers may expose cryptographic functions, which rely on these numbers, to be exploitable. When generating numbers for sensitive values such as tokens, nonces, and cryptographic keys, it is recommended that the randomBytes method of the crypto module be used instead of pseudoRandomBytes.

Example using randomBytes:

// Generate 256 bytes of random data const randomBytes = crypto.randomBytes(256);

For more information on JavaScript Cryptography see: crypto.html

OWASP:
  • A02:2021-Cryptographic Failures
  • A3:2017-Sensitive Data Exposure
Improper neutralization of input during web page generation ('Cross-site Scripting') javascript_react_rule-dangerouslysetinnerhtml, CWE-79 Severity: Medium

The application was found calling dangerouslySetInnerHTML which may lead to Cross Site Scripting (XSS). By default, React components will encode the data properly before rendering. Calling dangerouslySetInnerHTML disables this encoding and allows raw markup and JavaScript to be executed.

XSS is an attack which exploits a web application or system to treat user input as markup or script code. It is important to encode the data, depending on the specific context it is used in. There are at least six context types:

  • Inside HTML tags <div>context 1</div>
  • Inside attributes: <div class="context 2"></div>
  • Inside event attributes <button onclick="context 3">button</button>
  • Inside script blocks: <script>var x = "context 4"</script>
  • Unsafe element HTML assignment: element.innerHTML = "context 5"
  • Inside URLs: <iframe src="context 6"></iframe><a href="context 6">link</a>

Script blocks alone have multiple ways they need to be encoded. Extra care must be taken if user input is ever output inside of script tags.

User input that is displayed within the application must be encoded, sanitized or validated to ensure it cannot be treated as HTML or executed as Javascript code. Care must also be taken to not mix server-side templating with client-side templating, as the server-side templating will not encode things like {{ 77 }} which may execute client-side templating features.

It is NOT advised to encode user input prior to inserting into a data store. The data will need to be encoded depending on context of where it is output. It is much safer to force the displaying system to handle the encoding and not attempt to guess how it should be encoded.

Remove the call to dangerouslySetInnerHTML or ensure that the data used in this call does not come from user-supplied input.

For more information on dangerously setting inner HTML see:
common
OWASP:*
  • A03:2021-Injection
  • A7:2017-Cross-Site Scripting (XSS)
Improper neutralization of input during web page generation (XSS) javascript_xss_rule-mustache-escape, CWE-79 Severity: Medium

Markup escaping disabled. This can be used with some template engines to escape disabling of HTML entities, which can lead to XSS attacks.

OWASP:
  • A03:2021-Injection
  • A7:2017-Cross-Site Scripting (XSS)
Improper neutralization of directives in dynamically evaluated code ('Eval Injection') javascript_require_rule-non-literal-require, CWE-95 Severity: Low

The application was found to dynamically import a module by calling require using a non-literal string. An adversary might be able to read the first line of arbitrary files. If they had write access to the file system, they may also be able to execute arbitrary code.

To remediate this issue, use a hardcoded string literal when calling require. Never call it it with dynamically created variables or user-supplied data.

OWASP:
  • A03:2021-Injection
  • A1:2017-Injection

kotlin

Name Identifiers Description
Improper neutralization of CRLF sequences in HTTP headers ('HTTP Response Splitting') kotlin_cookie_rule-RequestParamToHeader, CWE-113 Severity: Critical

This code directly writes an HTTP parameter to an HTTP header, which allows for a HTTP response splitting vulnerability. See http://en.wikipedia.org/wiki/HTTP_response_splitting for more information.

OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Permissive cross-domain policy with untrusted domains kotlin_cors_rule-PermissiveCORSInjection, CWE-942 Severity: Critical

Prior to HTML5, Web browsers enforced the Same Origin Policy which ensures that in order for JavaScript to access the contents of a Web page, both the JavaScript and the Web page must originate from the same domain. Without the Same Origin Policy, a malicious website could serve up JavaScript that loads sensitive information from other websites using a client's credentials, cull through it, and communicate it back to the attacker. HTML5 makes it possible for JavaScript to access data across domains if a new HTTP header called Access-Control-Allow-Origin is defined. With this header, a Web server defines which other domains are allowed to access its domain using cross-origin requests. However, caution should be taken when defining the header because an overly permissive CORS policy will allow a malicious application to communicate with the victim application in an inappropriate way, leading to spoofing, data theft, relay and other attacks.

OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Inadequate Encryption Strength kotlin_crypto_rule-CipherECBMode, CWE-326 Severity: Critical

An authentication cipher mode which provides better confidentiality of the encrypted data should be used instead of Electronic Code Book (ECB) mode, which does not provide good confidentiality. Specifically, ECB mode produces the same output for the same input each time. This allows an attacker to intercept and replay the data.

OWASP:
Use of a broken or risky cryptographic algorithm kotlin_crypto_rule-CipherIntegrity, CWE-327 Severity: Critical

The ciphertext produced is susceptible to alteration by an adversary. This mean that the cipher provides no way to detect that the data has been tampered with. If the ciphertext can be controlled by an attacker, it could be altered without detection.

OWASP:
  • A02:2021-Cryptographic Failures
  • A3:2017-Sensitive Data Exposure
Use of a broken or risky cryptographic algorithm kotlin_crypto_rule-CipherPaddingOracle, CWE-327 Severity: Critical

This specific mode of CBC with PKCS5Padding is susceptible to padding oracle attacks. An adversary could potentially decrypt the message if the system exposed the difference between plaintext with invalid padding or valid padding. The distinction between valid and invalid padding is usually revealed through distinct error messages being returned for each condition.

OWASP:
  • A02:2021-Cryptographic Failures
  • A3:2017-Sensitive Data Exposure
URL redirection to untrusted site ('Open Redirect') kotlin_endpoint_rule-UnvalidatedRedirect, CWE-601 Severity: Critical

Unvalidated redirects occur when an application redirects a user to a destination URL specified by a user supplied parameter that is not validated. Such vulnerabilities can be used to facilitate phishing attacks.

OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Improper limitation of a pathname to a restricted directory ('Path Traversal') kotlin_file_rule-FileUploadFileName, CWE-22 Severity: Critical

The filename provided by the FileUpload API can be tampered with by the client to reference unauthorized files. The provided filename should be properly validated to ensure it's properly structured, contains no unauthorized path characters (e.g., / ), and refers to an authorized file.

OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Files or directories accessible to external parties kotlin_inject_rule-FileDisclosure, CWE-552 Severity: Critical

Constructing a server-side redirect path with user input could allow an attacker to download application binaries (including application classes or jar files) or view arbitrary files within protected directories.

OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Improper neutralization of argument delimiters in a command ('Argument Injection') kotlin_inject_rule-HttpParameterPollution, CWE-88 Severity: Critical

Concatenating unvalidated user input into a URL can allow an attacker to override the value of a request parameter. Attacker may be able to override existing parameter values, inject a new parameter or exploit variables out of a direct reach. HTTP Parameter Pollution (HPP) attacks consist of injecting encoded query string delimiters into other existing parameters. If a web application does not properly sanitize the user input, a malicious user may compromise the logic of the application to perform either client-side or server-side attacks.

OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection') kotlin_inject_rule-SqlInjection, CWE-89 Severity: Critical

The input values included in SQL queries need to be passed in safely. Bind variables in prepared statements can be used to easily mitigate the risk of SQL injection.

OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Use of hard-coded password kotlin_password_rule-ConstantDBPassword, CWE-259 Severity: Critical

A potential hard-coded password was identified in a database connection string. Passwords should not be stored directly in code but loaded from secure locations such as a Key Management System (KMS).

The purpose of using a Key Management System is so access can be audited and keys easily rotated in the event of a breach. By hardcoding passwords, it will be extremely difficult to determine when or if, a key is compromised.

The recommendation on which KMS to use depends on the environment the application is running in:

OWASP:
  • A07:2021-Identification and Authentication Failures
  • A2:2017-Broken Authentication
Missing authentication for critical function (database) kotlin_password_rule-EmptyDBPassword, CWE-306 Severity: Critical

The application does not provide authentication when communicating a database server. It is strongly recommended that the database server be configured with authentication and restrict what queries users can execute.

Please see your database server's documentation on how to configure a password.

Additionally, passwords should not be stored directly in code but loaded from secure locations such as a Key Management System (KMS).

The purpose of using a Key Management System is so access can be audited and keys easily rotated in the event of a breach. By hardcoding passwords, it will be extremely difficult to determine when or if, a key is compromised.

The recommendation on which KMS to use depends on the environment the application is running in:

OWASP:
  • A07:2021-Identification and Authentication Failures
  • A2:2017-Broken Authentication
Improper control of generation of code ('Code Injection') kotlin_script_rule-ScriptInjection, CWE-94 Severity: Critical

The software constructs all or part of a code segment using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the syntax or behavior of the intended code segment.

OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Improper validation of certificate with host mismatch kotlin_smtp_rule-InsecureSmtp, CWE-297 Severity: Critical

Server identity verification is disabled when making SSL connections.

OWASP:
  • A02:2021-Cryptographic Failures
  • A3:2017-Sensitive Data Exposure
Improper neutralization of special elements used in a command kotlin_smtp_rule-SmtpClient, CWE-77 Severity: Critical

Simple Mail Transfer Protocol (SMTP) is a the text based protocol used for email delivery. Like with HTTP, headers are separate by new line separator. If kuser input is place in a header line, the application should remove or replace new line characters (CR / LF). You should use a safe wrapper such as Apache Common Email and Simple Java Mail which filter special characters that can lead to header injection.

OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Server-Side Request Forgery (SSRF) kotlin_ssrf_rule-SSRF, CWE-918 Severity: Critical

Server-Side Request Forgery occur when a web server executes a request to a user supplied destination parameter that is not validated. Such vulnerabilities could allow an attacker to access internal services or to launch attacks from your web server.

OWASP:
  • A10:2021-Server-Side Request Forgery
  • A1:2017-Injection
Use of externally-controlled format string kotlin_strings_rule-FormatStringManipulation, CWE-134 Severity: Critical

Allowing user input to control format parameters could enable an attacker to cause exceptions to be thrown or leak information.Attackers may be able to modify the format string argument, such that an exception is thrown. If this exception is left uncaught, it may crash the application. Alternatively, if sensitive information is used within the unused arguments, attackers may change the format string to reveal this information.

OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Improper control of generation of code ('Code Injection') kotlin_templateinjection_rule-TemplateInjection, CWE-94 Severity: Critical

A malicious user in control of a template can run malicious code on the server-side. Velocity templates should be seen as scripts.

OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Improper neutralization of data within XPath expressions ('XPath Injection') kotlin_xpathi_rule-XpathInjection, CWE-643 Severity: Critical

The input values included in SQL queries need to be passed in safely. Bind variables in prepared statements can be used to easily mitigate the risk of SQL injection.

OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Improper restriction of XML external entity reference ('XXE') kotlin_xxe_rule-SaxParserXXE, CWE-611 Severity: Critical

XML External Entity (XXE) attacks can occur when an XML parser supports XML entities while processing XML received from an untrusted source.

OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Improper restriction of XML external entity reference ('XXE') kotlin_xxe_rule-XMLRdr, CWE-611 Severity: Critical

XML External Entity (XXE) attacks can occur when an XML parser supports XML entities while processing XML received from an untrusted source.

OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Improper restriction of XML external entity reference ('XXE') kotlin_xxe_rule-XMLStreamRdr, CWE-611 Severity: Critical

XML External Entity (XXE) attacks can occur when an XML parser supports XML entities while processing XML received from an untrusted source.

OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Use of hard-coded password kotlin_password_rule-HardcodePassword, CWE-259 Severity: High

A potential hard-coded password was identified in the source code. Passwords should not be stored directly in code but loaded from secure locations such as a Key Management System (KMS).

The purpose of using a Key Management System is so access can be audited and keys easily rotated in the event of a breach. By hardcoding passwords, it will be extremely difficult to determine when or if, a key is compromised.

The recommendation on which KMS to use depends on the environment the application is running in:

OWASP:
  • A07:2021-Identification and Authentication Failures
  • A2:2017-Broken Authentication
Sensitive cookie without 'HttpOnly' flag kotlin_cookie_rule-CookieHTTPOnly, CWE-1004 Severity: Medium

A new cookie is created without the HttpOnly flag set. The HttpOnly flag is a directive to the browser to make sure that the cookie can not be red by malicious script. When a user is the target of a "Cross-Site Scripting", the attacker would benefit greatly from getting the session id for example.

OWASP:
  • A05:2021-Security Misconfiguration
  • A6:2017-Security Misconfiguration
Sensitive cookie in HTTPS session without 'Secure' attribute kotlin_cookie_rule-CookieInsecure, CWE-614 Severity: Medium

"A new cookie is created without the Secure flag set. The Secure flag is a
directive to the browser to make sure that the cookie is not sent for insecure communication
(http://)"

OWASP:
  • A05:2021-Security Misconfiguration
  • A6:2017-Security Misconfiguration
Improper neutralization of CRLF sequences in HTTP headers ('HTTP Response Splitting') kotlin_cookie_rule-HttpResponseSplitting, CWE-113 Severity: Medium

When an HTTP request contains unexpected CR and LF characters, the server may respond with an output stream that is interpreted as two different HTTP responses (instead of one). An attacker can control the second response and mount attacks such as cross-site scripting and cache poisoning attacks.

OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Inadequate encryption strength kotlin_crypto_rule-BlowfishKeySize, CWE-326 Severity: Medium

A small key size makes the ciphertext vulnerable to brute force attacks. At least 128 bits of entropy should be used when generating the key if use of Blowfish is required.

OWASP:
  • A02:2021-Cryptographic Failures
  • A3:2017-Sensitive Data Exposure
Inadequate encryption strength kotlin_crypto_rule-CipherDESInsecure, CWE-326 Severity: Medium

DES is considered strong ciphers for modern applications. Currently, NIST recommends the usage of AES block ciphers instead of DES.

OWASP:
  • A02:2021-Cryptographic Failures
  • A3:2017-Sensitive Data Exposure
Use of a broken or risky cryptographic algorithm kotlin_crypto_rule-CipherDESedeInsecure, CWE-327 Severity: Medium

Triple DES (also known as 3DES or DESede) is considered strong ciphers for modern applications. NIST recommends the usage of AES block ciphers instead of 3DES.

OWASP:
  • A02:2021-Cryptographic Failures
  • A3:2017-Sensitive Data Exposure
Use of a broken or risky cryptographic algorithm kotlin_crypto_rule-CustomMessageDigest, CWE-327 Severity: Medium

Implementing a custom MessageDigest is error-prone. National Institute of Standards and Technology(NIST) recommends the use of SHA-224, SHA-256, SHA-384, SHA-512, SHA-512/224, or SHA-512/256.

OWASP:
  • A04:2021-Insecure Design
  • A6:2017-Security Misconfiguration
Inadequate encryption strength kotlin_crypto_rule-HazelcastSymmetricEncryption, CWE-326 Severity: Medium

The network communications for Hazelcast is configured to use a symmetric cipher (probably DES or Blowfish). Those ciphers alone do not provide integrity or secure authentication. The use of asymmetric encryption is preferred.

OWASP:
  • A02:2021-Cryptographic Failures
  • A3:2017-Sensitive Data Exposure
Inadequate encryption strength kotlin_crypto_rule-InsufficientKeySizeRsa, CWE-326 Severity: Medium

Detected an insufficient key size for DSA. NIST recommends a key size of 2048 or higher.

OWASP:
  • A02:2021-Cryptographic Failures
  • A3:2017-Sensitive Data Exposure
Use of a broken or risky cryptographic algorithm kotlin_crypto_rule-NullCipher, CWE-327 Severity: Medium

The NullCipher implements the Cipher interface by returning ciphertext identical to the supplied plaintext. In a few contexts, such as testing, a NullCipher may be appropriate. Avoid using the NullCipher. Its accidental use can introduce a significant confidentiality risk.

OWASP:
  • A02:2021-Cryptographic Failures
  • A3:2017-Sensitive Data Exposure
Use of RSA algorithm without OAEP kotlin_crypto_rule-RsaNoPadding, CWE-780 Severity: Medium

The software uses the RSA algorithm but does not incorporate Optimal Asymmetric Encryption Padding (OAEP), which might weaken the encryption.

OWASP:
  • A02:2021-Cryptographic Failures
  • A3:2017-Sensitive Data Exposure
Use of a broken or risky cryptographic algorithm (SHA1 / MD5) kotlin_crypto_rule-WeakMessageDigest, CWE-327 Severity: Medium

DES is considered strong ciphers for modern applications. Currently, NIST recommends the usage of AES block ciphers instead of DES.

OWASP:
  • A04:2021-Insecure Design
  • A6:2017-Security Misconfiguration
Improper certificate validation kotlin_crypto_rule-WeakTLSProtocol, CWE-295 Severity: Medium

A HostnameVerifier that accept any host are often use because of certificate reuse on many hosts. As a consequence, this is vulnerable to Man-in-the-middleattacks attacks since the client will trust any certificate.

OWASP:
  • A02:2021-Cryptographic Failures
  • A3:2017-Sensitive Data Exposure
Inadequate encryption strength kotlin_crypto_rule-WeakTLSProtocolVersion, CWE-326 Severity: Medium

The application was found enabling insecure TLS protocol versions. When enabling protocol versions for an SSLContext, only the following versions should be allowed:
- TLSv1.2
- TLSv1.3
- DTLSv1.2
- DTLSv1.3

To mitigate potential security risks, it is strongly advised to enforce TLS 1.2 as the minimum protocol version and disallow older versions such as TLS 1.0. Do note that newer versions of Java do not even support TLS 1.0 and will throw NoSuchAlgorithmException. Versions of TLS prior to 1.2 could expose the connection to downgrade attacks, where an adversary intercepts the connection and alters the requested protocol version to be a less secure one.

In many scenarios, relying on the default system configuration does not meet compliance standards. This is due to the application being deployed across diverse systems with varying configurations and Java versions. While the default value may be secure on modern and up-to-date systems, it may not hold true for older systems. Consequently, it is highly recommended to explicitly define a secure configuration in all cases.

Example configuring an SSLContext with TLSv1.2:

// Create an SSLContext with TLSv1.2 explicitly SSLContext tlsContext = SSLContext.getInstance("TLSv1.2"); // or TLSv1.3, DTLSv1.2, DTLSv1.3

// Alternatively, set the enabled protocols SSLContext serverSslContext = SSLContext.getInstance("TLS");
SSLEngine serverEngine = serverSslContext.createSSLEngine();
// Calling setEnabledProtocols will override the original context's configured protocol version serverEngine.setEnabledProtocols(new String[]{ "TLSv1.2" });
For more information on SSLContext see:
SSLContext.html
For more information on MiTM attacks see:
Manipulator-in-the-middle_attack
OWASP:
  • A02:2021-Cryptographic Failures
  • A3:2017-Sensitive Data Exposure
Cross-Site Request Forgery (CSRF) kotlin_csrf_rule-SpringCSRFDisabled, CWE-352 Severity: Medium

The application fails to protect against Cross-Site Request Forgery (CSRF)
due to disabling Spring's CSRF protection features.

OWASP:
  • A01:2021-Broken Access Control
  • A5:2017-Broken Access Control
Improper Certificate Validation kotlin_endpoint_rule-WeakHostNameVerification, CWE-295 Severity: Medium

A HostnameVerifier that accept any host are often use because of certificate reuse on many hosts. As a consequence, this is vulnerable to Man-in-the-middle attacks since the client will trust any certificate.

OWASP:
Improper limitation of a pathname to a restricted directory ('Path Traversal') kotlin_file_rule-FilenameUtils, CWE-22 Severity: Medium

A file is opened to read its content. The filename comes from an input parameter. If an unfiltered parameter is passed to this file API, files from an arbitrary filesystem location could be read.

OWASP:
  • A01:2021-Broken Access Control
  • A5:2017-Broken Access Control
Improper neutralization of special elements used in an OS command ('OS Command Injection') kotlin_inject_rule-CommandInjection, CWE-78 Severity: Medium

The highlighted API is used to execute a system command. If unfiltered input is passed to this API, it can lead to arbitrary command execution.

OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Improper neutralization of special elements used in an expression language statement ('Expression Language Injection') kotlin_inject_rule-ELInjection, CWE-917 Severity: Medium

An expression is built with a dynamic value. The source of the value(s) should be verified to avoid that unfiltered values fall into this risky code evaluation.

OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Improper neutralization of special elements used in an LDAP query ('LDAP Injection') kotlin_inject_rule-LDAPInjection, CWE-90 Severity: Medium

Just like SQL, all inputs passed to an LDAP query need to be passed in safely. Unfortunately, LDAP doesn't have prepared statement interfaces like SQL. Therefore, the primary defense against LDAP injection is strong input validation of any untrusted data before including it in an LDAP query.

OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Expression injection (OGNL) kotlin_inject_rule-OgnlInjection, CWE-917 Severity: Medium

"A expression is built with a dynamic value. The source of the value(s) should be verified to avoid that unfiltered values fall into this risky code evaluation."

OWASP:
Improper limitation of a pathname to a restricted directory ('Path Traversal') kotlin_inject_rule-SpotbugsPathTraversalAbsolute, CWE-22 Severity: Medium

The software uses an HTTP request parameter to construct a pathname that should be within a restricted directory, but it does not properly neutralize absolute path sequences such as
"/abs/path" that can resolve to a location that is outside of that directory. See http://cwe.mitre.org/data/definitions/36.html for more information.

OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Missing authentication for critical function (LDAP) kotlin_ldap_rule-AnonymousLDAP, CWE-306 Severity: Medium

Without proper access control, executing an LDAP statement that contains a user-controlled value can allow an attacker to abuse poorly configured LDAP context

OWASP:
  • A07:2021-Identification and Authentication Failures
  • A2:2017-Broken Authentication
Insecure inherited permissions kotlin_perm_rule-DangerousPermissions, CWE-277 Severity: Medium

Do not grant dangerous combinations of permissions.

OWASP:
  • A01:2021-Broken Access Control
  • A5:2017-Broken Access Control
Incorrect permission assignment for critical resource kotlin_perm_rule-OverlyPermissiveFilePermissionInline, CWE-732 Severity: Medium

Overly permissive file permission

OWASP:
  • A01:2021-Broken Access Control
  • A5:2017-Broken Access Control
Incorrect type conversion or cast kotlin_strings_rule-BadHexConversion, CWE-704 Severity: Medium

When converting a byte array containing a hash signature to a human readable string, a conversion mistake can be made if the array is read byte by byte.

OWASP:
  • A05:2021-Security Misconfiguration
  • A6:2017-Security Misconfiguration
Collapse of data into unsafe value kotlin_strings_rule-ModifyAfterValidation, CWE-182 Severity: Medium

CERT: IDS11-J. Perform any string modifications before validation

OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Incorrect behavior order: validate before canonicalize kotlin_strings_rule-NormalizeAfterValidation, CWE-180 Severity: Medium

IDS01-J. Normalize strings before validating them

OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
External control of system or configuration setting kotlin_unsafe_rule-ExternalConfigControl, CWE-15 Severity: Medium

Allowing external control of system settings can disrupt service or cause an application to behave in unexpected, and potentially malicious ways. An attacker could cause an error by providing a nonexistent catalog name or connect to an unauthorized portion of the database.

OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Weak authentication kotlin_xml_rule-SAMLIgnoreComments, CWE-1390 Severity: Medium

Ignoring XML comments in SAML may lead to authentication bypass

OWASP:
  • A01:2021-Broken Access Control
  • A5:2017-Broken Access Control
Deserialization of untrusted data kotlin_xml_rule-XmlDecoder, CWE-502 Severity: Medium

Avoid using XMLDecoder to parse content from an untrusted source.

OWASP:
  • A08:2021-Software and Data Integrity Failures
  • A8:2017-Insecure Deserialization
XML injection (aka Blind XPath injection) kotlin_xml_rule-XsltTransform, CWE-91 Severity: Medium

It is possible to attach malicious behavior to those style sheets. Therefore, if an attacker can control the content or the source of the style sheet, he might be able to trigger remote code execution.

OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Improper neutralization of input during web page generation ('Cross-site Scripting') kotlin_xss_rule-WicketXSS, CWE-79 Severity: Medium

Disabling HTML escaping put the application at risk for Cross-Site Scripting (XSS).

OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Improper neutralization of input during web page generation ('Cross-site Scripting') kotlin_xss_rule-XSSReqParamToServletWriter, CWE-79 Severity: Medium

Servlet reflected cross site scripting vulnerability

OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Leftover debug code rules_lgpl_kotlin_other_rule-android-kotlin-webview-debug, CWE-489 Severity: Medium

Remote WebView debugging is enabled.This can introduce security
risks as it allows remote debugging tools, such as Chrome DevTools,
to inspect and manipulate the WebView content. This can potentially
expose sensitive information, including user data, session tokens,
and other confidential data, to unauthorized parties.

To fix this security issue, you should disable remote WebView
debugging in production builds of your app. Here's how you can do it:

import WebKit

class ViewController: UIViewController {

override func viewDidLoad() {
super.viewDidLoad()

// Disable remote WebView debugging in production builds
#if DEBUG
WebViewConfiguration.shared().preferences.setValue(true, forKey: "developerExtrasEnabled")
#else
WebViewConfiguration.shared().preferences.setValue(false, forKey: "developerExtrasEnabled")
#endif

// Other setup code...
}

// Other methods...
}
OWASP:
  • A05:2021-Security Misconfiguration
  • A6:2017-Security Misconfiguration

python

Name Identifiers Description
Improper neutralization of user input rendered in HTML ('XSS') pyramid_jinja2_reflected_xss, CWE-79 Severity: High

Untrusted user input is passed to Pyramid's template rendering functions without proper sanitization, creating a reflected XSS vulnerability. Even though templates typically auto-escape variables, this protection can be bypassed. Never include untrusted user data directly in templates or with auto-escaping disabled. Always pass user data through context dictionaries. If necessary, sanitize user input before passing it to templates using Pyramid's escape_html, MarkupSafe's escape, Jinja2's escape, html.escape(), or bleach.clean(). Be especially careful with template features that disable auto-escaping (like safe filters or raw blocks) when working with user-controlled data.

OWASP:
  • A03:2021-Injection
  • A7:2017-Cross-Site Scripting (XSS)
Improper neutralization of user input rendered in HTML ('XSS') pyramid_unsafe_user_input, CWE-79 Severity: High

Untrusted user input from request objects (params, GET, POST, json_body, matchdict) is directly embedded in a Pyramid Response without proper sanitization, creating a reflected XSS vulnerability. Always sanitize user input before including it in HTML responses using Pyramid's escape_html, MarkupSafe's escape, html.escape(), or bleach.clean(). Consider using Pyramid's template engines which automatically escape variables by default instead of manually constructing HTML. Remember that HTML escaping is not sufficient for JavaScript contexts, CSS contexts, or URL attributes - use context-specific sanitization for these cases.

OWASP:
  • A03:2021-Injection
  • A7:2017-Cross-Site Scripting (XSS)
Deserialization of untrusted data python_deserialization_rule-cpickle, CWE-502 Severity: High

The application was found using cPickle which is vulnerable to deserialization attacks. Deserialization attacks exploit the process of reading serialized data and turning it back into an object. By constructing malicious objects and serializing them, an adversary may attempt to:

  • Inject code that is executed upon object construction, which occurs during the deserialization process.
  • Exploit mass assignment by including fields that are not normally a part of the serialized data but are read in during deserialization.

Consider safer alternatives such as serializing data in the JSON format. Ensure any format chosen allows the application to specify exactly which object types are allowed to be deserialized.

To protect against mass assignment, only allow deserialization of the specific fields that are required. If this is not easily done, consider creating an intermediary type that can be serialized with only the necessary fields exposed.

Example JSON deserializer using an intermediary type that is validated against a schema to ensure it is safe from mass assignment:

import jsonschema

# Create a schema to validate our user-supplied input against
# an intermediary object intermediary_schema = {
"type" : "object",
"properties" : {
"name": {"type" : "string"}
},
"required": ["name"],
# Protect against random properties being added to the object
"additionalProperties": False,
}
# If a user attempted to add "'is_admin': True" it would cause a validation error intermediary_object = {'name': 'test user'}

try:
# Validate the user supplied intermediary object against our schema
jsonschema.validate(instance=intermediary_object, schema=intermediary_schema)
user_object = {'user':
{
# Assign the deserialized data from intermediary object
'name': intermediary_object['name'],
# Add in protected data in object definition (or set it from a class constructor)
'is_admin': False,
}
}
# Work with the user_object except jsonschema.exceptions.ValidationError as ex:
# Gracefully handle validation errors
# ...
For more details on deserialization attacks in general, see OWASP's guide:
Deserialization_Cheat_Sheet.html
OWASP:
  • A08:2021-Software and Data Integrity Failures
  • A8:2017-Insecure Deserialization
Deserialization of untrusted data python_deserialization_rule-dill, CWE-502 Severity: High

The application was found using dill which is vulnerable to deserialization attacks. Deserialization attacks exploit the process of reading serialized data and turning it back into an object. By constructing malicious objects and serializing them, an adversary may attempt to:

  • Inject code that is executed upon object construction, which occurs during the deserialization process.
  • Exploit mass assignment by including fields that are not normally a part of the serialized data but are read in during deserialization.

Consider safer alternatives such as serializing data in the JSON format. Ensure any format chosen allows the application to specify exactly which object types are allowed to be deserialized.

To protect against mass assignment, only allow deserialization of the specific fields that are required. If this is not easily done, consider creating an intermediary type that can be serialized with only the necessary fields exposed.

Example JSON deserializer using an intermediary type that is validated against a schema to ensure it is safe from mass assignment:

import jsonschema

# Create a schema to validate our user-supplied input against
# an intermediary object intermediary_schema = {
"type" : "object",
"properties" : {
"name": {"type" : "string"}
},
"required": ["name"],
# Protect against random properties being added to the object
"additionalProperties": False,
}
# If a user attempted to add "'is_admin': True" it would cause a validation error intermediary_object = {'name': 'test user'}

try:
# Validate the user supplied intermediary object against our schema
jsonschema.validate(instance=intermediary_object, schema=intermediary_schema)
user_object = {'user':
{
# Assign the deserialized data from intermediary object
'name': intermediary_object['name'],
# Add in protected data in object definition (or set it from a class constructor)
'is_admin': False,
}
}
# Work with the user_object except jsonschema.exceptions.ValidationError as ex:
# Gracefully handle validation errors
# ...
For more details on deserialization attacks in general, see OWASP's guide:
Deserialization_Cheat_Sheet.html
OWASP:
  • A08:2021-Software and Data Integrity Failures
  • A8:2017-Insecure Deserialization
Deserialization of untrusted data python_deserialization_rule-marshal, CWE-502 Severity: High

The application was found using dill which is vulnerable to deserialization attacks. Deserialization attacks exploit the process of reading serialized data and turning it back into an object. By constructing malicious objects and serializing them, an adversary may attempt to:

  • Inject code that is executed upon object construction, which occurs during the deserialization process.
  • Exploit mass assignment by including fields that are not normally a part of the serialized data but are read in during deserialization.

Consider safer alternatives such as serializing data in the JSON format. Ensure any format chosen allows the application to specify exactly which object types are allowed to be deserialized.

To protect against mass assignment, only allow deserialization of the specific fields that are required. If this is not easily done, consider creating an intermediary type that can be serialized with only the necessary fields exposed.

Example JSON deserializer using an intermediary type that is validated against a schema to ensure it is safe from mass assignment:

import jsonschema

# Create a schema to validate our user-supplied input against
# an intermediary object intermediary_schema = {
"type" : "object",
"properties" : {
"name": {"type" : "string"}
},
"required": ["name"],
# Protect against random properties being added to the object
"additionalProperties": False,
}
# If a user attempted to add "'is_admin': True" it would cause a validation error intermediary_object = {'name': 'test user'}

try:
# Validate the user supplied intermediary object against our schema
jsonschema.validate(instance=intermediary_object, schema=intermediary_schema)
user_object = {'user':
{
# Assign the deserialized data from intermediary object
'name': intermediary_object['name'],
# Add in protected data in object definition (or set it from a class constructor)
'is_admin': False,
}
}
# Work with the user_object except jsonschema.exceptions.ValidationError as ex:
# Gracefully handle validation errors
# ...
For more details on deserialization attacks in general, see OWASP's guide:
Deserialization_Cheat_Sheet.html
OWASP:
  • A08:2021-Software and Data Integrity Failures
  • A8:2017-Insecure Deserialization
Deserialization of untrusted data python_deserialization_rule-pickle, CWE-502 Severity: High

The application was found using pickle which is vulnerable to deserialization attacks. Deserialization attacks exploit the process of reading serialized data and turning it back into an object. By constructing malicious objects and serializing them, an adversary may attempt to:

  • Inject code that is executed upon object construction, which occurs during the deserialization process.
  • Exploit mass assignment by including fields that are not normally a part of the serialized data but are read in during deserialization.

Consider safer alternatives such as serializing data in the JSON format. Ensure any format chosen allows the application to specify exactly which object types are allowed to be deserialized.

To protect against mass assignment, only allow deserialization of the specific fields that are required. If this is not easily done, consider creating an intermediary type that can be serialized with only the necessary fields exposed.

Example JSON deserializer using an intermediary type that is validated against a schema to ensure it is safe from mass assignment:

import jsonschema

# Create a schema to validate our user-supplied input against
# an intermediary object intermediary_schema = {
"type" : "object",
"properties" : {
"name": {"type" : "string"}
},
"required": ["name"],
# Protect against random properties being added to the object
"additionalProperties": False,
}
# If a user attempted to add "'is_admin': True" it would cause a validation error intermediary_object = {'name': 'test user'}

try:
# Validate the user supplied intermediary object against our schema
jsonschema.validate(instance=intermediary_object, schema=intermediary_schema)
user_object = {'user':
{
# Assign the deserialized data from intermediary object
'name': intermediary_object['name'],
# Add in protected data in object definition (or set it from a class constructor)
'is_admin': False,
}
}
# Work with the user_object except jsonschema.exceptions.ValidationError as ex:
# Gracefully handle validation errors
# ...
For more details on deserialization attacks in general, see OWASP's guide:
Deserialization_Cheat_Sheet.html
OWASP:
  • A08:2021-Software and Data Integrity Failures
  • A8:2017-Insecure Deserialization
Deserialization of untrusted data python_deserialization_rule-shelve, CWE-502 Severity: High

The application was found using shelve which is vulnerable to deserialization attacks as it calls pickle internally. Deserialization attacks exploit the process of reading serialized data and turning it back into an object. By constructing malicious objects and serializing them, an adversary may attempt to:

  • Inject code that is executed upon object construction, which occurs during the deserialization process.
  • Exploit mass assignment by including fields that are not normally a part of the serialized data but are read in during deserialization.

Consider safer alternatives such as serializing data in the JSON format. Ensure any format chosen allows the application to specify exactly which object types are allowed to be deserialized.

To protect against mass assignment, only allow deserialization of the specific fields that are required. If this is not easily done, consider creating an intermediary type that can be serialized with only the necessary fields exposed.

Example JSON deserializer using an intermediary type that is validated against a schema to ensure it is safe from mass assignment:

import jsonschema

# Create a schema to validate our user-supplied input against
# an intermediary object intermediary_schema = {
"type" : "object",
"properties" : {
"name": {"type" : "string"}
},
"required": ["name"],
# Protect against random properties being added to the object
"additionalProperties": False,
}
# If a user attempted to add "'is_admin': True" it would cause a validation error intermediary_object = {'name': 'test user'}

try:
# Validate the user supplied intermediary object against our schema
jsonschema.validate(instance=intermediary_object, schema=intermediary_schema)
user_object = {'user':
{
# Assign the deserialized data from intermediary object
'name': intermediary_object['name'],
# Add in protected data in object definition (or set it from a class constructor)
'is_admin': False,
}
}
# Work with the user_object except jsonschema.exceptions.ValidationError as ex:
# Gracefully handle validation errors
# ...
For more details on deserialization attacks in general, see OWASP's guide:
Deserialization_Cheat_Sheet.html
OWASP:
  • A08:2021-Software and Data Integrity Failures
  • A8:2017-Insecure Deserialization
Deserialization of untrusted data python_deserialization_rule-yaml-load, CWE-502 Severity: High

The application was found using an unsafe version of yaml load which is vulnerable to deserialization attacks. Deserialization attacks exploit the process of reading serialized data and turning it back into an object. By constructing malicious objects and serializing them, an adversary may attempt to:

  • Inject code that is executed upon object construction, which occurs during the deserialization process.
  • Exploit mass assignment by including fields that are not normally a part of the serialized data but are read in during deserialization.

To remediate this issue, use safe_load() or call yaml.load() with the Loader argument set to
yaml.SafeLoader.

Example loading YAML using safe_load:

import yaml

# Use safe_load to load data into an intermediary object intermediary_object = yaml.safe_load("""user:
name: 'test user'"""
)
# Create our real object, copying over only the necessary fields user_object = {'user': {
# Assign the deserialized data from intermediary object
'name': intermediary_object['user']['name'],
# Add in protected data in object definition (or set it from a class constructor)
'is_admin': False,
}
}
# Work with user_object
# ...
For more details on deserialization attacks in general, see OWASP's guide:
Deserialization_Cheat_Sheet.html
OWASP:
  • A08:2021-Software and Data Integrity Failures
  • A8:2017-Insecure Deserialization
Improper neutralization of special elements used in an SQL Command ('SQL Injection') python_django_rule-django-extra-used, CWE-89 Severity: High

SQL Injection is a critical vulnerability that can lead to data or system compromise. By dynamically generating SQL query strings, user input may be able to influence the logic of the SQL statement. This could lead to an adversary accessing information they should not have access to, or in some circumstances, being able to execute OS functionality or code.

Replace all dynamically generated SQL queries with parameterized queries. In situations where dynamic queries must be created, never use direct user input, but instead use a map or dictionary of valid values and resolve them using a user supplied key.

For example, some database drivers do not allow parameterized queries for > or < comparison operators. In these cases, do not use a user supplied > or < value, but rather have the user supply a gt or lt value. The alphabetical values are then used to look up the > and <
values to be used in the construction of the dynamic query. The same goes for other queries where column or table names are required but cannot be parameterized.

The QuerySet.extra API method will be deprecated as it a source of SQL Injection vulnerabilities and other problems. This method is especially risky as callers will need to do their own escaping of any parameters that come from user-supplied information.

To remediate this issue, do not use extra but use other QuerySet methods to achieve the same goals. If for some reason this is not feasible, consider using the RawSQL method and making sure that all arguments, including user-supplied ones, are only used in
params

While not recommended due to potential SQL Injection, below is an example using RawSQL, passing in user-supplied data as a param which will escape the input:

# If dealing with integer based user input, restrict the values to integers only using the
# path configuration: path('<int:user_supplied_id>/someview/', views.some_view, name='someview'),

# views.py def some_view(request, user_supplied_id):
# Never use string interpolation in the sql parameter.
# Never quote the %s string format such as ... where id='%s' as this could lead to SQL Injection.
# Pass the user supplied data only in the params parameter.
for obj in DBObject.objects.all().annotate(
val=RawSQL(sql="select id from some_secondary_table where id=%s", params=[user_supplied_id])):
# Work with the results from the query
# ...
For more information on QuerySet see:
For more information on SQL Injection see OWASP:
SQL_Injection_Prevention_Cheat_Sheet.html
OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Improper neutralization of user input rendered in HTML ('XSS') python_django_rule_reflected_xss_csp, CWE-79 Severity: High

Unsecure Content Security Policy detected in Django. Avoid usage of 'unsafe-inline', 'unsafe-eval' or 'unsafe-hashes' in the CSP.
Avoid overly permissive CSP (containing ''). Use 'self' or allow lists instead.

OWASP:*
  • A03:2021-Injection
  • A7:2017-Cross-Site Scripting (XSS)
Improper neutralization of user input rendered in HTML ('XSS') in Django python_django_rule_reflected_xss_global, CWE-79 Severity: High

A reflected XSS vulnerability was detected in Django due to an insecure global parameter: either the security headers SECURE_BROWSER_XSS_FILTER or SECURE_CONTENT_TYPE_NOSNIFF were set to False (they should be True), ALLOWED_HOSTS was overly permissive (e.g., '' instead of 'self' or an allowlist), auto-escaping was disabled globally (autoescape: False), or a class was incorrectly decorated with @html_safe (which bypasses escaping for all its string output, risking XSS if the class processes untrusted data).

OWASP:*
  • A03:2021-Injection
  • A7:2017-Cross-Site Scripting (XSS)
Improper neutralization of user input rendered in HTML ('XSS') in Django python_django_rule_reflected_xss_httpresponse, CWE-79 Severity: High

A reflected Cross-Site Scripting (XSS) vulnerability was identified in Django. By default, Django’s HttpResponse bypasses Django's automatic escaping, making it unsafe to use with unescaped user-controlled input.
To mitigate this, use Django’s auto-escaping render() method instead of HttpResponse or manually sanitize inputs with django.utils.html.escape/format_html before passing them to HttpResponse.
Be careful when using format_html not to use f-string with the user controlled input nested in it, the escaping would be cancelled. instead, use it this way: format_html("{}", user_input).
Ensure to be aware of the context in which the user controlled data will be rendered: if it is embedded in CSS or <script> tags, you need to use a dedicated escaping method as django.utils.html.escapejs. Django's escape methods is meant to be use for HTML sanitizing!

OWASP:
  • A03:2021-Injection
  • A7:2017-Cross-Site Scripting (XSS)
Improper neutralization of user input rendered in HTML ('XSS') python_django_rule_reflected_xss_render, CWE-79 Severity: High

A user controlled input is used in Django's render() function but the auto escaping has been disabled with django.utils.safestring.mark_safe|SafeString. Hence the user controlled input is directly embedded in the HTML template, creating an XSS vulnerability.
Avoid using mark_safe|SafeString on user controlled variables. Escape the user controlled variables with django.utils.html.escape/format_html.
Be careful when using format_html not to use f-string with the user controlled input nested in it, the escaping would be cancelled. instead, use it this way: format_html("{}", user_input).
Ensure to be aware of the context in which the user controlled data will be rendered: if it is embedded in CSS or <script> tags, you need to use a dedicated escaping method as django.utils.html.escapejs in addition to Django's autoescaping. Django's escape methods is meant to be use for HTML sanitizing!

OWASP:
  • A03:2021-Injection
  • A7:2017-Cross-Site Scripting (XSS)
Improper neutralization of directives in dynamically evaluated code ('Eval Injection') python_eval_rule-eval, CWE-95 Severity: High

The application was found calling the eval function with non-literal data. If the variable contains
user-controlled data, either partially or fully, an adversary could compromise the entire system by
executing arbitrary Python code.

To remediate this issue, remove all calls to eval and consider alternative methods for executing
the necessary business logic. There is almost no safe method of calling eval with user-supplied input.

If the application only needs to convert strings into objects, consider using json.loads. In
some cases ast.literal_eval is recommended, but this should be avoided as it can still suffer
from other issues such as the ability for malicious code to crash the python interpreter or application.

Example using `json.loads`` to load in arbitrary data to create data structures:

# User supplied data as a blob of JSON user_supplied_data = """{"user": "test", "metadata": [1,2,3]}"""
# Load the JSON user_object = json.loads(user_supplied_data)
# Manually add protected properties after loading, never before user_object["is_admin"] = False
# Work with the object
OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Improper neutralization of special elements used in an OS command ('OS Command Injection') python_exec_rule-exec-used, CWE-78 Severity: High

The application was found calling the exec function with a non-literal variable. If the variable comes from user-supplied input, an adversary could compromise the entire system by executing arbitrary python code.

To remediate this issue, remove all calls to exec and consider alternative methods for executing the necessary business logic. There is almost no safe method of calling eval
with user-supplied input.

If the application only needs to convert strings into objects, consider using json.loads. In some cases ast.literal_eval is recommended, but this should be avoided as it can still suffer from other issues such as the ability for malicious code to crash the python interpreter or application.

Example using `json.loads`` to load in arbitrary data to create data structures:

# User supplied data as a blob of JSON user_supplied_data = """{"user": "test", "metadata": [1,2,3]}"""
# Load the JSON user_object = json.loads(user_supplied_data)
# Manually add protected properties after loading, never before user_object["is_admin"] = False
# Work with the object
OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Improper neutralization of wildcards or matching symbols python_exec_rule-linux-command-wildcard-injection, CWE-155 Severity: High

Detected use of the wildcard character in a system call that spawns a shell. This subjects the wildcard to normal shell expansion, which can have unintended consequences if there exist any non-standard file names. For instance, a file named -e sh script.sh could cause issues when
expanded by the shell and executed as a command. Consider using a different method to achieve
the same result, such as using the glob module to expand the wildcard before passing it to the system call. Or if the command is static, consider hardcoding the command instead of using a wildcard.

For example, the below code uses the glob module to expand the wildcard and get a list of all
CSV files in the current directory. This list is then used in the subprocess.run call, instead of a
wildcard. This avoids the potential issues that can arise from using a wildcard in a system call.

import glob import subprocess

# Secure way to process all CSV files files = glob.glob('.csv')
for file in files:
subprocess.run(['process_data', file])
OWASP:*
  • A03:2021-Injection
  • A1:2017-Injection
Improper neutralization of special elements used in an OS Command ('OS Command Injection') python_exec_rule-os-path, CWE-78 Severity: High

Starting a process with a shell; seems safe, but may be changed in the future, consider rewriting without shell

OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Improper neutralization of special elements used in an OS Command ('OS Command Injection') python_exec_rule-os-popen2, CWE-78 Severity: High

Starting a process with a shell; seems safe, but may be changed in the future, consider rewriting without shell

OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Improper neutralization of special elements used in an OS Command ('OS Command Injection') python_exec_rule-start-process-with-no-shell, CWE-78 Severity: High

Found dynamic content when spawning a process. This is dangerous if externaldata can reach this function call because it allows a malicious actor to execute commands. Ensure no external data reaches here.

OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Improper neutralization of special elements used in an OS Command ('OS Command Injection') python_exec_rule-subprocess-call, CWE-78 Severity: High

Python possesses many mechanisms to invoke an external executable. However, doing so may present a security issue if appropriate care is not taken to sanitize any user provided or variable input. This plugin test is part of a family of tests built to check for process spawning and warn appropriately. Specifically, this test looks for the spawning of a subprocess without the use of a command shell. This type of subprocess invocation is not vulnerable to shell injection attacks, but care should still be taken to ensure validity of input.

OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Improper neutralization of special elements used in an OS Command ('OS Command Injection') python_exec_rule-subprocess-popen-shell-true, CWE-78 Severity: High

Found subprocess function $FUNC with shell=True. This is dangerous because this call will spawn the command using a shell process. Doing so propagates current shell settings and variables, which makes it much easier for a malicious actor to execute commands. Use shell=False
instead.

OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Improper neutralization of special elements used in an OS Command ('OS Command Injection') python_exec_rule-subprocess-shell-TRUE, CWE-78 Severity: High

subprocess call - check for execution of untrusted input

OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Improper neutralization of user input rendered in HTML (XSS) python_flask_rule_reflected_xss_make_response, CWE-79 Severity: High

Untrusted user input from request objects is directly inserted into an HTML response created with make_response() without proper sanitization, creating a reflected XSS vulnerability. Always sanitize user input before including it in HTML responses using Flask's escape function, MarkupSafe's escape, html.escape(), or bleach.clean(). Use Flask's render_template() with Jinja2 templates instead of manually constructing HTML with make_response(), as templates automatically escape variables. Remember that HTML escaping is not sufficient for JavaScript contexts, CSS contexts, or URL attributes - use context-specific sanitization for these cases.

OWASP:
  • A03:2021-Injection
  • A7:2017-Cross-Site Scripting (XSS)
Improper neutralization of user input rendered in HTML (XSS) python_flask_rule_reflected_xss_render, CWE-79 Severity: High

Untrusted user input is directly inserted into an HTML template string passed to render_template_string(), creating a reflected XSS vulnerability. While Jinja2 templates automatically escape variables, this protection is bypassed when user input is embedded in the template string itself or when the |safe filter is used. Never construct template strings dynamically with user input - always pass user data as context variables to the template instead. If you must include user data in dynamic templates, sanitize it first with Flask's escape function, MarkupSafe's escape, or html.escape(). Never use the |safe filter with untrusted data, and consider using render_template() with static template files instead of render_template_string().

OWASP:
  • A03:2021-Injection
  • A7:2017-Cross-Site Scripting (XSS)
Improper neutralization of user input rendered in HTML (XSS) python_flask_rule_reflected_xss_user_input, CWE-79 Severity: High

User input from request objects (args, form, values, json) is directly used in HTML output without proper sanitization, creating a reflected XSS vulnerability. Always sanitize user input before including it in HTML responses using Flask's escape function, MarkupSafe's escape, html.escape(), or bleach.clean(). Use Flask templates (Jinja2) which automatically escape variables by default instead of manually constructing HTML. For JavaScript contexts or URL attributes, use additional context-specific sanitization as HTML escaping alone is insufficient.

OWASP:
  • A03:2021-Injection
  • A7:2017-Cross-Site Scripting (XSS)
Improper control of generation of code ('Code Injection') python_log_rule-logging-config-insecure-listen, CWE-94 Severity: High

The application was found calling the logging.config.listen` function, which provides the ability to listen for external configuration files over a socket server. This listen socket parses part of the configuration and calls</code>eval on the supplied configuration file. A local user, or an adversary who is able to exploit a Server Side Request Forgery (SSRF) attack to communicate over localhost, would be able to execute arbitrary code by passing in a logging config that contains python code.

To remediate the issue, remove the call to logging.config.listen method.

For more information on the listen functionality see:
logging.config.html
OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Improper neutralization of special elements used in an SQL Command ('SQL Injection') python_sql_rule-hardcoded-sql-expression, CWE-89 Severity: High

SQL Injection is a critical vulnerability that can lead to data or system compromise. By dynamically generating SQL query strings, user input may be able to influence the logic of the SQL statement. This could lead to an adversary accessing information they should not have access to, or in some circumstances, being able to execute OS functionality or code.

Replace all dynamically generated SQL queries with parameterized queries. In situations where dynamic queries must be created, never use direct user input, but instead use a map or dictionary of valid values and resolve them using a user supplied key.

For example, some database drivers do not allow parameterized queries for > or < comparison operators. In these cases, do not use a user supplied > or < value, but rather have the user supply a gt or lt value. The alphabetical values are then used to look up the > and <
values to be used in the construction of the dynamic query. The same goes for other queries where column or table names are required but cannot be parameterized.

Example using PreparedStatement queries:

import sqlite3

# Create a new database (in memory)
con = sqlite3.connect(":memory:")
# Get a cursor from the connection cur = con.cursor()
# Create a tuple of the value to be used in the parameterized query params = ('user-input',)
# execute the statement, passing in the params for the value cur.execute("select name from sqlite_master where name = ?", params)
# work with the result result = cur.fetchall()

For more information on SQL Injection see OWASP: SQL_Injection_Prevention_Cheat_Sheet.html

OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Improper neutralization of user input rendered in Tornado ('XSS') python_tornado_rule_reflected_xss, CWE-79 Severity: High

User controlled input given to Tornado self.write() or self.redirect() methods can lead to XSS attacks as they do not escape the variable. Prefer using tornado.web.RequestHandler render() methods which auto escapes variables rendered in the Template.
If you need to use self.write() or self.redirect(), make sure to sanitize them using tornado.escape.xhtml_escape(...) or tornado.escape.url_escape(...) if it is a URL.

OWASP:
  • A03:2021-Injection
  • A7:2017-Cross-Site Scripting (XSS)
Improper neutralization of user input rendered in HTML ('XSS') python_tornado_rule_reflected_xss_csp, CWE-79 Severity: High

Unsecure Content Security Policy in Tornado. Avoid using unsafe-inline, unsafe-eval and unsafe-hashes, as they can lead to XSS attacks.
Avoid overly permissive CSP containing ''. Prefer using 'self' or allow lists.
Never set X-XSS-Protection to 0.

OWASP:*
  • A03:2021-Injection
  • A7:2017-Cross-Site Scripting (XSS)
Improper neutralization of user input rendered in HTML ('XSS') python_tornado_rule_reflected_xss_global, CWE-79 Severity: High

Reflected XSS vulnerability in Django

OWASP:
  • A03:2021-Injection
  • A7:2017-Cross-Site Scripting (XSS)
Use of a broken or risky cryptographic algorithm python_crypto_rule-cipher-modes, CWE-327 Severity: Medium

Cryptographic algorithms provide many different modes of operation, only some of which provide message integrity. Without message integrity it could be possible for an adversary to attempt to tamper with the ciphertext which could lead to compromising the encryption key. Newer algorithms apply message integrity to validate ciphertext has not been tampered with.

Instead of using an algorithm that requires configuring a cipher mode, an algorithm that has built-in message integrity should be used. Consider using ChaCha20Poly1305 or
AES-256-GCM instead.

For older applications that don't have support for ChaCha20Poly1305, AES-256-GCM is recommended, however it has many drawbacks:
- Slower than ChaCha20Poly1305.
- Catastrophic failure if nonce values are reused.

Example using ChaCha20Poly1305:

import os
# Import ChaCha20Poly1305 from cryptography from cryptography.hazmat.primitives.ciphers.aead import ChaCha20Poly1305
# Our plaintext to encrypt plain_text = b"Secret text to encrypt"
# We do not require authenticated but unencrypted data, so set to None aad = None
# Generate a secure key key = ChaCha20Poly1305.generate_key()
# Create a new ChaCha20Poly1305 instance with our secure key chacha = ChaCha20Poly1305(key)
# Note: nonce values must be regenerated every time they are used. nonce = os.urandom(12)
# Encrypt our plaintext cipher_text = chacha.encrypt(nonce, plain_text, aad)
# Decrypt the plain text using the nonce and cipher_text chacha.decrypt(nonce, cipher_text, aad)

Example using AESGCM:

import os
# Import AESGCM from cryptography from cryptography.hazmat.primitives.ciphers.aead import AESGCM
# Our plaintext to encrypt plain_text = b"Secret text to encrypt"
# We do not require authenticated but unencrypted data, so set to None aad = None
# Generate a secure key key = AESGCM.generate_key(bit_length=128)
# Create a new AESGCM instance with our secure key aesgcm = AESGCM(key)
# Note: nonce values must be regenerated every time they are used. nonce = os.urandom(12)
# Encrypt our plaintext cipher_text = aesgcm.encrypt(nonce, plain_text, aad)
# Decrypt the plain text using the nonce and cipher_text aesgcm.decrypt(nonce, cipher_text, aad)
For more information on the cryptography module see:
OWASP:
  • A02:2021-Cryptographic Failures
  • A3:2017-Sensitive Data Exposure
Use of a broken or risky cryptographic algorithm python_crypto_rule-crypto-cipher-blowfish, CWE-327 Severity: Medium

The Blowfish encryption algorithm was meant as a drop-in replacement for DES and was created in
1993. Smaller key sizes may make the ciphertext vulnerable to birthday attacks. While no known attacks against Blowfish exist, it should never be used to encrypt files over 4GB in size. If possible consider using ChaCha20Poly1305 or AES-GCM instead of Blowfish.

For older applications that don't have support for ChaCha20Poly1305, AES-256-GCM is recommended, however it has many drawbacks:
- Slower than ChaCha20Poly1305.
- Catastrophic failure if nonce values are reused.

Note that the Crypto and Cryptodome Python packages are no longer recommended for new applications, instead consider using the cryptography package.

Example using ChaCha20Poly1305:

import os
# Import ChaCha20Poly1305 from cryptography from cryptography.hazmat.primitives.ciphers.aead import ChaCha20Poly1305
# Our plaintext to encrypt plain_text = b"Secret text to encrypt"
# We do not require authenticated but unencrypted data, so set to None aad = None
# Generate a secure key key = ChaCha20Poly1305.generate_key()
# Create a new ChaCha20Poly1305 instance with our secure key chacha = ChaCha20Poly1305(key)
# Note: nonce values must be regenerated every time they are used. nonce = os.urandom(12)
# Encrypt our plaintext cipher_text = chacha.encrypt(nonce, plain_text, aad)
# Decrypt the plain text using the nonce and cipher_text chacha.decrypt(nonce, cipher_text, aad)

Example using AESGCM:

import os
# Import AESGCM from cryptography from cryptography.hazmat.primitives.ciphers.aead import AESGCM
# Our plaintext to encrypt plain_text = b"Secret text to encrypt"
# We do not require authenticated but unencrypted data, so set to None aad = None
# Generate a secure key key = AESGCM.generate_key(bit_length=128)
# Create a new AESGCM instance with our secure key aesgcm = AESGCM(key)
# Note: nonce values must be regenerated every time they are used. nonce = os.urandom(12)
# Encrypt our plaintext cipher_text = aesgcm.encrypt(nonce, plain_text, aad)
# Decrypt the plain text using the nonce and cipher_text aesgcm.decrypt(nonce, cipher_text, aad)
For more information on the cryptography module see:
OWASP:
  • A02:2021-Cryptographic Failures
  • A3:2017-Sensitive Data Exposure
Use of a broken or risky cryptographic algorithm python_crypto_rule-crypto-cipher-des, CWE-327 Severity: Medium

DES, TripleDES, RC2 and RC4 are all considered broken or insecure cryptographic algorithms. Newer algorithms apply message integrity to validate ciphertext has not been tampered with. Consider using ChaCha20Poly1305 instead as it is easier and faster than the alternatives such as AES-256-GCM.

For older applications that don't have support for ChaCha20Poly1305,
AES-256-GCM is recommended, however it has many drawbacks:
- Slower than ChaCha20Poly1305.
- Catastrophic failure if nonce values are reused.

Note that the Crypto and Cryptodome Python packages are no longer recommended for new applications, instead consider using the cryptography package.

Example using ChaCha20Poly1305:

import os
# Import ChaCha20Poly1305 from cryptography from cryptography.hazmat.primitives.ciphers.aead import ChaCha20Poly1305
# Our plaintext to encrypt plain_text = b"Secret text to encrypt"
# We do not require authenticated but unencrypted data, so set to None aad = None
# Generate a secure key key = ChaCha20Poly1305.generate_key()
# Create a new ChaCha20Poly1305 instance with our secure key chacha = ChaCha20Poly1305(key)
# Note: nonce values must be regenerated every time they are used. nonce = os.urandom(12)
# Encrypt our plaintext cipher_text = chacha.encrypt(nonce, plain_text, aad)
# Decrypt the plain text using the nonce and cipher_text chacha.decrypt(nonce, cipher_text, aad)

Example using AESGCM:

import os
# Import AESGCM from cryptography from cryptography.hazmat.primitives.ciphers.aead import AESGCM
# Our plaintext to encrypt plain_text = b"Secret text to encrypt"
# We do not require authenticated but unencrypted data, so set to None aad = None
# Generate a secure key key = AESGCM.generate_key(bit_length=128)
# Create a new AESGCM instance with our secure key aesgcm = AESGCM(key)
# Note: nonce values must be regenerated every time they are used. nonce = os.urandom(12)
# Encrypt our plaintext cipher_text = aesgcm.encrypt(nonce, plain_text, aad)
# Decrypt the plain text using the nonce and cipher_text aesgcm.decrypt(nonce, cipher_text, aad)
For more information on the cryptography module see:
OWASP:
  • A02:2021-Cryptographic Failures
  • A3:2017-Sensitive Data Exposure
Use of a broken or risky cryptographic algorithm python_crypto_rule-crypto-cipher-rc2, CWE-327 Severity: Medium

DES, TripleDES, RC2 and RC4 are all considered broken or insecure cryptographic algorithms. Newer algorithms apply message integrity to validate ciphertext has not been tampered with. Consider using ChaCha20Poly1305 instead as it is easier and faster than the alternatives such as AES-256-GCM.

For older applications that don't have support for ChaCha20Poly1305,
AES-256-GCM is recommended, however it has many drawbacks:
- Slower than ChaCha20Poly1305.
- Catastrophic failure if nonce values are reused.

Note that the Crypto and Cryptodome Python packages are no longer recommended for new applications, instead consider using the cryptography package.

Example using ChaCha20Poly1305:

import os
# Import ChaCha20Poly1305 from cryptography from cryptography.hazmat.primitives.ciphers.aead import ChaCha20Poly1305
# Our plaintext to encrypt plain_text = b"Secret text to encrypt"
# We do not require authenticated but unencrypted data, so set to None aad = None
# Generate a secure key key = ChaCha20Poly1305.generate_key()
# Create a new ChaCha20Poly1305 instance with our secure key chacha = ChaCha20Poly1305(key)
# Note: nonce values must be regenerated every time they are used. nonce = os.urandom(12)
# Encrypt our plaintext cipher_text = chacha.encrypt(nonce, plain_text, aad)
# Decrypt the plain text using the nonce and cipher_text chacha.decrypt(nonce, cipher_text, aad)

Example using AESGCM:

import os
# Import AESGCM from cryptography from cryptography.hazmat.primitives.ciphers.aead import AESGCM
# Our plaintext to encrypt plain_text = b"Secret text to encrypt"
# We do not require authenticated but unencrypted data, so set to None aad = None
# Generate a secure key key = AESGCM.generate_key(bit_length=128)
# Create a new AESGCM instance with our secure key aesgcm = AESGCM(key)
# Note: nonce values must be regenerated every time they are used. nonce = os.urandom(12)
# Encrypt our plaintext cipher_text = aesgcm.encrypt(nonce, plain_text, aad)
# Decrypt the plain text using the nonce and cipher_text aesgcm.decrypt(nonce, cipher_text, aad)
For more information on the cryptography module see:
OWASP:
  • A02:2021-Cryptographic Failures
  • A3:2017-Sensitive Data Exposure
Use of a broken or risky cryptographic algorithm python_crypto_rule-crypto-cipher-rc4, CWE-327 Severity: Medium

DES, TripleDES, RC2 and RC4 are all considered broken or insecure cryptographic algorithms. Newer algorithms apply message integrity to validate ciphertext has not been tampered with. Consider using ChaCha20Poly1305 instead as it is easier and faster than the alternatives such as AES-256-GCM.

For older applications that don't have support for ChaCha20Poly1305,
AES-256-GCM is recommended, however it has many drawbacks:
- Slower than ChaCha20Poly1305.
- Catastrophic failure if nonce values are reused.

Note that the Crypto and Cryptodome Python packages are no longer recommended for new applications, instead consider using the cryptography package.

Example using ChaCha20Poly1305:

import os
# Import ChaCha20Poly1305 from cryptography from cryptography.hazmat.primitives.ciphers.aead import ChaCha20Poly1305
# Our plaintext to encrypt plain_text = b"Secret text to encrypt"
# We do not require authenticated but unencrypted data, so set to None aad = None
# Generate a secure key key = ChaCha20Poly1305.generate_key()
# Create a new ChaCha20Poly1305 instance with our secure key chacha = ChaCha20Poly1305(key)
# Note: nonce values must be regenerated every time they are used. nonce = os.urandom(12)
# Encrypt our plaintext cipher_text = chacha.encrypt(nonce, plain_text, aad)
# Decrypt the plain text using the nonce and cipher_text chacha.decrypt(nonce, cipher_text, aad)

Example using AESGCM:

import os
# Import AESGCM from cryptography from cryptography.hazmat.primitives.ciphers.aead import AESGCM
# Our plaintext to encrypt plain_text = b"Secret text to encrypt"
# We do not require authenticated but unencrypted data, so set to None aad = None
# Generate a secure key key = AESGCM.generate_key(bit_length=128)
# Create a new AESGCM instance with our secure key aesgcm = AESGCM(key)
# Note: nonce values must be regenerated every time they are used. nonce = os.urandom(12)
# Encrypt our plaintext cipher_text = aesgcm.encrypt(nonce, plain_text, aad)
# Decrypt the plain text using the nonce and cipher_text aesgcm.decrypt(nonce, cipher_text, aad)
For more information on the cryptography module see:
OWASP:
  • A02:2021-Cryptographic Failures
  • A3:2017-Sensitive Data Exposure
Use of a broken or risky cryptographic algorithm python_crypto_rule-crypto-cipher-xor, CWE-327 Severity: Medium

The application was found using the xor algorithm, which can be trivially decoded. Newer algorithms apply message integrity to validate ciphertext has not been tampered with. Consider using ChaCha20Poly1305 instead as it is easier and faster than the alternatives such as AES-256-GCM.

For older applications that don't have support for ChaCha20Poly1305,
AES-256-GCM is recommended, however it has many drawbacks:
- Slower than ChaCha20Poly1305.
- Catastrophic failure if nonce values are reused.

Note that the Crypto and Cryptodome Python packages are no longer recommended for new applications, instead consider using the cryptography package.

Example using ChaCha20Poly1305:

import os
# Import ChaCha20Poly1305 from cryptography from cryptography.hazmat.primitives.ciphers.aead import ChaCha20Poly1305
# Our plaintext to encrypt plain_text = b"Secret text to encrypt"
# We do not require authenticated but unencrypted data, so set to None aad = None
# Generate a secure key key = ChaCha20Poly1305.generate_key()
# Create a new ChaCha20Poly1305 instance with our secure key chacha = ChaCha20Poly1305(key)
# Note: nonce values must be regenerated every time they are used. nonce = os.urandom(12)
# Encrypt our plaintext cipher_text = chacha.encrypt(nonce, plain_text, aad)
# Decrypt the plain text using the nonce and cipher_text chacha.decrypt(nonce, cipher_text, aad)

Example using AESGCM:

import os
# Import AESGCM from cryptography from cryptography.hazmat.primitives.ciphers.aead import AESGCM
# Our plaintext to encrypt plain_text = b"Secret text to encrypt"
# We do not require authenticated but unencrypted data, so set to None aad = None
# Generate a secure key key = AESGCM.generate_key(bit_length=128)
# Create a new AESGCM instance with our secure key aesgcm = AESGCM(key)
# Note: nonce values must be regenerated every time they are used. nonce = os.urandom(12)
# Encrypt our plaintext cipher_text = aesgcm.encrypt(nonce, plain_text, aad)
# Decrypt the plain text using the nonce and cipher_text aesgcm.decrypt(nonce, cipher_text, aad)
For more information on the cryptography module see:
OWASP:
  • A02:2021-Cryptographic Failures
  • A3:2017-Sensitive Data Exposure
Inadequate encryption strength python_crypto_rule-crypto-encrypt-dsa-rsa, CWE-326 Severity: Medium

The application is generating an RSA key that is less than the recommended 2048 bits. The National Institute of Standards and Technology (NIST) deprecated signing Digital Certificates that contained RSA Public Keys of 1024 bits in December 2010. While
1024-bit RSA keys have not been factored yet, advances in compute may make it possible in the near future.

Consider upgrading to the newer asymmetric algorithm such as X25519 which handles the complexities of generating key pairs and choosing correct key sizes for you:

from cryptography.hazmat.primitives.asymmetric.x25519 import X25519PrivateKey

# Generate a private key for use in the exchange. private_key = X25519PrivateKey.generate()
# Work with private key/exchange with a peer's
# public key to created a shared and derived key
# ...

Otherwise use a key size greater than 2048 when generating RSA keys:

from cryptography.hazmat.primitives.asymmetric import rsa
# Generate a private key of 4096 bits private_key = rsa.generate_private_key(
# do not change the exponent value from 65537
public_exponent=65537,
key_size=4096,
)
# Work with the private key to sign/encrypt data
# ...
For more information on using the cryptography module see:
latest
OWASP:
  • A02:2021-Cryptographic Failures
  • A3:2017-Sensitive Data Exposure
Inadequate encryption strength python_crypto_rule-crypto-encrypt-ec, CWE-326 Severity: Medium

The application was found using an insufficient curve size for the Elliptical Cryptography (EC) asymmetric algorithm. NIST recommends using a key size of
224 or greater.

To remediate this issue, replace the current key size with ec.SECP384R1,

Example using ec.SECP384R1:

from cryptography.hazmat.primitives.asymmetric import ec
# Generate an EC private key using SECP384R1
private_key = ec.generate_private_key(
ec.SECP384R1()
)
# Work with/sign data using the key
# ...
For more information on the cryptography module's EC section see:
OWASP:
  • A02:2021-Cryptographic Failures
  • A3:2017-Sensitive Data Exposure
Use of a broken or risky cryptographic algorithm python_crypto_rule-crypto-hash-md5, CWE-327 Severity: Medium

The application was found using an insecure or risky digest or signature algorithm. MD5
and SHA1 hash algorithms have been found to be vulnerable to producing collisions.

This means that two different values, when hashed, can lead to the same hash value. If the application is trying to use these hash methods for storing passwords, then it is recommended to switch to a password hashing algorithm such as Argon2id or PBKDF2. It is strongly recommended that a standard digest algorithm be chosen instead as implementing a custom algorithm is prone to errors.

Note that the Crypto and Cryptodome Python packages are no longer recommended for new applications, instead consider using the cryptography package.

Example of creating a SHA-384 hash using the cryptography package:

from cryptography.hazmat.primitives import hashes
# Create a SHA384 digest digest = hashes.Hash(hashes.SHA384())
# Update the digest with some initial data digest.update(b"some data to hash")
# Add more data to the digest digest.update(b"some more data")
# Finalize the digest as bytes result = digest.finalize()
For more information on secure password storage see OWASP:
Password_Storage_Cheat_Sheet.html
For more information on the cryptography module see:
OWASP:
  • A02:2021-Cryptographic Failures
  • A3:2017-Sensitive Data Exposure
Use of a broken or risky cryptographic algorithm python_crypto_rule-crypto-hash-sha1, CWE-327 Severity: Medium

The application was found using an insecure or risky digest or signature algorithm. MD5
and SHA1 hash algorithms have been found to be vulnerable to producing collisions.

This means that two different values, when hashed, can lead to the same hash value. If the application is trying to use these hash methods for storing passwords, then it is recommended to switch to a password hashing algorithm such as Argon2id or PBKDF2. It is strongly recommended that a standard digest algorithm be chosen instead as implementing a custom algorithm is prone to errors.

Note that the Crypto and Cryptodome Python packages are no longer recommended for new applications, instead consider using the cryptography package.

Example of creating a SHA-384 hash using the cryptography package:

from cryptography.hazmat.primitives import hashes
# Create a SHA384 digest digest = hashes.Hash(hashes.SHA384())
# Update the digest with some initial data digest.update(b"some data to hash")
# Add more data to the digest digest.update(b"some more data")
# Finalize the digest as bytes result = digest.finalize()
For more information on secure password storage see OWASP:
Password_Storage_Cheat_Sheet.html
For more information on the cryptography module see:
OWASP:
  • A02:2021-Cryptographic Failures
  • A3:2017-Sensitive Data Exposure
Use of a broken or risky cryptographic algorithm python_crypto_rule-crypto-hazmat-cipher-arc4, CWE-327 Severity: Medium

DES, TripleDES, RC2 and RC4 are all considered broken or insecure cryptographic algorithms. Newer algorithms apply message integrity to validate ciphertext has not been tampered with. Consider using ChaCha20Poly1305 instead as it is easier and faster than the alternatives such as AES-256-GCM.

For older applications that don't have support for ChaCha20Poly1305,
AES-256-GCM is recommended, however it has many drawbacks:
- Slower than ChaCha20Poly1305.
- Catastrophic failure if nonce values are reused.

Example using ChaCha20Poly1305:

import os
# Import ChaCha20Poly1305 from cryptography from cryptography.hazmat.primitives.ciphers.aead import ChaCha20Poly1305
# Our plaintext to encrypt plain_text = b"Secret text to encrypt"
# We do not require authenticated but unencrypted data, so set to None aad = None
# Generate a secure key key = ChaCha20Poly1305.generate_key()
# Create a new ChaCha20Poly1305 instance with our secure key chacha = ChaCha20Poly1305(key)
# Note: nonce values must be regenerated every time they are used. nonce = os.urandom(12)
# Encrypt our plaintext cipher_text = chacha.encrypt(nonce, plain_text, aad)
# Decrypt the plain text using the nonce and cipher_text chacha.decrypt(nonce, cipher_text, aad)

Example using AESGCM:

import os
# Import AESGCM from cryptography from cryptography.hazmat.primitives.ciphers.aead import AESGCM
# Our plaintext to encrypt plain_text = b"Secret text to encrypt"
# We do not require authenticated but unencrypted data, so set to None aad = None
# Generate a secure key key = AESGCM.generate_key(bit_length=128)
# Create a new AESGCM instance with our secure key aesgcm = AESGCM(key)
# Note: nonce values must be regenerated every time they are used. nonce = os.urandom(12)
# Encrypt our plaintext cipher_text = aesgcm.encrypt(nonce, plain_text, aad)
# Decrypt the plain text using the nonce and cipher_text aesgcm.decrypt(nonce, cipher_text, aad)
For more information on the cryptography module see:
OWASP:
  • A02:2021-Cryptographic Failures
  • A3:2017-Sensitive Data Exposure
Use of a broken or risky cryptographic algorithm python_crypto_rule-crypto-hazmat-cipher-blowfish, CWE-327 Severity: Medium

The Blowfish encryption algorithm was meant as a drop-in replacement for DES and was created in
1993. Smaller key sizes may make the ciphertext vulnerable to birthday attacks. While no known attacks against Blowfish exist, it should never be used to encrypt files over 4GB in size. If possible consider using ChaCha20Poly1305 or AES-GCM instead of Blowfish.

For older applications that don't have support for ChaCha20Poly1305, AES-256-GCM is recommended, however it has many drawbacks:
- Slower than ChaCha20Poly1305.
- Catastrophic failure if nonce values are reused.

Example using ChaCha20Poly1305:

import os
# Import ChaCha20Poly1305 from cryptography from cryptography.hazmat.primitives.ciphers.aead import ChaCha20Poly1305
# Our plaintext to encrypt plain_text = b"Secret text to encrypt"
# We do not require authenticated but unencrypted data, so set to None aad = None
# Generate a secure key key = ChaCha20Poly1305.generate_key()
# Create a new ChaCha20Poly1305 instance with our secure key chacha = ChaCha20Poly1305(key)
# Note: nonce values must be regenerated every time they are used. nonce = os.urandom(12)
# Encrypt our plaintext cipher_text = chacha.encrypt(nonce, plain_text, aad)
# Decrypt the plain text using the nonce and cipher_text chacha.decrypt(nonce, cipher_text, aad)

Example using AESGCM:

import os
# Import AESGCM from cryptography from cryptography.hazmat.primitives.ciphers.aead import AESGCM
# Our plaintext to encrypt plain_text = b"Secret text to encrypt"
# We do not require authenticated but unencrypted data, so set to None aad = None
# Generate a secure key key = AESGCM.generate_key(bit_length=128)
# Create a new AESGCM instance with our secure key aesgcm = AESGCM(key)
# Note: nonce values must be regenerated every time they are used. nonce = os.urandom(12)
# Encrypt our plaintext cipher_text = aesgcm.encrypt(nonce, plain_text, aad)
# Decrypt the plain text using the nonce and cipher_text aesgcm.decrypt(nonce, cipher_text, aad)
For more information on the cryptography module see:
OWASP:
  • A02:2021-Cryptographic Failures
  • A3:2017-Sensitive Data Exposure
Use of a Broken or Risky Cryptographic Algorithm python_crypto_rule-crypto-hazmat-cipher-idea, CWE-327 Severity: Medium

The IDEA encryption algorithm was meant as a drop-in replacement for DES and was created in
1991. A number of vulnerabilities and exploits have been identified to work against IDEA and it is no longer recommended. If possible consider using ChaCha20Poly1305 or AES-GCM instead of Blowfish.

For older applications that don't have support for ChaCha20Poly1305, AES-256-GCM is recommended, however it has many drawbacks:
- Slower than ChaCha20Poly1305.
- Catastrophic failure if nonce values are reused.

Example using ChaCha20Poly1305:

import os
# Import ChaCha20Poly1305 from cryptography from cryptography.hazmat.primitives.ciphers.aead import ChaCha20Poly1305
# Our plaintext to encrypt plain_text = b"Secret text to encrypt"
# We do not require authenticated but unencrypted data, so set to None aad = None
# Generate a secure key key = ChaCha20Poly1305.generate_key()
# Create a new ChaCha20Poly1305 instance with our secure key chacha = ChaCha20Poly1305(key)
# Note: nonce values must be regenerated every time they are used. nonce = os.urandom(12)
# Encrypt our plaintext cipher_text = chacha.encrypt(nonce, plain_text, aad)
# Decrypt the plain text using the nonce and cipher_text chacha.decrypt(nonce, cipher_text, aad)

Example using AESGCM:

import os
# Import AESGCM from cryptography from cryptography.hazmat.primitives.ciphers.aead import AESGCM
# Our plaintext to encrypt plain_text = b"Secret text to encrypt"
# We do not require authenticated but unencrypted data, so set to None aad = None
# Generate a secure key key = AESGCM.generate_key(bit_length=128)
# Create a new AESGCM instance with our secure key aesgcm = AESGCM(key)
# Note: nonce values must be regenerated every time they are used. nonce = os.urandom(12)
# Encrypt our plaintext cipher_text = aesgcm.encrypt(nonce, plain_text, aad)
# Decrypt the plain text using the nonce and cipher_text aesgcm.decrypt(nonce, cipher_text, aad)
For more information on the cryptography module see:
OWASP:
  • A02:2021-Cryptographic Failures
  • A3:2017-Sensitive Data Exposure
Use of a broken or risky cryptographic algorithm python_crypto_rule-crypto.hazmat-hash-md5, CWE-327 Severity: Medium

The application was found using an insecure or risky digest or signature algorithm. MD2, MD5
and SHA1 hash algorithms have been found to be vulnerable to producing collisions.

This means that two different values, when hashed, can lead to the same hash value. If the application is trying to use these hash methods for storing passwords, then it is recommended to switch to a password hashing algorithm such as Argon2id or PBKDF2. It is strongly recommended that a standard digest algorithm be chosen instead as implementing a custom algorithm is prone to errors.

Example of creating a SHA-384 hash using the cryptography package:

from cryptography.hazmat.primitives import hashes
# Create a SHA384 digest digest = hashes.Hash(hashes.SHA384())
# Update the digest with some initial data digest.update(b"some data to hash")
# Add more data to the digest digest.update(b"some more data")
# Finalize the digest as bytes result = digest.finalize()
For more information on secure password storage see OWASP:
Password_Storage_Cheat_Sheet.html
For more information on the cryptography module see:
OWASP:
  • A02:2021-Cryptographic Failures
  • A3:2017-Sensitive Data Exposure
Use of a broken or risky cryptographic algorithm python_crypto_rule-crypto.hazmat-hash-sha1, CWE-327 Severity: Medium

The application was found using an insecure or risky digest or signature algorithm. MD2, MD5
and SHA1 hash algorithms have been found to be vulnerable to producing collisions.

This means that two different values, when hashed, can lead to the same hash value. If the application is trying to use these hash methods for storing passwords, then it is recommended to switch to a password hashing algorithm such as Argon2id or PBKDF2. It is strongly recommended that a standard digest algorithm be chosen instead as implementing a custom algorithm is prone to error.

Example of creating a SHA-384 hash using the cryptography package:

from cryptography.hazmat.primitives import hashes
# Create a SHA384 digest digest = hashes.Hash(hashes.SHA384())
# Update the digest with some initial data digest.update(b"some data to hash")
# Add more data to the digest digest.update(b"some more data")
# Finalize the digest as bytes result = digest.finalize()
For more information on secure password storage see OWASP:
Password_Storage_Cheat_Sheet.html
For more information on the cryptography module see:
OWASP:
  • A02:2021-Cryptographic Failures
  • A3:2017-Sensitive Data Exposure
Use of a broken or risky cryptographic algorithm python_crypto_rule-hash-md2, CWE-327 Severity: Medium

The application was found using an insecure or risky digest or signature algorithm. MD2, MD5
and SHA1 hash algorithms have been found to be vulnerable to producing collisions.

This means that two different values, when hashed, can lead to the same hash value. If the application is trying to use these hash methods for storing passwords, then it is recommended to switch to a password hashing algorithm such as Argon2id or PBKDF2.

Note that the Crypto and Cryptodome Python packages are no longer recommended for new applications, instead consider using the cryptography package.

Example of creating a SHA-384 hash using the cryptography package:

from cryptography.hazmat.primitives import hashes
# Create a SHA384 digest digest = hashes.Hash(hashes.SHA384())
# Update the digest with some initial data digest.update(b"some data to hash")
# Add more data to the digest digest.update(b"some more data")
# Finalize the digest as bytes result = digest.finalize()
For more information on secure password storage see OWASP:
Password_Storage_Cheat_Sheet.html
For more information on the cryptography module see:
OWASP:
  • A02:2021-Cryptographic Failures
  • A3:2017-Sensitive Data Exposure
Use of a broken or risky cryptographic algorithm python_crypto_rule-hash-md4, CWE-327 Severity: Medium

The application was found using an insecure or risky digest or signature algorithm. MD2, MD4,
MD5 and SHA1 hash algorithms have been found to be vulnerable to producing collisions.

This means that two different values, when hashed, can lead to the same hash value. If the application is trying to use these hash methods for storing passwords, then it is recommended to switch to a password hashing algorithm such as Argon2id or PBKDF2.

Note that the Crypto and Cryptodome Python packages are no longer recommended for new applications, instead consider using the cryptography package.

Example of creating a SHA-384 hash using the cryptography package:

from cryptography.hazmat.primitives import hashes
# Create a SHA384 digest digest = hashes.Hash(hashes.SHA384())
# Update the digest with some initial data digest.update(b"some data to hash")
# Add more data to the digest digest.update(b"some more data")
# Finalize the digest as bytes result = digest.finalize()
For more information on secure password storage see OWASP:
Password_Storage_Cheat_Sheet.html
For more information on the cryptography module see:
OWASP:
  • A02:2021-Cryptographic Failures
  • A3:2017-Sensitive Data Exposure
Use of a broken or risky cryptographic algorithm python_crypto_rule-hash-md5, CWE-327 Severity: Medium

The application was found using an insecure or risky digest or signature algorithm. MD2, MD4,
MD5 and SHA1 hash algorithms have been found to be vulnerable to producing collisions.

This means that two different values, when hashed, can lead to the same hash value. If the application is trying to use these hash methods for storing passwords, then it is recommended to switch to a password hashing algorithm such as Argon2id or PBKDF2.

Note that the Crypto and Cryptodome Python packages are no longer recommended for new applications, instead consider using the cryptography package.

Example of creating a SHA-384 hash using the cryptography package:

from cryptography.hazmat.primitives import hashes
# Create a SHA384 digest digest = hashes.Hash(hashes.SHA384())
# Update the digest with some initial data digest.update(b"some data to hash")
# Add more data to the digest digest.update(b"some more data")
# Finalize the digest as bytes result = digest.finalize()
For more information on secure password storage see OWASP:
Password_Storage_Cheat_Sheet.html
For more information on the cryptography module see:
OWASP:
  • A02:2021-Cryptographic Failures
  • A3:2017-Sensitive Data Exposure
Use of a broken or risky cryptographic algorithm python_crypto_rule-hash-sha1, CWE-327 Severity: Medium

The application was found using an insecure or risky digest or signature algorithm. MD2, MD4,
MD5 and SHA1 hash algorithms have been found to be vulnerable to producing collisions.

This means that two different values, when hashed, can lead to the same hash value. If the application is trying to use these hash methods for storing passwords, then it is recommended to switch to a password hashing algorithm such as Argon2id or PBKDF2.

Note that the Crypto and Cryptodome Python packages are no longer recommended for new applications, instead consider using the cryptography package.

Example of creating a SHA-384 hash using the cryptography package:

from cryptography.hazmat.primitives import hashes
# Create a SHA384 digest digest = hashes.Hash(hashes.SHA384())
# Update the digest with some initial data digest.update(b"some data to hash")
# Add more data to the digest digest.update(b"some more data")
# Finalize the digest as bytes result = digest.finalize()
For more information on secure password storage see OWASP:
Password_Storage_Cheat_Sheet.html
For more information on the cryptography module see:
OWASP:
  • A02:2021-Cryptographic Failures
  • A3:2017-Sensitive Data Exposure
Use of a broken or risky cryptographic algorithm python_crypto_rule-hashlib-new-insecure-functions, CWE-327 Severity: Medium

The application was found using an insecure or risky digest or signature algorithm. MD2, MD4, MD5 and SHA1 hash algorithms have been found to be vulnerable to producing collisions.

This means that two different values, when hashed, can lead to the same hash value. If the application is trying to use these hash methods for storing passwords, then it is recommended to switch to a password hashing algorithm such as Argon2id or PBKDF2. It is strongly recommended that a standard digest algorithm be chosen instead as implementing a custom algorithm is prone to errors.

Example using hashlib.sha384() to create a SHA384 hash:

import hashlib
# Create a SHA384 digest digest = hashlib.sha384()
# Update the digest with some initial data digest.update(b"some data to hash")
# Add more data to the digest digest.update(b"some more data")
# Finalize the digest as bytes digest.digest()
OWASP:
  • A02:2021-Cryptographic Failures
  • A3:2017-Sensitive Data Exposure
Use of unmaintained third party components python_crypto_rule-import-pycrypto, CWE-1104 Severity: Medium

The application was detected importing pycrypto. This package has been deprecated as it contains security vulnerabilities.

To remediate this issue, consider using the cryptography
package instead.

OWASP:
  • A02:2021-Cryptographic Failures
  • A9:2017-Using Components with Known Vulnerabilities
Improper encoding or escaping of output python_escaping_rule-jinja2-autoescape-false, CWE-116 Severity: Medium

The application was found using Jinja2 Environment without autoescaping enabled. If using in the context of HTML this could lead to Cross-Site Scripting (XSS) attacks when rendering with user-supplied input.

Unfortunately, Jinja2 does not support context-aware escaping, meaning it is insufficient to protect against XSS for the various web contexts. It is important to encode the data depending on the specific context it is used in. There are at least six context types:

  • Inside HTML tags <div>context 1</div>
  • Inside attributes: <div class="context 2"></div>
  • Inside event attributes <button onclick="context 3">button</button>
  • Inside script blocks: <script>var x = "context 4"</script>
  • Unsafe element HTML assignment: element.innerHTML = "context 5"
  • Inside URLs: <iframe src="context 6"></iframe><a href="context 6">link</a>

Script blocks alone have multiple ways they need to be encoded. Extra care must be taken if user input is ever output inside of script tags.

User input that is displayed within the application must be encoded, sanitized or validated to ensure it cannot be treated as HTML or executed as Javascript code. Care must also be taken to not mix server-side templating with client-side templating, as the server-side templating will not encode things like {{ 77 }} which may execute client-side templating features.

It is NOT advised to encode user input prior to inserting into a data store. The data will need to be encoded depending on context of where it is output. It is much safer to force the displaying system to handle the encoding and not attempt to guess how it should be encoded.

To handle different contexts, one approach would be to write custom Jinja2 filters. Below is an example that escapes or encodes links and potentially malicious script, note this does not include other contexts such as CSS or attributes:

from jinja2 import Environment, select_autoescape, FileSystemLoader from jinja2 import pass_eval_context from markupsafe import Markup, escape

@pass_eval_context def escape_link(eval_ctx, value):
bad_link = "#JinjatmplZ"
# Block any values that start with // as that could be used to inject
# links to third party pages see: Wikipedia:Protocol-relative_URL
if value.startswith('//'):
return bad_link

# Only allow relative links
# if you want to allow links that start with http or ws replace with below:
# if not value.startswith('/'): and not value.startswith('http') and not value.startswith('ws')
if not value.startswith('/'):
return bad_link

# Alternatively, you could only call escape if autoescape is true
# if eval_ctx.autoescape:
# return escape(value)
# else
# return value

return escape(value)

# Create a replacement table js_replacement = str.maketrans({
'"': "\u0022",
'': &quot;\\u0060&quot;,<br/> '&amp;': &quot;\\u0026&quot;,<br/> '\'': &quot;\\u0027&quot;,<br/> '+': &quot;\\u002b&quot;,<br/> '/': &quot;\\/&quot;,<br/> '&lt;': &quot;\\u003c&quot;,<br/> '&gt;': &quot;\\u003e&quot;,<br/> '\\': &quot;\\\\&quot;,<br/> '(': &quot;\\u0028&quot;,<br/> ')': &quot;\\u0029&quot;,<br/> })<br/><br/>@pass_eval_context def escape_js(eval_ctx, value):<br/> &quot;&quot;&quot;<br/> Escape the input for use in &lt;script&gt; context, USE WITH CAUTION<br/> It is strongly recommended to _never_ pass user-supplied input to<br/> the JavaScript context. This may still be unsafe depending where<br/> used, it does not consider characters used in regular expressions<br/> for example.<br/> &quot;&quot;&quot;<br/><br/> #if eval_ctx.autoescape:<br/> # value = escape(value)<br/> # Escape by default<br/> value = escape(value)<br/> # Translate any potential characters using our translation table<br/> return value.translate(js_replacement)<br/><br/># Create our environment, setting autoescape to use the default<br/># select_autoescape function env = Environment(<br/> loader=FileSystemLoader(os.getcwd()+&quot;/template&quot;),<br/> autoescape=select_autoescape,<br/>)<br/># Add an escape link filter to be used in our template env.filters[&quot;escape_link&quot;] = escape_link env.filters[&quot;escape_js&quot;] = escape_js<br/># Load our template file template = env.get_template(&quot;mytemplate.html&quot;)<br/># Render with different variables which call our filters print(template.render(<br/> html_context=&quot;&lt;img src=x onerror=alert(1)&gt;&quot;,<br/> link_context=&quot;/# onclick=alert(1)&lt;script&gt;alert(1)&lt;/script&gt;&quot;,<br/> script_context=&quot;alert(1);alert1`",)
)

# Sample template:
"""
<!DOCTYPE html>
<html lang="en">
<head>
<title>My Webpage</title>
</head>
<body>
<h1>My Webpage</h1>
{{ html_context }}
<a href="{{ link_context | escape_link }}">link</a>
<script>{{ script_context | escape_js }}</script>
</body>
</html>
"""
For more information on autoescape see:
For more information on XSS see OWASP:
Cross_Site_Scripting_Prevention_Cheat_Sheet.html
OWASP:*
  • A03:2021-Injection
  • A7:2017-Cross-Site Scripting (XSS)
Improper neutralization of input during web page generation ('Cross-site Scripting') python_escaping_rule-use-of-mako-templates, CWE-79 Severity: Medium

The application was found using mako templates without default_filters
being passed to the Template or TemplateLookup constructors. If using
in the context of HTML, this could lead to Cross-Site Scripting (XSS) attacks
when rendering with user-supplied input.

Unfortunately, Jinja2 does not support context-aware escaping, meaning it is insufficient to protect against XSS for the various web contexts. It is
important to encode the data depending on the specific context it is used in.
There are at least six context types:

  • Inside HTML tags <div>context 1</div>
  • Inside attributes: <div class="context 2"></div>
  • Inside event attributes <button onclick="context 3">button</button>
  • Inside script blocks: <script>var x = "context 4"</script>
  • Unsafe element HTML assignment: element.innerHTML = "context 5"
  • Inside URLs:
    <iframe src="context 6"></iframe><a href="context 6">link</a>

Script blocks alone have multiple ways they need to be encoded. Extra care must be taken if user input is ever output inside of script tags.

User input that is displayed within the application must be encoded, sanitized or validated to ensure it cannot be treated as HTML or executed
as Javascript code. Care must also be taken to not mix server-side templating
with client-side templating, as the server-side templating will not encode things
like {{ 77 }} which may execute client-side templating features.

It is NOT advised to encode user input prior to inserting into a data store. The data will need to be encoded depending on context of where it is output.
It is much safer to force the displaying system to handle the encoding and
not attempt to guess how it should be encoded.

To handle different contexts, one approach would be to write custom mako filters. Below is an example that escapes or encodes links and
potentially malicious script, note this does not include other contexts
such as CSS or attributes:

# filters.py module:

def escape_link(value):
bad_link = "#JinjatmplZ"
# Block any values that start with // as that could be used to inject
# links to third party pages see: Wikipedia:Protocol-relative_URL
if value.startswith('//'):
return bad_link

# Only allow relative links
# if you want to allow links that start with http or ws replace with below:
# if not value.startswith('/'): and not value.startswith('http') and not value.startswith('ws')
if not value.startswith('/'):
return bad_link

return value

# Create a replacement table js_replacement = str.maketrans({
'\0': "\u0000",
'\t': "\t",
'\n': "\n",
'\v': "\u000b",
'\f': "\f&quot;,<br/> '\r': &quot;\\r&quot;,<br/> '&quot;': &quot;\\u0022&quot;,<br/> '': "\u0060",
'&': "\u0026",
'\'': "\u0027",
'+': "\u002b",
'/': "\/",
'<': "\u003c",
'>': "\u003e",
'\': "\\",
'(': "\u0028",
')': "\u0029",
})

def escape_js(value):
# Escape the input for use in <script> context, USE WITH CAUTION
# It is strongly recommended to never pass user-supplied input to
# the JavaScript context.

# Translate any potential characters using our translation table
return value.translate(js_replacement)

#####################################################################
# main module: #
#####################################################################
from mako.template import Template

# Define our template, note the calls to our custom filters depending
# on context template_text = """

<!DOCTYPE html>
<html lang="en">
<head>
<title>My Webpage</title>
</head>
<body>
<h1>My Webpage</h1>
${html_context}
<a href="${link_context | escape_link}">link</a>
<script>${script_context | escape_js}</script>
</body>
</html>
"""

# Load our template with default filters and our imported filters for
# usage in template files t = Template(template_text,
# By default enable the html filter with 'h'
default_filters=['h'],
# Import our custom filters
imports=["from filters import escape_link, escape_js"])

# Render our template print(t.render(html_context="<img src=x onerror=alert(1)>",
link_context="/# onclick=alert(1)<script>alert(1)</script>",
script_context="alert(1)<img src=x onerror=alert(1)>",)
)
OWASP:*
  • A03:2021-Injection
  • A7:2017-Cross-Site Scripting (XSS)
Incorrect permission assignment for critical resource python_file-permissions_rule-general-bad-permission, CWE-732 Severity: Medium

The application was found setting file permissions to overly permissive values. Consider using the following values if the application user is the only process to access the file:

  • 0400 - read only access to the file
  • 0200 - write only access to the file
  • 0600 - read/write access to the file

Example creating a file with read/write permissions for the application user:

# Use octal values to set 0o600 (read/write access to the file) for the current
# user os.chmod('somefile.txt', 0o600)

For all other values please see: File-system_permissions

OWASP:
  • A01:2021-Broken Access Control
  • A5:2017-Broken Access Control
Improper limitation of a pathname to a restricted directory ('Path Traversal') python_files_rule-tarfile-unsafe-members, CWE-22 Severity: Medium

The application may be vulnerable to a path traversal if it extracts untrusted archive files. This vulnerability is colloquially known as 'Zip Slip'. Archive files may contain folders which, when extracted, may write outside of the intended directory. This is exploited by including path traversal characters such as ../../other/directory to overwrite or place files in system or application directories.

Extra care must be taken when extracting archive files as there are numerous concerns:

  • If possible, generate unique filenames instead of using the archives file names, as it may be possible for users to overwrite files if the filenames are the same.
  • Validate file paths are written with a prefixed, known trusted directory.
  • Only process regular files and not symbolic links, as some applications may attempt to read/follow the symbolic link, leading to arbitrary file read / write vulnerabilities.

Example of securely processing an archive file:

import tarfile import uuid
# import os

tar = tarfile.open('some.tar')

# Max number of allowed files in our archive max_files = 10
# Max size for all files in archive max_size = 1024 * 1024 * 10 # 10MB
# Max size per file in archive max_file_size = 1024 * 1024 # 1MB

# Validate number of files in archive if len(tar.getmembers()) > max_files:
raise Exception("Too many files in archive")

total_size = 0
# Loop over all files to see if we exceed max size
# if so, do not process any of them. for f in tar.getmembers():
total_size += f.size
if total_size >= max_size:
raise Exception("Archive files exceeded max file size")

# Iterate over files now that we know the total size is within limits for f in tar.getmembers():
# Internally this calls TarInfo.isreg() which ensures
# the file is a regular file and not a sym link or directory
if not f.isfile():
continue

# Optional, set a limit on each file size
if f.size > max_file_size:
raise Exception(f"File {f.name} too large: {f.size}")

# If original names are required, ensure that only the
# filename is used:
# filename = os.path.basename(f.name)

# More secure, generate a UUID4 value instead
filename = uuid.uuid4().hex

# Reset the archive filename to the basename
# Newer versions of python (3.11.4+) should use:
# new_tar = old_tar.replace(name=...new name...)
f.name = filename

# Extract the file into a restricted directory, with our
# own user's attributes, not the file from the archive
tar.extract(f, '/opt/app/restricted/', set_attrs=False)
For more information on tarfile see:
tarfile.html
OWASP:
  • A01:2021-Broken Access Control
  • A5:2017-Broken Access Control
Active debug code python_flask_rule-app-debug, CWE-489 Severity: Medium

The Flask application is running with debug=True configured. By enabling this option, certain exceptions or errors could cause sensitive information to be leaked in HTTP responses.

Additionally, it is not recommended to run a Flask application using Flask.run(...) in production. Instead, a WSGI server such as
gunicorn
or waitress be used instead.

For more information on deployment options for Flask applications see:
OWASP:
  • A05:2021-Security Misconfiguration
  • A6:2017-Security Misconfiguration
Cleartext transmission of sensitive information python_ftp_rule-ftplib, CWE-319 Severity: Medium

The application was found using an FTP library. As FTP does not provide encryption, it is strongly recommended that any file transfers be done over a more secure transport such as SSH.

The paramiko library can be used with an SCP module to allow secure file transfers.

Example using paramiko SSH client and the scp module:

import paramiko import scp

# Create an SSH client with paramiko.SSHClient() as ssh:
# Load the system host keys so we can confirm the
# host we are connecting to is legitimate
ssh.load_system_host_keys('/home/appuser/.ssh/known_hosts')

# Connect to the remote host using our SSH private key
ssh.connect(hostname='example.org',
port=22,
username='appuser',
key_filename='/home/appuser/.ssh/private_key')

# Create an SCP client with the ssh transport and copy files
with scp.SCPClient(ssh.get_transport()) as secure_copy:
secure_copy.get('remote/test.file', 'local/test.file')
secure_copy.put('local/some.file', 'remote/some.file')
For more information on the paramiko module see:
For more information on the scp module see:
scp.py
OWASP:
  • A02:2021-Cryptographic Failures
  • A3:2017-Sensitive Data Exposure
Allocation of resources without limits or throttling python_requests_rule-request-without-timeout, CWE-770 Severity: Medium

The application was found using the requests module without configuring a timeout value for connections. This could lead to uncontrolled resource consumption where the application could run out of socket descriptors, effectively causing a Denial of Service (DoS).

To remediate this issue, pass in a timeout= argument to each requests call.

Example using a timeout for an HTTP GET request:

# Issue a GET request to https://example.com with a timeout of 10 seconds response = requests.get('https://example.com', timeout=10)
# Work with the response object
# ...
For more information on using the requests module see:
OWASP:
  • A05:2021-Security Misconfiguration
  • A6:2017-Security Misconfiguration
Cleartext transmission of sensitive information python_snmp_rule-insecure-snmp-version, CWE-319 Severity: Medium

Pysnmp was detected using versions SNMPv1 or SNMPv2. SNPMv1 and SNMPv2 are insecure and should no longer be used as they do not offer encryption.

If possible, query SNMP devices using SNMPv3 instead.

Example querying a device using SNMPv3 with SHA-AES:

from pysnmp.hlapi import 
# Create the snpm iterator iterator = getCmd(
SnmpEngine(),
# Configure using SHA AES
UsmUserData('usr-sha-aes', 'authkey1', 'privkey1',
authProtocol=USM_AUTH_HMAC96_SHA,
privProtocol=USM_PRIV_CFB128_AES),
UdpTransportTarget(('demo.snmplabs.com', 161)),
ContextData(),
ObjectType(ObjectIdentity('SNMPv2-MIB', 'sysDescr', 0))
)
For more information on using SNMPv3 with Pysnmp see:
snmp-versions.html
OWASP:*
  • A02:2021-Cryptographic Failures
  • A3:2017-Sensitive Data Exposure
Cleartext transmission of sensitive information python_snmp_rule-snmp-weak-cryptography, CWE-319 Severity: Medium

Pysnmp was detected using SNMPv3 without authentication or encryption protections enabled.

  • Use of usmNoAuthProtocol or usmNoPrivProtocol indicates that either authentication or privacy, respectively, is not being used.
  • The absence of authKey (or authKey=None) implies no authentication,
    which is equivalent to using usmNoAuthProtocol.
  • The absence of privKey (or privKey=None) implies no privacy (encryption),
    which is equivalent to using usmNoPrivProtocol.

To enhance the security of your SNMP communications, it is recommended to use both authentication and privacy features in SNMPv3:

  • Use SHA for Authentication: SHA (Secure Hash Algorithm) is a more secure option
    for SNMP message authentication. To use SHA, set the authProtocol to
    usmHMACSHAAuthProtocol and provide a strong authKey.
  • Use AES for Privacy: AES (Advanced Encryption Standard) is recommended for
    encrypting SNMP messages. Set the privProtocol to usmAesCfb128Protocol
    or a similar AES-based protocol and specify a strong privKey.

Example of secure UsmUserData configuration:

  from pysnmp.hlapi import UsmUserData, usmHMACSHAAuthProtocol, usmAesCfb128Protocol

user_data = UsmUserData('username','authKey', 'privKey',
authProtocol=usmHMACSHAAuthProtocol,
privProtocol=usmAesCfb128Protocol)
OWASP:
  • A02:2021-Cryptographic Failures
  • A3:2017-Sensitive Data Exposure
Key exchange without entity authentication python_ssh_rule-ssh-nohost-key-verification, CWE-322 Severity: Medium

The application was found to ignore host keys. Host keys are important as they provide assurance that the client can prove that the host is trusted. By ignoring these host keys, it is impossible for the client to validate the connection is to a trusted host.

To remediate this issue, remove the call to set_missing_host_key_policy(...) which sets the host key policy. Instead, load key files using either load_system_host_keys
or load_host_keys to only allow known good hosts. By not setting a host key policy for unknown hosts, paramiko's default policy is to use RejectPolicy.

Example configuration connecting to a known, trusted host, and not allowing connections to unknown hosts:

import paramiko

# Create an SSH client with paramiko.SSHClient() as ssh:
# Load the system host keys so we can confirm the
# host we are connecting to is legitimate
ssh.load_system_host_keys('/home/appuser/.ssh/known_hosts')

# Connect to the remote host using our SSH private key
ssh.connect(hostname='example.org',
port=22,
username='appuser',
key_filename='/home/appuser/.ssh/private_key')
For more information on set_missing_host_key_policy see:
client.html
OWASP:
  • A07:2021-Identification and Authentication Failures
  • A5:2017-Broken Access Control
Improper certificate validation python_ssl_rule-req-no-certvalid, CWE-295 Severity: Medium

The application was found using the requests module without configuring a timeout value for connections. The verify=False argument has been set, which effectively disables the validation of server certificates.

This allows for an adversary who is in between the application and the target host to intercept potentially sensitive information or transmit malicious data.

To remediate this issue either remove the verify=False argument, or set verify=Trueto each
requests call.

Example verifying server certificates for an HTTP GET request:

# Issue a GET request to https://example.com with a timeout of 10 seconds and verify the
# server certificate explicitly. response = requests.get('https://example.com', timeout=10, verify=True)
# Work with the response object
# ...
For more information on using the requests module see:
OWASP:
  • A07:2021-Identification and Authentication Failures
  • A2:2017-Broken Authentication
Inadequate encryption strength python_ssl_rule-ssl-no-version, CWE-326 Severity: Medium

The application was found calling ssl.wrap_socket without a TLS protocol version specified. Additionally, ssl.wrap_socket has been deprecated since Python 3.7. It is strongly recommended that newer applications use TLS 1.2 or 1.3 and SSLContext.wrap_socket.

To remediate this issue, create a new TLS context and pass in ssl.PROTOCOL_TLS_CLIENT
for clients or ssl.PROTOCOL_TLS_SERVER for servers to the ssl.SSLContext(...) protocol=
argument. When converting the socket to a TLS socket, use the new SSLContext.wrap_socket
method instead.

Example creating a TLS 1.3 client socket connection by using a newer version of Python
(3.11.4) and the SSL module:

import ssl import socket

# Create our initial socket with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
# Connect the socket
sock.connect(('www.example.org', 443))

# Create a new SSLContext with protocol set to ssl.PROTOCOL_TLS_CLIENT
# This will auto-select the highest grade TLS protocol version (1.3)
context = ssl.SSLContext(protocol=ssl.PROTOCOL_TLS_CLIENT)
# Load our a certificates for server certificate authentication
context.load_verify_locations('cert.pem')
# Create our TLS socket, and validate the server hostname matches
with context.wrap_socket(sock, server_hostname="www.example.org") as tls_sock:
# Send some bytes over the socket (HTTP request in this case)\
data = bytes('GET / HTTP/1.1\r\nHost: example.org\r\n\r\n', 'utf-8')
sent_bytes = tls_sock.send(data)
# Validate number of sent bytes
# ...
# Read the response
resp = tls_sock.recv()
# Work with the response
# ...
For more information on the ssl module see:
ssl.html
OWASP:
  • A02:2021-Cryptographic Failures
  • A3:2017-Sensitive Data Exposure
Inadequate Encryption Strength python_ssl_rule-ssl-with-bad-version, CWE-326 Severity: Medium

The application was found calling an SSL module with SSL or TLS protocols that have known deficiencies. It is strongly recommended that newer applications use TLS 1.2 or 1.3 and
SSLContext.wrap_socket.

If using the pyOpenSSL module, please note that it has been deprecated and the Python Cryptographic Authority strongly suggests moving to use the pyca/cryptography
module instead.

To remediate this issue for the ssl module, create a new TLS context and pass in
ssl.PROTOCOL_TLS_CLIENT for clients or ssl.PROTOCOL_TLS_SERVER for servers to the
ssl.SSLContext(...) protocol=
argument. When converting the socket to a TLS socket, use the new SSLContext.wrap_socket
method instead.

Example creating a TLS 1.3 client socket connection by using a newer version of Python
(3.11.4) and the SSL module:

import ssl import socket

# Create our initial socket with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
# Connect the socket
sock.connect(('www.example.org', 443))

# Create a new SSLContext with protocol set to ssl.PROTOCOL_TLS_CLIENT
# This will auto-select the highest grade TLS protocol version (1.3)
context = ssl.SSLContext(protocol=ssl.PROTOCOL_TLS_CLIENT)
# Load our a certificates for server certificate authentication
context.load_verify_locations('cert.pem')
# Create our TLS socket, and validate the server hostname matches
with context.wrap_socket(sock, server_hostname="www.example.org") as tls_sock:
# Send some bytes over the socket (HTTP request in this case)\
data = bytes('GET / HTTP/1.1\r\nHost: example.org\r\n\r\n', 'utf-8')
sent_bytes = tls_sock.send(data)
# Validate number of sent bytes
# ...
# Read the response
resp = tls_sock.recv()
# Work with the response
# ...
For more information on the ssl module see:
ssl.html
For more information on pyca/cryptography and openssl see:
OWASP:
  • A02:2021-Cryptographic Failures
  • A3:2017-Sensitive Data Exposure
Improper certificate validation python_ssl_rule-unverified-context, CWE-295 Severity: Medium

The application was found creating a SSL context using the _create_unverified_context. This effectively disables the validation of server certificates.

This allows for an adversary who is in between the application and the target host to intercept potentially sensitive information or transmit malicious data.

To remediate this issue remove the call to _create_unverified_context and either create a default context using ssl.create_default_context or create a context with TLS 1.3.

Example creating a TLS 1.3 client socket connection by using a newer version of Python
(3.11.4) and the SSL module:

import ssl import socket

# Create our initial socket with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
# Connect the socket
sock.connect(('www.example.org', 443))

# Create a new SSLContext with protocol set to ssl.PROTOCOL_TLS_CLIENT
# This will auto-select the highest grade TLS protocol version (1.3)
context = ssl.SSLContext(protocol=ssl.PROTOCOL_TLS_CLIENT)
# Load our a certificates for server certificate authentication
context.load_verify_locations('cert.pem')
# Create our TLS socket, and validate the server hostname matches
with context.wrap_socket(sock, server_hostname="www.example.org") as tls_sock:
# Send some bytes over the socket (HTTP request in this case)\
data = bytes('GET / HTTP/1.1\r\nHost: example.org\r\n\r\n', 'utf-8')
sent_bytes = tls_sock.send(data)
# Validate number of sent bytes
# ...
# Read the response
resp = tls_sock.recv()
# Work with the response
# ...

Unverified SSL context detected. This will permit insecure connections without verifyingSSL
certificates. Use ssl.create_default_context() instead.

OWASP:
  • A07:2021-Identification and Authentication Failures
  • A2:2017-Broken Authentication
Cleartext transmission of sensitive information python_telnet_rule-import-telnib, CWE-319 Severity: Medium

The application was found using a telnet library. As telnet does not provide encryption, it is strongly recommended that communications use a more secure transport such as SSH.

The paramiko library can be used to initiate SSH connections.

Example using paramiko SSH client:

import paramiko import scp

# Create an SSH client with paramiko.SSHClient() as ssh:
# Load the system host keys so we can confirm the
# host we are connecting to is legitimate
ssh.load_system_host_keys('/home/appuser/.ssh/known_hosts')

# Connect to the remote host using our SSH private key
ssh.connect(hostname='example.org',
port=22,
username='appuser',
key_filename='/home/appuser/.ssh/private_key')
# Work with the connection
For more information on the paramiko module see:
OWASP:
  • A02:2021-Cryptographic Failures
  • A3:2017-Sensitive Data Exposure
Insecure temporary file python_tmpdir_rule-hardcodedtmp, CWE-377 Severity: Medium

The application was found creating files in shared system temporary directories
(/tmp or /var/tmp) without using the tempfile.TemporaryFile function. Depending on how the application uses this temporary file, an attacker may be able to create symlinks that point to other files prior to the application creating or writing to the target file, leading to unintended files being created or overwritten.

Example using tempfile.TemporaryFile to write a file:

import tempfile

# Open a new temporary file using a context manager with tempfile.TemporaryFile() as fp:
# Write some data to the temporary file
fp.write(b'Some data')
# Seek back to beginning of file
fp.seek(0)
# Read it
data = fp.read()
# File is automatically closed/removed once we exit the with context
For more information on alternative tempfile functions see:
tempfile.html
OWASP:
  • A01:2021-Broken Access Control
  • A5:2017-Broken Access Control
Insecure temporary file python_tmpdir_rule-mktemp-q, CWE-377 Severity: Medium

The application was found creating temporary files with the insecure mktemp method. Depending on how the application uses this temporary file, an attacker may be able to create symlinks that point to other files prior to the application creating or writing to the target file, leading to unintended files being created or overwritten.

To remediate this issue consider using tempfile.TemporaryFile instead.

Example using tempfile.TemporaryFile to write a file:

import tempfile

# Open a new temporary file using a context manager with tempfile.TemporaryFile() as fp:
# Write some data to the temporary file
fp.write(b'Some data')
# Seek back to beginning of file
fp.seek(0)
# Read it
data = fp.read()
# File is automatically closed/removed once we exit the with context
For more information on alternative tempfile functions see:
tempfile.html
OWASP:
  • A01:2021-Broken Access Control
  • A3:2017-Sensitive Data Exposure
Improper authorization in handler for custom URL scheme python_urlopen_rule-urllib-urlopen, CWE-939 Severity: Medium

The application was found passing in a non-literal value to the urllib methods which issue requests. urllib supports the file:// scheme, which may allow an adversary who can control the URL value to read arbitrary files on the file system.

To remediate this issue either hardcode the URLs being used in urllib or use the requests
module instead.

Example using the requests module to issue an HTTPS request:

import requests
# Issue a GET request to https://example.com with a timeout of 10 seconds response = requests.get('https://example.com', timeout=10)
# Work with the response object
# ...
OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Improper restriction of XML external entity reference python_xml_rule-celement, CWE-611 Severity: Medium

The application was found using the xml.etree package for processing XML. Pythons default xml processors suffer from various XML parsing vulnerabilities and care must be taken when handling XML data. Additionally, depending on the version of Python, more critical vulnerabilities such as eXternal XML Entity injection maybe exploitable.

The etree package suffers from the following security risks as of Python 3.7.1:
Billion laughs / exponential entity expansion - May allow an adversary to cause
a Denial of Service (DoS) against the application parsing arbitrary XML.
Quadratic blowup entity expansion - Similar to above, but requires a larger input
to cause the Denial of Service.

To remediate the above issues, consider using the
defusedxml
library when processing untrusted XML.

Example parsing an XML document using defusedxml:

from defusedxml.ElementTree import parse

# Parse the inventory.xml file et = parse('inventory.xml')
# Get the root element root = et.getroot()
# Work with the root element
# ...
For more information on the various XML parsers and their vulnerabilities please see:
xml.html
For more information on XML security see OWASP's guide:
XML_External_Entity_Prevention_Cheat_Sheet.html
OWASP:
  • A03:2021-Injection
  • A4:2017-XML External Entities (XXE)
Improper restriction of XML external entity reference python_xml_rule-element, CWE-611 Severity: Medium

The application was found using the xml.etree package for processing XML. Pythons default xml processors suffer from various XML parsing vulnerabilities and care must be taken when handling XML data. Additionally, depending on the version of Python, more critical vulnerabilities such as eXternal XML Entity injection maybe exploitable.

The etree package suffers from the following security risks as of Python 3.7.1:
Billion laughs / exponential entity expansion - May allow an adversary to cause
a Denial of Service (DoS) against the application parsing arbitrary XML.
Quadratic blowup entity expansion - Similar to above, but requires a larger input
to cause the Denial of Service.

To remediate the above issues, consider using the
defusedxml
library when processing untrusted XML.

Example parsing an XML document using defusedxml:

from defusedxml.ElementTree import parse

# Parse the inventory.xml file et = parse('inventory.xml')
# Get the root element root = et.getroot()
# Work with the root element
# ...
For more information on the various XML parsers and their vulnerabilities please see:
xml.html
For more information on XML security see OWASP's guide:
XML_External_Entity_Prevention_Cheat_Sheet.html
OWASP:
  • A03:2021-Injection
  • A4:2017-XML External Entities (XXE)
Improper restriction of XML external entity reference python_xml_rule-etree, CWE-611 Severity: Medium

The application was found using the lxml.etree package for processing XML. Python's default XML processors suffer from various XML parsing vulnerabilities and care must be taken when handling XML data. Additionally, depending on the version of Python, more critical vulnerabilities such as eXternal XML Entity injection maybe exploitable.

The etree package suffers from the following security risks as of Python 3.7.1:
Billion laughs / exponential entity expansion - May allow an adversary to cause
a Denial of Service (DoS) against the application parsing arbitrary XML.
Quadratic blowup entity expansion - Similar to above, but requires a larger input
to cause the Denial of Service.

To remediate the above issues, consider using the
defusedxml
library when processing untrusted XML.

Example parsing an XML document using defusedxml:

from defusedxml.ElementTree import parse

# Parse the inventory.xml file et = parse('inventory.xml')
# Get the root element root = et.getroot()
# Work with the root element
# ...
For more information on the various XML parsers and their vulnerabilities please see:
xml.html
For more information on XML security see OWASP's guide:
XML_External_Entity_Prevention_Cheat_Sheet.html
OWASP:
  • A03:2021-Injection
  • A4:2017-XML External Entities (XXE)
Improper restriction of XML external entity reference python_xml_rule-expatbuilder, CWE-611 Severity: Medium

The application was found using the xml.dom.expatbuilder which calls the xml.dom.minidom
package for processing XML. Python's default XML processors suffer from various XML parsing vulnerabilities and care must be taken when handling XML data. Additionally, depending on the version of Python, more critical vulnerabilities such as eXternal XML Entity injection maybe exploitable.

The xml.dom.minidom package suffers from the following security risks as of Python 3.7.1:
Billion laughs / exponential entity expansion - May allow an adversary to cause
a Denial of Service (DoS) against the application parsing arbitrary XML.
Quadratic blowup entity expansion - Similar to above, but requires a larger input
to cause the Denial of Service.

To remediate the above issues, consider using the
defusedxml
library when processing untrusted XML.

Example parsing an XML document using defusedxml:

from defusedxml.ElementTree import parse

# Parse the inventory.xml file et = parse('inventory.xml')
# Get the root element root = et.getroot()
# Work with the root element
# ...
For more information on the various XML parsers and their vulnerabilities please see:
xml.html
For more information on XML security see OWASP's guide:
XML_External_Entity_Prevention_Cheat_Sheet.html
OWASP:
  • A03:2021-Injection
  • A4:2017-XML External Entities (XXE)
Improper restriction of XML external entity reference python_xml_rule-expatreader, CWE-611 Severity: Medium

The application was found using the xml.sax.expatreader package for processing XML. Python's default XML processors suffer from various XML parsing vulnerabilities and care must be taken when handling XML data. Additionally, depending on the version of Python, more critical vulnerabilities such as eXternal XML Entity injection maybe exploitable.

The xml.sax package suffers from the following security risks as of Python 3.7.1:
Billion laughs / exponential entity expansion - May allow an adversary to cause
a Denial of Service (DoS) against the application parsing arbitrary XML.
Quadratic blowup entity expansion - Similar to above, but requires a larger input
to cause the Denial of Service.

To remediate the above issues, consider using the
defusedxml
library when processing untrusted XML.

Example parsing an XML document using defusedxml:

from defusedxml.ElementTree import parse

# Parse the inventory.xml file et = parse('inventory.xml')
# Get the root element root = et.getroot()
# Work with the root element
# ...
For more information on the various XML parsers and their vulnerabilities please see:
xml.html
For more information on XML security see OWASP's guide:
XML_External_Entity_Prevention_Cheat_Sheet.html
OWASP:
  • A03:2021-Injection
  • A4:2017-XML External Entities (XXE)
Improper restriction of XML external entity reference python_xml_rule-minidom, CWE-611 Severity: Medium

The application was found using the xml.dom.minidom package for processing XML. Python's default XML processors suffer from various XML parsing vulnerabilities and care must be taken when handling XML data. Additionally, depending on the version of Python, more critical vulnerabilities such as eXternal XML Entity injection maybe exploitable.

The xml.dom.minidom package suffers from the following security risks as of Python 3.7.1:
Billion laughs / exponential entity expansion - May allow an adversary to cause
a Denial of Service (DoS) against the application parsing arbitrary XML.
Quadratic blowup entity expansion - Similar to above, but requires a larger input
to cause the Denial of Service.

To remediate the above issues, consider using the
defusedxml
library when processing untrusted XML.

Example parsing an XML document using defusedxml:

from defusedxml.ElementTree import parse

# Parse the inventory.xml file et = parse('inventory.xml')
# Get the root element root = et.getroot()
# Work with the root element
# ...
For more information on the various XML parsers and their vulnerabilities please see:
xml.html
For more information on XML security see OWASP's guide:
XML_External_Entity_Prevention_Cheat_Sheet.html
OWASP:
  • A03:2021-Injection
  • A4:2017-XML External Entities (XXE)
Improper restriction of XML external entity reference python_xml_rule-pulldom, CWE-611 Severity: Medium

The application was found using the xml.dom.pulldom package for processing XML. Python's default XML processors suffer from various XML parsing vulnerabilities and care must be taken when handling XML data. Additionally, depending on the version of Python, more critical vulnerabilities such as eXternal XML Entity injection maybe exploitable.

The xml.dom.pulldom package suffers from the following security risks as of Python 3.7.1:
Billion laughs / exponential entity expansion - May allow an adversary to cause
a Denial of Service (DoS) against the application parsing arbitrary XML.
Quadratic blowup entity expansion - Similar to above, but requires a larger input
to cause the Denial of Service.

To remediate the above issues, consider using the
defusedxml
library when processing untrusted XML.

Example parsing an XML document using defusedxml:

from defusedxml.ElementTree import parse

# Parse the inventory.xml file et = parse('inventory.xml')
# Get the root element root = et.getroot()
# Work with the root element
# ...
For more information on the various XML parsers and their vulnerabilities please see:
xml.html
For more information on XML security see OWASP's guide:
XML_External_Entity_Prevention_Cheat_Sheet.html
OWASP:
  • A03:2021-Injection
  • A4:2017-XML External Entities (XXE)
Improper restriction of XML external entity reference python_xml_rule-sax, CWE-611 Severity: Medium

The application was found using the xml.sax package for processing XML. Python's default XML processors suffer from various XML parsing vulnerabilities and care must be taken when handling XML data. Additionally, depending on the version of Python, more critical vulnerabilities such as eXternal XML Entity injection maybe exploitable.

The xml.sax package suffers from the following security risks as of Python 3.7.1:
Billion laughs / exponential entity expansion - May allow an adversary to cause
a Denial of Service (DoS) against the application parsing arbitrary XML.
Quadratic blowup entity expansion - Similar to above, but requires a larger input
to cause the Denial of Service.

To remediate the above issues, consider using the
defusedxml
library when processing untrusted XML.

Example parsing an XML document using defusedxml:

from defusedxml.ElementTree import parse

# Parse the inventory.xml file et = parse('inventory.xml')
# Get the root element root = et.getroot()
# Work with the root element
# ...
For more information on the various XML parsers and their vulnerabilities please see:
xml.html
For more information on XML security see OWASP's guide:
XML_External_Entity_Prevention_Cheat_Sheet.html
OWASP:
  • A03:2021-Injection
  • A4:2017-XML External Entities (XXE)
Binding to an unrestricted IP address python_bind-all-interfaces_rule-general-bindall-interfaces, CWE-1327 Severity: Low

Binding to all network interfaces can potentially open up a service to traffic on unintended interfaces, that may not be properly documented or secured. By passing "0.0.0.0", "::" or an empty string as the address to the socket.bind
function, the application will bind to all interfaces.

Consider passing in the interface ip address through an environment variable, configuration file, or by determining the primary interface(s) IP address.

Example getting the IP address from an environment variable IP_ADDRESS:

# Get the IP_ADDRESS env variable, or bind to
# 127.0.0.1 if it is not set address = os.getenv("IP_ADDRESS", "127.0.0.1")
# Create an internet socket sock = socket.socket(socket.AF_INET)
# Set the port to listen on port = 9777
# Bind to the address and port combination sock.bind((address, port))
# Listen for connections sock.listen()
# Handle the connection
OWASP:
  • A05:2021-Security Misconfiguration
  • A6:2017-Security Misconfiguration
Use of cryptographically weak pseudo-random number generator (PRNG) python_random_rule-random, CWE-338 Severity: Low

Depending on the context, generating weak random numbers may expose cryptographic functions, which rely on these numbers, to be exploitable. When generating numbers for sensitive values such as tokens, nonces, and cryptographic keys, it is recommended that the secrets module be used instead.

Example using the secrets module:

import secrets

# Generate a secure random 64 byte array random_bytes = secrets.token_bytes(64)
print(random_bytes)

# Generate a secure random 64 byte array as a hex string random_bytes_hex = secrets.token_hex(64)

# Generate a secure random 64 byte array base64 encoded for use in URLs random_string = secrets.token_urlsafe(64)
For more information on the secrets module see:
secrets.html
OWASP:
  • A02:2021-Cryptographic Failures
  • A3:2017-Sensitive Data Exposure
Improper check for unusual or exceptional conditions python_assert_rule-assert-used, CWE-754 Severity: Info

The application was found using assert in non-test code. Usually reserved for debug and test code, the assert
function is commonly used to test conditions before continuing execution. However, enclosed code will be removed when compiling Python code to optimized byte code. Depending on the assertion and subsequent logic, this could lead to undefined behavior of the application or application crashes.

To remediate this issue, remove the assert calls. If necessary, replace them with either if
conditions or
try/except blocks.

Example using try/except instead of assert:

# Below try/except is equal to the assert statement of:
# assert user.is_authenticated(), "user must be authenticated"
try:
if not user.is_authenticated():
raise AuthError("user must be authenticated")
except AuthError as e:
# Handle error
# ...
# Return, do not continue processing
return
OWASP:
  • A05:2021-Security Misconfiguration
  • A6:2017-Security Misconfiguration

scala

Name Identifiers Description
Use of Hard-coded Password scala_password_rule-ConstantDBPassword, CWE-259 Severity: Critical

A potential hard-coded password was identified in a database connection string. Passwords should not be stored directly in code but loaded from secure locations such as a Key Management System (KMS).

The purpose of using a Key Management System is so access can be audited and keys easily rotated in the event of a breach. By hardcoding passwords, it will be extremely difficult to determine when or if, a key is compromised.

The recommendation on which KMS to use depends on the environment the application is running in:

OWASP:
Use of Hard-coded Password scala_password_rule-EmptyDBPassword, CWE-259 Severity: Critical

The application does not provide authentication when communicating a database server. It is strongly recommended that the database server be configured with authentication and restrict what queries users can execute.

Please see your database server's documentation on how to configure a password.

Additionally, passwords should not be stored directly in code but loaded from secure locations such as a Key Management System (KMS).

The purpose of using a Key Management System is so access can be audited and keys easily rotated in the event of a breach. By hardcoding passwords, it will be extremely difficult to determine when or if, a key is compromised.

The recommendation on which KMS to use depends on the environment the application is running in:

OWASP:
Improper Neutralization of CRLF Sequences in HTTP Headers ('HTTP Response Splitting') scala_cookie_rule-HttpResponseSplitting, CWE-113 Severity: High

When an HTTP request contains unexpected CR and LF characters, the server may respond with an output stream that is interpreted as two different HTTP responses (instead of one). An attacker can control the second response and mount attacks such as cross-site scripting and cache poisoning attacks.

OWASP:
Improper Neutralization of CRLF Sequences in HTTP Headers ('HTTP Response Splitting') scala_cookie_rule-RequestParamToHeader, CWE-113 Severity: High

This code directly writes an HTTP parameter to an HTTP header, which allows for a HTTP response splitting vulnerability. See http://en.wikipedia.org/wiki/HTTP_response_splitting for more information.

OWASP:
Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection') scala_inject_rule-CustomInjectionSQLString, CWE-89 Severity: High

The method identified is susceptible to injection. The input should be validated and properly escaped.

OWASP:
Improper Control of Generation of Code ('Code Injection') scala_inject_rule-ELInjection, CWE-94 Severity: High

An expression is built with a dynamic value. The source of the value(s) should be verified to avoid that unfiltered values fall into this risky code evaluation.

OWASP:
Improper limitation of a pathname to a restricted directory ('Path Traversal') scala_inject_rule-PathTraversalOut, CWE-22 Severity: High

A file is opened to write to its contents. The filename comes from an input parameter. If an unfiltered parameter is passed to this file API, files at an arbitrary filesystem location could be modified. This rule identifies potential path traversal vulnerabilities. In many cases, the constructed file path cannot be controlled by the user.

OWASP:
  • A01:2021-Broken Access Control
  • A5:2017-Broken Access Control
Improperly implemented security check for standard scala_ldap_rule-EntryPoisoning, CWE-358 Severity: High

Without proper access control, executing an LDAP statement that contains a user-controlled value can allow an attacker to abuse poorly configured LDAP context

OWASP:
Use of Hard-coded Password scala_password_rule-HardcodePassword, CWE-259 Severity: High

A potential hard-coded password was identified in the source code. Passwords should not be stored directly in code but loaded from secure locations such as a Key Management System (KMS).

The purpose of using a Key Management System is so access can be audited and keys easily rotated in the event of a breach. By hardcoding passwords, it will be extremely difficult to determine when or if, a key is compromised.

The recommendation on which KMS to use depends on the environment the application is running in:

OWASP:
Incorrect Permission Assignment for Critical Resource scala_perm_rule-OverlyPermissiveFilePermissionInline, CWE-732 Severity: High

Overly permissive file permission

OWASP:
Improper Validation of Certificate with Host Mismatch scala_smtp_rule-InsecureSmtp, CWE-297 Severity: High

Server identity verification is disabled when making SSL connections.

OWASP:
  • A07:2021-Identification and Authentication Failures
  • A2:2017-Broken Authentication
Improper Neutralization of Special Elements used in a Command scala_smtp_rule-SmtpClient, CWE-77 Severity: High

Simple Mail Transfer Protocol (SMTP) is a the text based protocol used for email delivery. Like with HTTP, headers are separate by new line separator. If kuser input is place in a header line, the application should remove or replace new line characters (CR / LF). You should use a safe wrapper such as Apache Common Email and Simple Java Mail which filter special characters that can lead to header injection.

OWASP:
External Control of System or Configuration Setting scala_unsafe_rule-ExternalConfigControl, CWE-15 Severity: High

Allowing external control of system settings can disrupt service or cause an application to behave in unexpected, and potentially malicious ways. An attacker could cause an error by providing a nonexistent catalog name or connect to an unauthorized portion of the database.

OWASP:
Deserialization of Untrusted Data scala_xml_rule-XmlDecoder, CWE-502 Severity: High

Avoid using XMLDecoder to parse content from an untrusted source.

OWASP:
Inadequate Encryption Strength scala_crypto_rule-BlowfishKeySize, CWE-326 Severity: Medium

A small key size makes the ciphertext vulnerable to brute force attacks. At least 128 bits of entropy should be used when generating the key if use of Blowfish is required.

OWASP:
Inadequate Encryption Strength scala_crypto_rule-CipherDESInsecure, CWE-326 Severity: Medium

DES is considered strong ciphers for modern applications. Currently, NIST recommends the usage of AES block ciphers instead of DES.

OWASP:
Inadequate Encryption Strength scala_crypto_rule-CipherDESedeInsecure, CWE-326 Severity: Medium

Triple DES (also known as 3DES or DESede) is considered strong ciphers for modern applications. NIST recommends the usage of AES block ciphers instead of 3DES.

OWASP:
Inadequate Encryption Strength scala_crypto_rule-CipherECBMode, CWE-326 Severity: Medium

An authentication cipher mode which provides better confidentiality of the encrypted data should be used instead of Electronic Code Book (ECB) mode, which does not provide good confidentiality. Specifically, ECB mode produces the same output for the same input each time. This allows an attacker to intercept and replay the data.

OWASP:
Missing Support for Integrity Check scala_crypto_rule-CipherIntegrity, CWE-353 Severity: Medium

The ciphertext produced is susceptible to alteration by an adversary. This mean that the cipher provides no way to detect that the data has been tampered with. If the ciphertext can be controlled by an attacker, it could be altered without detection.

OWASP:
Incorrect Behavior Order scala_crypto_rule-CipherPaddingOracle, CWE-696 Severity: Medium

This specific mode of CBC with PKCS5Padding is susceptible to padding oracle attacks. An adversary could potentially decrypt the message if the system exposed the difference between plaintext with invalid padding or valid padding. The distinction between valid and invalid padding is usually revealed through distinct error messages being returned for each condition.

OWASP:
Use of a Broken or Risky Cryptographic Algorithm scala_crypto_rule-CustomMessageDigest, CWE-327 Severity: Medium

Implementing a custom MessageDigest is error-prone. National Institute of Standards and Technology(NIST) recommends the use of SHA-224, SHA-256, SHA-384, SHA-512, SHA-512/224, or SHA-512/256.

OWASP:
Inadequate Encryption Strength scala_crypto_rule-HazelcastSymmetricEncryption, CWE-326 Severity: Medium

The network communications for Hazelcast is configured to use a symmetric cipher (probably DES or Blowfish). Those ciphers alone do not provide integrity or secure authentication. The use of asymmetric encryption is preferred.

OWASP:
Inadequate Encryption Strength scala_crypto_rule-InsufficientKeySizeRsa, CWE-326 Severity: Medium

Detected an insufficient key size for DSA. NIST recommends a key size of 2048 or higher.

OWASP:
Use of a Broken or Risky Cryptographic Algorithm scala_crypto_rule-NullCipher, CWE-327 Severity: Medium

The NullCipher implements the Cipher interface by returning ciphertext identical to the supplied plaintext. In a few contexts, such as testing, a NullCipher may be appropriate. Avoid using the NullCipher. Its accidental use can introduce a significant confidentiality risk.

OWASP:
Use of RSA Algorithm without OAEP scala_crypto_rule-RsaNoPadding, CWE-780 Severity: Medium

The software uses the RSA algorithm but does not incorporate Optimal Asymmetric Encryption Padding (OAEP), which might weaken the encryption.

OWASP:
  • A02:2021-Cryptographic Failures
  • A3:2017-Sensitive Data Exposure
Inadequate Encryption Strength scala_crypto_rule-WeakMessageDigest, CWE-326 Severity: Medium

DES is considered strong ciphers for modern applications. Currently, NIST recommends the usage of AES block ciphers instead of DES.

OWASP:
Improper Certificate Validation scala_crypto_rule-WeakTLSProtocol, CWE-295 Severity: Medium

A HostnameVerifier that accept any host are often use because of certificate reuse on many hosts. As a consequence, this is vulnerable to Man-in-the-middleattacks attacks since the client will trust any certificate.

OWASP:
Use of less trusted source scala_endpoint_rule-JaxRsEndpoint, CWE-348 Severity: Medium

This method is part of a REST Web Service (JSR311). The security of this web service should be analyzed. For example:
- Authentication, if enforced, should be tested.
- Access control, if enforced, should be tested.
- The inputs should be tracked for potential vulnerabilities.
- The communication should ideally be over SSL.
- If the service supports writes (e.g., via POST), its vulnerability to CSRF should be investigated.

OWASP:
Improper limitation of a pathname to a restricted directory ('Path Traversal') scala_file_rule-FilenameUtils, CWE-22 Severity: Medium

A file is opened to read its content. The filename comes from an input parameter. If an unfiltered parameter is passed to this file API, files from an arbitrary filesystem location could be read.

OWASP:
  • A01:2021-Broken Access Control
  • A5:2017-Broken Access Control
Improper Neutralization of Special Elements used in an LDAP Query ('LDAP Injection') scala_inject_rule-LDAPInjection, CWE-90 Severity: Medium

Just like SQL, all inputs passed to an LDAP query need to be passed in safely. Unfortunately, LDAP doesn't have prepared statement interfaces like SQL. Therefore, the primary defense against LDAP injection is strong input validation of any untrusted data before including it in an LDAP query.

OWASP:
Expression injection (OGNL) scala_inject_rule-OgnlInjection, CWE-917 Severity: Medium

"A expression is built with a dynamic value. The source of the value(s) should be verified to avoid that unfiltered values fall into this risky code evaluation."

OWASP:
Improper limitation of a pathname to a restricted directory ('Path Traversal') scala_inject_rule-PathTraversalIn, CWE-22 Severity: Medium

A file is opened to read its content. The filename comes from an input parameter. If an unfiltered parameter is passed to this file API, files from an arbitrary filesystem location could be read. This rule identifies potential path traversal vulnerabilities. In many cases, the constructed file path cannot be controlled by the user.

OWASP:
  • A01:2021-Broken Access Control
  • A5:2017-Broken Access Control
Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection') scala_inject_rule-SqlInjection, CWE-89 Severity: Medium

The input values included in SQL queries need to be passed in safely. Bind variables in prepared statements can be used to easily mitigate the risk of SQL injection.

OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Incorrect Permission Assignment for Critical Resource scala_perm_rule-OverlyPermissiveFilePermissionObj, CWE-732 Severity: Medium

Overly permissive file permission

OWASP:
Improper Control of Generation of Code ('Code Injection') scala_script_rule-SpelView, CWE-94 Severity: Medium

The software constructs all or part of a code segment using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the syntax or behavior of the intended code segment.

OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Server-Side Request Forgery (SSRF) scala_ssrf_rule-PlaySSRF, CWE-918 Severity: Medium

Server-Side Request Forgery occur when a web server executes a request to a user supplied destination parameter that is not validated. Such vulnerabilities could allow an attacker to access internal services or to launch attacks from your web server.

OWASP:
Incorrect Type Conversion or Cast scala_strings_rule-BadHexConversion, CWE-704 Severity: Medium

When converting a byte array containing a hash signature to a human readable string, a conversion mistake can be made if the array is read byte by byte.

OWASP:
Improper Handling of Unicode Encoding scala_strings_rule-ImproperUnicode, CWE-176 Severity: Medium

Improper Handling of Unicode Encoding

OWASP:
Weak authentication scala_xml_rule-SAMLIgnoreComments, CWE-1390 Severity: Medium

Ignoring XML comments in SAML may lead to authentication bypass

OWASP:
Improper Restriction of XML External Entity Reference ('XXE') scala_xpathi_rule-XpathInjection, CWE-611 Severity: Medium

The input values included in SQL queries need to be passed in safely. Bind variables in prepared statements can be used to easily mitigate the risk of SQL injection.

OWASP:
Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting') scala_xss_rule-RequestWrapper, CWE-79 Severity: Medium

Avoid using custom XSS filtering. Please use standard sanitization functions.

OWASP:
Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting') scala_xss_rule-WicketXSS, CWE-79 Severity: Medium

Disabling HTML escaping put the application at risk for Cross-Site Scripting (XSS).

OWASP:
Improper Neutralization of Input During Web Page Generation scala_xss_rule-XSSReqParamToServletWriter, CWE-79 Severity: Medium

Servlet reflected cross site scripting vulnerability

OWASP:
Improper Restriction of XML External Entity Reference ('XXE') scala_xxe_rule-Document, CWE-611 Severity: Medium

XML External Entity (XXE) attacks can occur when an XML parser supports XML entities while processing XML received from an untrusted source.

OWASP:
Improper Restriction of XML External Entity Reference ('XXE') scala_xxe_rule-Trans, CWE-611 Severity: Medium

XML External Entity (XXE) attacks can occur when an XML parser supports XML entities while processing XML received from an untrusted source.

OWASP:
Improper Restriction of XML External Entity Reference ('XXE') scala_xxe_rule-XMLRdr, CWE-611 Severity: Medium

XML External Entity (XXE) attacks can occur when an XML parser supports XML entities while processing XML received from an untrusted source.

OWASP:
Improper Restriction of XML External Entity Reference ('XXE') scala_xxe_rule-XMLStreamRdr, CWE-611 Severity: Medium

XML External Entity (XXE) attacks can occur when an XML parser supports XML entities while processing XML received from an untrusted source.

OWASP:
Improper Restriction of XML External Entity Reference ('XXE') scala_xxe_rule-XPathXXE, CWE-611 Severity: Medium

XML External Entity (XXE) attacks can occur when an XML parser supports XML entities while processing XML received from an untrusted source.

OWASP:
Sensitive Cookie Without 'HttpOnly' Flag scala_cookie_rule-CookieHTTPOnly, CWE-1004 Severity: Low

A new cookie is created without the HttpOnly flag set. The HttpOnly flag is a directive to the browser to make sure that the cookie can not be red by malicious script. When a user is the target of a "Cross-Site Scripting", the attacker would benefit greatly from getting the session id for example.

OWASP:
Information Exposure Through Persistent Cookies scala_cookie_rule-CookieInsecure, CWE-539 Severity: Low

"A new cookie is created without the Secure flag set. The Secure flag is a
directive to the browser to make sure that the cookie is not sent for insecure communication
(http://)"

OWASP:
Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection') scala_inject_rule-CustomInjection, CWE-89 Severity: Low

The method identified is susceptible to injection. The input should be validated and properly escaped.

OWASP:
Server-Side Request Forgery (SSRF) scala_ssrf_rule-SSRF, CWE-918 Severity: Low

Server-Side Request Forgery occur when a web server executes a request to a user supplied destination parameter that is not validated. Such vulnerabilities could allow an attacker to access internal services or to launch attacks from your web server.

OWASP:
Information Exposure Through an Error Message scala_unsafe_rule-InformationExposure, CWE-209 Severity: Low

The sensitive information may be valuable information on its own (such as a password), or it may be useful for launching other, more deadly attacks. If an attack fails, an attacker may use error information provided by the server to launch another more focused attack. For example, an attempt to exploit a path traversal weakness (CWE-22) might yield the full pathname of the installed application.

OWASP:
Sensitive Cookie in HTTPS Session Without 'Secure' Attribute scala_cookie_rule-CookiePersistent, CWE-614 Severity: Info

"Storing sensitive data in a persistent cookie for an extended period can lead to a breach of confidentiality or account compromise."

OWASP:
Sensitive Cookie in HTTPS Session Without 'Secure' Attribute scala_cookie_rule-CookieUsage, CWE-614 Severity: Info

The information stored in a custom cookie should not be sensitive or related to the session. In most cases, sensitive data should only be stored in session and referenced by the user's session cookie.

OWASP:
Improper Neutralization of CRLF Sequences in HTTP Headers ('HTTP Response Splitting') scala_cookie_rule-RequestParamToCookie, CWE-113 Severity: Info

This code constructs an HTTP Cookie using an untrusted HTTP parameter. If this cookie is added to an HTTP response, it will allow a HTTP response splitting vulnerability. See http://en.wikipedia.org/wiki/HTTP_response_splitting for more information.

OWASP:
Trust Boundary Violation scala_cookie_rule-TrustBoundaryViolation, CWE-501 Severity: Info

A trust boundary can be thought of as line drawn through a program. On one side of the line, data is untrusted. On the other side of the line, data is assumed to be trustworthy. The purpose of validation logic is to allow data to safely cross the trust boundary - to move from untrusted to trusted. A trust boundary violation occurs when a program blurs the line between what is trusted and what is untrusted. By combining trusted and untrusted data in the same data structure, it becomes easier for programmers to mistakenly trust unvalidated data.

OWASP:
Permissive Cross-domain Policy with Untrusted Domains scala_cors_rule-PermissiveCORS, CWE-942 Severity: Info

Prior to HTML5, Web browsers enforced the Same Origin Policy which ensures that in order for JavaScript to access the contents of a Web page, both the JavaScript and the Web page must originate from the same domain. Without the Same Origin Policy, a malicious website could serve up JavaScript that loads sensitive information from other websites using a client's credentials, cull through it, and communicate it back to the attacker. HTML5 makes it possible for JavaScript to access data across domains if a new HTTP header called Access-Control-Allow-Origin is defined. With this header, a Web server defines which other domains are allowed to access its domain using cross-origin requests. However, caution should be taken when defining the header because an overly permissive CORS policy will allow a malicious application to communicate with the victim application in an inappropriate way, leading to spoofing, data theft, relay and other attacks.

OWASP:
Inadequate encryption strength scala_crypto_rule-DefaultHTTPClient, CWE-326 Severity: Info

DefaultHttpClient with default constructor is not compatible with TLS 1.2

OWASP:
Use of less trusted source scala_endpoint_rule-JaxWsEndpoint, CWE-348 Severity: Info

This method is part of a SOAP Web Service (JSR224). The security of this web service should be analyzed. For example:
- Authentication, if enforced, should be tested.
- Access control, if enforced, should be tested.
- The inputs should be tracked for potential vulnerabilities.
- The communication should ideally be over SSL.

OWASP:
  • A03:2021-Injection
  • A7:2017-Cross-Site Scripting (XSS)
Cleartext transmission of sensitive information scala_endpoint_rule-UnencryptedSocket, CWE-319 Severity: Info

Beyond using an SSL socket, you need to make sure your use of SSLSocketFactory does all the appropriate certificate validation checks to make sure you are not subject to man-in-the-middle attacks. Please read the OWASP Transport Layer Protection Cheat Sheet for details on how to do this correctly.

OWASP:
  • A02:2021-Cryptographic Failures
  • A3:2017-Sensitive Data Exposure
URL Redirection to Untrusted Site ('Open Redirect') scala_endpoint_rule-UnvalidatedRedirect, CWE-601 Severity: Info

Unvalidated redirects occur when an application redirects a user to a destination URL specified by a user supplied parameter that is not validated. Such vulnerabilities can be used to facilitate phishing attacks.

OWASP:
Improper Certificate Validation scala_endpoint_rule-WeakHostNameVerification, CWE-295 Severity: Info

A HostnameVerifier that accept any host are often use because of certificate reuse on many hosts. As a consequence, this is vulnerable to Man-in-the-middle attacks since the client will trust any certificate.

OWASP:
Improper limitation of a pathname to a restricted directory ('Path Traversal') scala_file_rule-FileUploadFileName, CWE-22 Severity: Info

The filename provided by the FileUpload API can be tampered with by the client to reference unauthorized files. The provided filename should be properly validated to ensure it's properly structured, contains no unauthorized path characters (e.g., / ), and refers to an authorized file.

OWASP:
  • A01:2021-Broken Access Control
  • A5:2017-Broken Access Control
Improper validation of unsafe equivalence in input scala_form_rule-FormValidate, CWE-1289 Severity: Info

Form inputs should have minimal input validation. Preventive validation helps provide defense in depth against a variety of risks.

OWASP:
Improper Neutralization of Special Elements in Data Query Logic scala_inject_rule-AWSQueryInjection, CWE-943 Severity: Info

Constructing SimpleDB queries containing user input can allow an attacker to view unauthorized records.

OWASP:
External Control of System or Configuration Setting scala_inject_rule-BeanPropertyInjection, CWE-15 Severity: Info

An attacker can set arbitrary bean properties that can compromise system integrity. An attacker can leverage this functionality to access special bean properties like class.classLoader that will allow them to override system properties and potentially execute arbitrary code.

OWASP:
Improper Neutralization of CRLF Sequences ('CRLF Injection') scala_inject_rule-CLRFInjectionLogs, CWE-93 Severity: Info

When data from an untrusted source is put into a logger and not neutralized correctly, an attacker could forge log entries or include malicious content. Inserted false entries could be used to skew statistics, distract the administrator or even to implicate another party in the commission of a malicious act. If the log file is processed automatically, the attacker can render the file unusable by corrupting the format of the file or injecting unexpected characters. An attacker may also inject code or other commands into the log file and take advantage of a vulnerability in the log processing utility (e.g. command injection or XSS).

OWASP:
Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection') scala_inject_rule-CommandInjection, CWE-78 Severity: Info

The highlighted API is used to execute a system command. If unfiltered input is passed to this API, it can lead to arbitrary command execution.

OWASP:
Files or Directories Accessible to External Parties scala_inject_rule-FileDisclosure, CWE-552 Severity: Info

Constructing a server-side redirect path with user input could allow an attacker to download application binaries (including application classes or jar files) or view arbitrary files within protected directories.

OWASP:
Improper Neutralization of Argument Delimiters in a Command ('Argument Injection') scala_inject_rule-HttpParameterPollution, CWE-88 Severity: Info

Concatenating unvalidated user input into a URL can allow an attacker to override the value of a request parameter. Attacker may be able to override existing parameter values, inject a new parameter or exploit variables out of a direct reach. HTTP Parameter Pollution (HPP) attacks consist of injecting encoded query string delimiters into other existing parameters. If a web application does not properly sanitize the user input, a malicious user may compromise the logic of the application to perform either client-side or server-side attacks.

OWASP:
Improper limitation of a pathname to a restricted directory ('Path Traversal') scala_inject_rule-SpotbugsPathTraversalAbsolute, CWE-22 Severity: Info

"The software uses an HTTP request parameter to construct a pathname that should be within a restricted directory, but it does not properly neutralize absolute path sequences such as
"/abs/path" that can resolve to a location that is outside of that directory. See http://cwe.mitre.org/data/definitions/36.html for more information."

OWASP:
  • A01:2021-Broken Access Control
  • A5:2017-Broken Access Control
Improper limitation of a pathname to a restricted directory ('Path Traversal') scala_inject_rule-SpotbugsPathTraversalRelative, CWE-22 Severity: Info

"The software uses an HTTP request parameter to construct a pathname that should be within a restricted directory, but it does not properly neutralize sequences such as ".." that can resolve to a location that is outside of that directory. See http://cwe.mitre.org/data/definitions/23.html for more information."

OWASP:
  • A01:2021-Broken Access Control
  • A5:2017-Broken Access Control
Improperly implemented security check for standard scala_ldap_rule-AnonymousLDAP, CWE-358 Severity: Info

Without proper access control, executing an LDAP statement that contains a user-controlled value can allow an attacker to abuse poorly configured LDAP context

OWASP:
Insecure inherited permissions scala_perm_rule-DangerousPermissions, CWE-277 Severity: Info

Do not grant dangerous combinations of permissions.

OWASP:
Improper Control of Generation of Code ('Code Injection') scala_script_rule-ScriptInjection, CWE-94 Severity: Info

The software constructs all or part of a code segment using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the syntax or behavior of the intended code segment.

OWASP:
  • A03:2021-Injection
  • A1:2017-Injection
Use of Externally-Controlled Format String scala_strings_rule-FormatStringManipulation, CWE-134 Severity: Info

Allowing user input to control format parameters could enable an attacker to cause exceptions to be thrown or leak information.Attackers may be able to modify the format string argument, such that an exception is thrown. If this exception is left uncaught, it may crash the application. Alternatively, if sensitive information is used within the unused arguments, attackers may change the format string to reveal this information.

OWASP:
Collapse of data into unsafe value scala_strings_rule-ModifyAfterValidation, CWE-182 Severity: Info

CERT: IDS11-J. Perform any string modifications before validation

OWASP:
Collapse of data into unsafe value scala_strings_rule-NormalizeAfterValidation, CWE-182 Severity: Info

IDS01-J. Normalize strings before validating them

OWASP:
Improper Control of Generation of Code ('Code Injection') scala_templateinjection_rule-TemplateInjection, CWE-94 Severity: Info

A malicious user in control of a template can run malicious code on the server-side. Velocity templates should be seen as scripts.

OWASP:
Exposure of sensitive system information to an unauthorized control sphere scala_unsafe_rule-SensitiveDataExposure, CWE-497 Severity: Info

Applications can unintentionally leak information about their configuration, internal workings, or violate privacy through a variety of application problems. Pages that provide different responses based on the validity of the data can lead to Information Leakage;
specifically when data deemed confidential is being revealed as a result of the web application's design.

OWASP:
Deserialization of Untrusted Data scala_xml_rule-ApacheXmlRpc, CWE-502 Severity: Info

Enabling extensions in Apache XML RPC server or client can lead to deserialization vulnerability which would allow an attacker to execute arbitrary code.

OWASP:
Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting') scala_xss_rule-MVCApi, CWE-79 Severity: Info

Disabling HTML escaping put the application at risk for Cross-Site Scripting (XSS).

OWASP:
Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting') scala_xss_rule-XSSServlet, CWE-79 Severity: Info

A potential XSS was found. It could be used to execute unwanted JavaScript in a client's browser.

OWASP:
Improper Restriction of XML External Entity Reference ('XXE') scala_xxe_rule-SaxParserXXE, CWE-611 Severity: Info

XML External Entity (XXE) attacks can occur when an XML parser supports XML entities while processing XML received from an untrusted source.

OWASP:

swift

Name Identifiers Description
Authentication bypass by primary weakness rules_lgpl_swift_other_rule-ios-biometric-acl, CWE-305 Severity: Critical

Weak biometric ACL flag is associated with a key stored in Keychain.
With '.biometryAny/.userPresence/.touchIDAny' flag, an attacker with
the ability to add a biometry to the device can authenticate as the
user. It is recommended to use more specific and secure authentication
mechanisms like '.biometryCurrentSet' and '.touchIDCurrentSet'.

Here's an example of how to fix the problem by using .biometryCurrentSet
for biometric authentication in Swift:

import LocalAuthentication

// Create an instance of LAContext for biometric authentication let context = LAContext()

// Check if biometric authentication is available if context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: nil) {
// Use biometryCurrentSet for biometric authentication
context.evaluatePolicy(.deviceOwnerAuthenticationWithBiometrics,
localizedReason: "Authenticate with biometrics",
reply: { success, error in
if success {
print("Biometric authentication successful.")
// Proceed with authenticated actions
} else {
print("Biometric authentication failed:
(error?.localizedDescription ?? "Unknown error")")
// Handle authentication failure
}
})
} else {
print("Biometric authentication not available.")
// Fallback to alternative authentication method
}

OWASP:
  • A07:2021-Identification and Authentication Failures
  • A2:2017-Broken Authentication
Cleartext storage of sensitive information rules_lgpl_swift_other_rule-ios-file-no-special, CWE-312 Severity: Critical

The file has no special protections associated with it. Using .noFileProtection or FileProtectionType.none for
file protection means that the file is not encrypted on disk,
leaving it vulnerable to unauthorized access if the device is
compromised or if the file is accessed outside of the app's
sandbox. To enhance security, it's crucial to use appropriate
file protection attributes based on the sensitivity of the data
being stored. For sensitive data, you should use file protection
options that encrypt the data on disk, such as
FileProtectionType.complete or
FileProtectionType.completeUnlessOpen.

Here's an example of how to fix the problem:

import Foundation  
// Define the file URL let fileURL = URL(fileURLWithPath: "path/to/file")
// Define data to be written to the file let data = "Sensitive data".data(using: .utf8)!
// Write data to the file with complete file protection do {
try data.write(to: fileURL, options: .completeFileProtection)
print("Data written to file with complete file protection.")
} catch {
print("Error writing data to file: (error)")
}
OWASP:
  • A02:2021-Cryptographic Failures
  • A3:2017-Sensitive Data Exposure
Selection of less-secure algorithm during negotiation ('algorithm downgrade') rules_lgpl_swift_other_rule-ios-tls3-not-used, CWE-757 Severity: Critical

The app uses TLS 1.0, TLS 1.1 or TLS 1.2. TLS 1.3 should be used instead. TLS versions 1.1 and 1.0 were deprecated by the IETF in June 2018 due to
a number of attacks against the vulnerable versions. Use of a deprecated
TLS version may result in the unauthorized retrieval of sensitive
information. It is strongly recommended that all TLS connections use TLS 1.3

TLS 1.3 includes several security improvements over previous versions, such as stronger cryptographic algorithms and negotiation mechanisms, reducing
the risk of security vulnerabilities and attacks like BEAST and POODLE.

Example using TLS 1.3:

import Foundation
// Create a URLSession configuration with TLS 1.3 support let configuration = URLSessionConfiguration.default configuration.tlsMinimumSupportedProtocol = .TLSv13
// Create a URLSession with the custom configuration let session = URLSession(configuration: configuration)
// Define the URL to connect to let url = URL(string: "https://example.com")!
// Create a data task to fetch data from the URL let task = session.dataTask(with: url) { data, response, error in
// Handle response
if let error = error {
print("Error: (error)")
return
}
if let httpResponse = response as? HTTPURLResponse {
print("Status code: (httpResponse.statusCode)")
}
if let data = data {
// Process received data
print("Received data: (data)")
}
}
// Start the data task task.resume()
OWASP:
  • A05:2021-Security Misconfiguration
  • A6:2017-Security Misconfiguration
Selection of less-secure algorithm during negotiation ('algorithm downgrade') rules_lgpl_swift_other_rule-ios-dtls1-used, CWE-757 Severity: Medium

DTLS 1.2 should be used. Detected old version - DTLS 1.0. DTLS (Datagram Transport Layer Security) 1.0 suffers from
various security vulnerabilities and weaknesses, as it is
an outdated and less secure protocol compared to newer
versions such as DTLS 1.2 or 1.3.

Here's an example of how to use DTLS 1.2:

import Network

// Create a NWConnection instance with DTLS 1.2
let connection = NWConnection(host: NWEndpoint.Host("example.com"), port: NWEndpoint.Port("443"), using: .dtls)

// Start the connection connection.start(queue: .main)

// Handle connection state changes connection.stateUpdateHandler = { newState in
switch newState {
case .ready:
print("Connection ready.")
// Perform data transfer or other operations
case .failed(let error):
print("Connection failed with error: (error)")
default:
break
}
}
OWASP:
  • A05:2021-Security Misconfiguration
  • A6:2017-Security Misconfiguration
Authentication bypass by primary weakness rules_lgpl_swift_other_rule-ios-keychain-weak-accessibility-value, CWE-305 Severity: Medium

A key stored in the Keychain is using a weak accessibility value.

kSecAttrAccessibleAlways allows access to the keychain item at all
times, even when the device is locked. Storing sensitive data with
this accessibility option means that the data is accessible to anyone
who gains physical access to the device, regardless of whether it's
locked or not. This increases the risk of unauthorized access to
sensitive information. kSecAttrAccessibleAfterFirstUnlock allows access to the keychain item only after the device has been unlocked once after a reboot. While this provides some level of protection, the data becomes accessible as soon as the device is unlocked for the first time after a reboot. If sensitive data is stored with this accessibility option, it
could still be accessed by an attacker who gains physical access to the device before it's unlocked for the first time after a reboot.

To mitigate these security risks, it's important to use the appropriate
accessibility option based on the sensitivity of the data being stored.
For sensitive data that should only be accessible when the device is
unlocked, the kSecAttrAccessibleWhenUnlocked or
kSecAttrAccessibleWhenUnlockedThisDeviceOnly
options should be used.

Here's an example code that fixes the problem by using the
kSecAttrAccessibleWhenUnlocked option:

import Foundation import Security

// Define the data to be stored in the keychain let secretData = "superSecretData".data(using: .utf8)!

// Create query dictionary to specify the keychain item let query: [String: Any] = [
kSecClass as String: kSecClassGenericPassword,
kSecAttrService as String: "com.example.myApp",
kSecAttrAccount as String: "userPassword",
kSecValueData as String: secretData,
kSecAttrAccessible as String: kSecAttrAccessibleWhenUnlocked
]

// Add the keychain item let status = SecItemAdd(query as CFDictionary, nil)
if status == errSecSuccess {
print("Secret data successfully stored in keychain.")
} else {
print("Error storing secret data in keychain: (status)")
}
OWASP:
  • A07:2021-Identification and Authentication Failures
  • A2:2017-Broken Authentication