#java
Rulesets (30)
Scan code for potential security issues that require additional review. Recommended for teams looking to set up guardrails or to flag troublesome spots for further review.
Use Semgrep as a universal linter to identify vulnerabilities and code smells in your code base with the FindSecBugs (https://find-sec-bugs.github.io/) rule pack.
Scan code for potential security issues that require additional review. Recommended for teams looking to set up guardrails or to flag troublesome spots for further review.
A collection of opinionated rules for best practices in popular languages. Recommended for users who want really strict coding standards.
Default ruleset for Java, curated by Semgrep.

Secure defaults for XSS prevention

r2c Java security rules, combined
Find common bugs, errors, and logic issues in popular languages.

Ensure your code communicates over encrypted channels instead of plaintext.

Secure XSS defaults for HttpServlets+JSP.

Rule pack for detecting insecure transport in java spring.
Rules for detecting secrets checked into version control

Rule pack for detecting insecure transport in java stdlib.
Use recommended rulesets specific to your project. Auto config is not a ruleset but a mode that scans for languages and frameworks and then uses the Semgrep Registry to select recommended rules. Semgrep will send a list of languages, frameworks, and your project URL to the Registry when using auto mode (but code is never uploaded).
Another test ruleset

Omni pack for insecure transport rules

Rule pack for detecting insecure transport in java spring.
Leverage all Gitlab provided rules with the gitlab rulepack.

Ensure your code communicates over encrypted channels instead of plaintext.

Secure defaults for Command injection prevention

Scan for runtime errors, logic bus, and high-confidence security vulnerabilities. Recommended for use in CI to block serious issues from reaching production. Supports Python, Java, JavaScript, and Go.

Scan for runtime errors, logic bus, and high-confidence security vulnerabilities. Recommended for use in CI to block serious issues from reaching production.

SQL injection guardrails. Checks for non-constant SQL queries and other SQLi.

Written by the MobSF team. See https://github.com/MobSF/mobsfscan for more.

OWASP Java Benchmark ruleset, a subset of java rules for faster results.
Rulset for reverse shells, by Kurt Boberg
Rule pack for detecting insecure transport in java spring.
Rules (371)

Strings should not be compared with '=='. This is a reference comparison operator. Use '.equals()' instead.

External entities are allowed for $DBFACTORY. This is vulnerable to XML external entity attacks. Disable this by setting the feature "http://xml.org/sax/features/external-general-entities" to false.

External entities are allowed for $DBFACTORY. This is vulnerable to XML external entity attacks. Disable this by setting the feature "http://xml.org/sax/features/external-parameter-entities" to false.

DOCTYPE declarations are enabled for this SAXParserFactory. This is vulnerable to XML external entity attacks. Disable this by setting the feature `http://apache.org/xml/features/disallow-doctype-decl` to true. Alternatively, allow DOCTYPE declarations and only prohibit external entities declarations. This can be done by setting the features `http://xml.org/sax/features/external-general-entities` and `http://xml.org/sax/features/external-parameter-entities` to false. NOTE - The previous links are not meant to be clicked. They are the literal config key values that are supposed to be used to disable these features. For more information, see https://semgrep.dev/docs/cheat-sheets/java-xxe/#3a-documentbuilderfactory.

A parameter being passed directly into java.net.URL function most likely lead to SSRF.

This if statement will always have the same behavior and is therefore unnecessary.

Older Java application servers are vulnerable to HTTP response splitting, which may occur if an HTTP request can be injected with CRLF characters. This finding is reported for completeness; it is recommended to ensure your environment is not affected by testing this yourself.

This rule is deprecated.

This App uses RSA Crypto without OAEP padding. The purpose of the padding scheme is to prevent a number of attacks on RSA that only work when the encryption is performed without padding.

Detected a method annotated with 'RequestMapping' that does not specify the HTTP method. CSRF protections are not enabled for GET, HEAD, TRACE, or OPTIONS, and by default all HTTP methods are allowed when the HTTP method is not explicitly specified. This means that a method that performs state changes could be vulnerable to CSRF attacks. To mitigate, add the 'method' field and specify the HTTP method (such as 'RequestMethod.POST').

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Used SnakeYAML org.yaml.snakeyaml.Yaml() constructor with no arguments, which is vulnerable to deserialization attacks. Use the one-argument Yaml(...) constructor instead, with SafeConstructor or a custom Constructor as the argument.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insecure HostnameVerifier implementation detected. This will accept any SSL certificate with any hostname, which creates the possibility for man-in-the-middle attacks.
Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Hidden elements in view can be used to hide data from user. But this data can be leaked.

The App logs information. Please ensure that sensitive information is never logged.

The file is World Readable. Any App can read from the file.

The file is World Readable and Writable. Any App can read/write to the file.

This app does not uses SafetyNet Attestation API that provides cryptographically-signed attestation, assessing the device's integrity. This check helps to ensure that the servers are interacting with the genuine app running on a genuine Android device.

This app does not have capabilities to prevent against Screenshots from Recent Task History/ Now On Tap etc.

This app does not have root detection capabilities. Running a sensitive application on a rooted device questions the device integrity and affects users data.

This app does not have capabilities to prevent tapjacking attacks. An attacker can hijack the user's taps and tricks him into performing some critical operations that he did not intend to.

This app does not enforce TLS Certificate Transparency that helps to detect SSL certificates that have been mistakenly issued by a certificate authority or maliciously acquired from an otherwise unimpeachable certificate authority.

This app does not use a TLS/SSL certificate or public key pinning in code to detect or prevent MITM attacks in secure communication channel. Please verify if pinning is enabled in `network_security_config.xml`.

The App uses ECB mode in Cryptographic encryption algorithm. ECB mode is known to be weak as it results in the same ciphertext for identical blocks of plaintext.

Calling Cipher.getInstance("AES") will return AES ECB mode by default. ECB mode is known to be weak as it results in the same ciphertext for identical blocks of plaintext.

Hardcoded encryption key makes AES symmetric encryption useless. An attacker can easily reverse engineer the application and recover the keys.

The App uses the encryption mode CBC with PKCS5/PKCS7 padding. This configuration is vulnerable to padding oracle attacks.

The IV for AES CBC mode should be random. A static IV makes the ciphertext vulnerable to Chosen Plaintext Attack.

The App uses an insecure Random Number Generator.

SSLv3 is insecure and has multiple known vulnerabilities.

SHA1 Hash algorithm used. The SHA1 hash is known to have hash collisions.

Weak encryption algorithm identified. This algorithm is vulnerable to cryptographic attacks.

Weak Hash algorithm used. The hash algorithm is known to have hash collisions.

The App may use weak IVs like "0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00" or "0x01,0x02,0x03,0x04,0x05,0x06,0x07". Not using a random IV makes the resulting ciphertext much more predictable and susceptible to a dictionary attack.

Cryptographic implementations with insufficient key length is susceptible to bruteforce attacks.

Found object deserialization using ObjectInputStream. Deserializing entire Java objects is dangerous because malicious actors can create Java object streams with unintended consequences. Ensure that the objects being deserialized are not user-controlled. Consider using HMACs to sign the data stream to make sure it is not tampered with, or consider only transmitting object fields and populating a new object.

User controlled strings in exec() will result in command execution.

The app uses jackson deserialization library. Deserialization of untrusted input can result in arbitrary code execution. Consider using HMACs to sign the data stream to make sure it is not tampered with, or consider only transmitting object fields and populating a new object.

A formatted or concatenated string was detected as input to a java.lang.Runtime call. This is dangerous if a variable is controlled by user input and could result in a command injection. Ensure your variables are not controlled by users or sufficiently sanitized.

App uses SQLite Database and execute raw SQL query. Untrusted user input in raw SQL queries can cause SQL Injection. Also sensitive information should be encrypted and written to the database.

Insecure Implementation of SSL. Trusting all the certificates or accepting self signed certificates is a critical Security Hole. This application is vulnerable to MITM attacks.

DefaultHTTPClient() with default constructor is not compatible with TLS 1.2.

Remote WebView debugging is enabled. This allows an attacker with debugging access to interact with the webview and steal or corrupt data.

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

WebView File System Access is enabled. An attacker able to inject script into a WebView, could exploit the opportunity to access local resources.

Insecure WebView Implementation. WebView ignores SSL Certificate errors and accept any SSL Certificate. This application is vulnerable to MITM attacks.

Ensure that javascript interface is implemented securely. Execution of user controlled code in WebView is a critical Security issue.

XMLDecoder should not be used to parse untrusted data. Deserializing user input can lead to arbitrary code execution. Use an alternative and explicitly disable external entities.

XML external entities are enabled for this XMLInputFactory. This is vulnerable to XML external entity attacks. Disable external entities by setting "javax.xml.stream.isSupportingExternalEntities" to false.

XML external entities are not explicitly disabled for this XMLInputFactory. This could be vulnerable to XML external entity vulnerabilities. Explicitly disable external entities by setting "javax.xml.stream.isSupportingExternalEntities" to false.

When using Jackson to marshall/unmarshall JSON to Java objects, enabling default typing is dangerous and can lead to RCE. If an attacker can control `$JSON` it might be possible to provide a malicious JSON which can be used to exploit unsecure deserialization. In order to prevent this issue, avoid to enable default typing (globally or by using "Per-class" annotations) and avoid using `Object` and other dangerous types for member variable declaration which creating classes for Jackson based deserialization.
Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Use of AES with ECB mode detected. ECB doesn't provide message confidentiality and is not semantically secure so should not be used. Instead, use a strong, secure cipher: Cipher.getInstance("AES/CBC/PKCS7PADDING"). See https://owasp.org/www-community/Using_the_Java_Cryptographic_Extensions for more information.

Use of Blowfish was detected. Blowfish uses a 64-bit block size that makes it vulnerable to birthday attacks, and is therefore considered non-compliant. Instead, use a strong, secure cipher: Cipher.getInstance("AES/CBC/PKCS7PADDING"). See https://owasp.org/www-community/Using_the_Java_Cryptographic_Extensions for more information.

Use of AES with no settings detected. By default, java.crypto.Cipher uses ECB mode. ECB doesn't provide message confidentiality and is not semantically secure so should not be used. Instead, use a strong, secure cipher: java.crypto.Cipher.getInstance("AES/CBC/PKCS7PADDING"). See https://owasp.org/www-community/Using_the_Java_Cryptographic_Extensions for more information.

Detected MD5 hash algorithm which is considered insecure. MD5 is not collision resistant and is therefore not suitable as a cryptographic signature. Use HMAC instead.

Use of RC2 was detected. RC2 is vulnerable to related-key attacks, and is therefore considered non-compliant. Instead, use a strong, secure cipher: Cipher.getInstance("AES/CBC/PKCS7PADDING"). See https://owasp.org/www-community/Using_the_Java_Cryptographic_Extensions for more information.

Use of RC4 was detected. RC4 is vulnerable to several attacks, including stream cipher attacks and bit flipping attacks. Instead, use a strong, secure cipher: Cipher.getInstance("AES/CBC/PKCS7PADDING"). See https://owasp.org/www-community/Using_the_Java_Cryptographic_Extensions for more information.

Detected use of the functions `Math.random()` or `java.util.Random()`. These are both not cryptographically strong random number generators (RNGs). If you are using these RNGs to create passwords or secret tokens, use `java.security.SecureRandom` instead.

RSA keys should be at least 2048 bits based on NIST recommendation.

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.

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.

Insecure SMTP connection detected. This connection will trust any SSL certificate. Enable certificate verification by setting 'email.setSSLCheckServerIdentity(true)'.

Possible JDBC injection detected. Use the parameterized query feature available in queryForObject instead of concatenating or formatting strings: 'jdbc.queryForObject("select * from table where name = ?", Integer.class, parameterName);'

An object-returning LDAP search will allow attackers to control the LDAP response. This could lead to Remote Code Execution.

Detected non-constant data passed into an LDAP query. If this data can be controlled by an external user, this is an LDAP injection. Ensure data passed to an LDAP query is not controllable; or properly sanitize the data.

It looks like MD5 is used as a password hash. MD5 is not considered a secure password hash because it can be cracked by an attacker in a short amount of time. Use a suitable password hashing function such as PBKDF2 or bcrypt. You can use `javax.crypto.SecretKeyFactory` with `SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1")` or, if using Spring, `org.springframework.security.crypto.bcrypt`.

Found object deserialization using ObjectInputStream. Deserializing entire Java objects is dangerous because malicious actors can create Java object streams with unintended consequences. Ensure that the objects being deserialized are not user-controlled. If this must be done, consider using HMACs to sign the data stream to make sure it is not tampered with, or consider only transmitting object fields and populating a new object.

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.

Detected file permissions that are overly permissive (read, write, and execute). It is generally a bad practices to set overly permissive file permission such as read+write+exec for all users. If the file affected is a configuration, a binary, a script or sensitive data, it can lead to privilege escalation or information leakage. Instead, follow the principle of least privilege and give users only the permissions they need.

https://find-sec-bugs.github.io/bugs.htm#PERMISSIVE_CORS 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.

Detected a formatted string in a SQL statement. This could lead to SQL injection if variables in the SQL statement are not properly sanitized. Use a prepared statements (java.sql.PreparedStatement) instead. You can obtain a PreparedStatement using 'connection.prepareStatement'.

Detected a formatted string in a SQL statement. This could lead to SQL injection if variables in the SQL statement are not properly sanitized. Use a prepared statements (java.sql.PreparedStatement) instead. You can obtain a PreparedStatement using 'connection.prepareStatement'.

Detected a formatted string in a SQL statement. This could lead to SQL injection if variables in the SQL statement are not properly sanitized. Use a prepared statements (java.sql.PreparedStatement) instead. You can obtain a PreparedStatement using 'connection.prepareStatement'.

Detected a formatted string in a SQL statement. This could lead to SQL injection if variables in the SQL statement are not properly sanitized. Use a prepared statements (java.sql.PreparedStatement) instead. You can obtain a PreparedStatement using 'connection.prepareStatement'.

Detected input from a HTTPServletRequest going into an LDAP query. This could lead to LDAP injection if the input is not properly sanitized, which could result in attackers modifying objects in the LDAP tree structure. Ensure data passed to an LDAP query is not controllable or properly sanitize the data.

Detected input from a HTTPServletRequest going into a XPath evaluate or compile command. This could lead to xpath injection if variables passed into the evaluate or compile commands are not properly sanitized. Xpath injection could lead to unauthorized access to sensitive information in XML documents. Instead, thoroughly sanitize user input or use parameterized xpath queries if you can.

If an attacker can supply values that the application then uses to determine which class to instantiate or which method to invoke, the potential exists for the attacker to create control flow paths through the application that were not intended by the application developers. This attack vector may allow the attacker to bypass authentication or access control checks or otherwise cause the application to behave in an unexpected manner.

Application redirects to a destination URL specified by a user-supplied parameter that is not validated. This could direct users to malicious locations. Consider using an allowlist to validate URLs.

URL rewriting has significant security risks. Since session ID appears in the URL, it may be easily seen by third parties.

An insecure SSL context was detected. TLS versions 1.0, 1.1, and all SSL versions are considered weak encryption and are deprecated. Use SSLContext.getInstance("TLSv1.2") for the best security.

XMLDecoder should not be used to parse untrusted data. Deserializing user input can lead to arbitrary code execution. Use an alternative and explicitly disable external entities. See https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html for alternatives and vulnerability prevention.

It looks like you're using an implementation of XSSRequestWrapper from dzone. (https://www.javacodegeeks.com/2012/07/anti-cross-site-scripting-xss-filter.html) The XSS filtering in this code is not secure and can be bypassed by malicious actors. It is recommended to use a stack that automatically escapes in your view or templates instead of filtering yourself.

DOCTYPE declarations are enabled for $DBFACTORY. Without prohibiting external entity declarations, this is vulnerable to XML external entity attacks. Disable this by setting the feature "http://apache.org/xml/features/disallow-doctype-decl" to true. Alternatively, allow DOCTYPE declarations and only prohibit external entities declarations. This can be done by setting the features "http://xml.org/sax/features/external-general-entities" and "http://xml.org/sax/features/external-parameter-entities" to false.

DOCTYPE declarations are enabled for this TransformerFactory. This is vulnerable to XML external entity attacks. Disable this by setting the attributes "accessExternalDTD" and "accessExternalStylesheet" to "".

XML external entities are not explicitly disabled for this XMLInputFactory. This could be vulnerable to XML external entity vulnerabilities. Explicitly disable external entities by setting "javax.xml.stream.isSupportingExternalEntities" to false.

Detected non-constant data passed into a NoSQL query using the 'where' evaluation operator. If this data can be controlled by an external user, this is a NoSQL injection. Ensure data passed to the NoSQL query is not user controllable, or properly sanitize the data. Ideally, avoid using the 'where' operator at all and instead use the helper methods provided by com.mongodb.client.model.Filters with comparative operators such as eq, ne, lt, gt, etc.

Checks for requests sent via HttpClient to http:// URLS. This is dangerous because the server is attempting to connect to a website that does not encrypt traffic with TLS. Instead, send requests only to https:// URLS.

Detected an HTTP request sent via HttpGet. This could lead to sensitive information being sent over an insecure channel. Instead, it is recommended to send requests over HTTPS.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

This code contains bidirectional (bidi) characters. While this is useful for support of right-to-left languages such as Arabic or Hebrew, it can also be used to trick language parsers into executing code in a manner that is different from how it is displayed in code editing and review tools. If this is not what you were expecting, please review this code in an editor that can reveal hidden Unicode characters.

Detected user input flowing into a manually constructed HTML string. You may be accidentally bypassing secure methods of rendering HTML by manually constructing HTML and this could create a cross-site scripting vulnerability, which could let attackers steal sensitive user data. To be sure this is safe, check that the HTML is rendered safely. You can use the OWASP ESAPI encoder if you must render user data.

Detected user input entering a method which executes a system command. This could result in a command injection vulnerability, which allows an attacker to inject an arbitrary system command onto the server. The attacker could download malware onto or steal data from the server. Instead, use ProcessBuilder, separating the command into individual arguments, like this: `new ProcessBuilder("ls", "-al", targetDirectory)`. Further, make sure you hardcode or allowlist the actual command so that attackers can't run arbitrary commands.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Detected a formatted string in a SQL statement. This could lead to SQL injection if variables in the SQL statement are not properly sanitized. Use a prepared statements (java.sql.PreparedStatement) instead. You can obtain a PreparedStatement using 'connection.prepareStatement'.

Digester being instantiated without calling the setFeature functions that are generally used for disabling entity processing

SAXBuilder being instantiated without calling the setFeature functions that are generally used for disabling entity processing

SAXParserFactory being instantiated without calling the setFeature functions that are generally used for disabling entity processing

SAXReader being instantiated without calling the setFeature functions that are generally used for disabling entity processing

XMLInputFactory being instantiated without calling the setProperty functions that are generally used for disabling entity processing

XMLReader being instantiated without calling the setFeature functions that are generally used for disabling entity processing

DocumentBuilderFactory being instantiated without calling the setFeature functions that are generally used for disabling entity processing, which can allow for XXE vulnerabilities

A parameter being passed directly into HttpClient functions most likely lead to SSRF.

Non-exhaustive list of Libraries that provide functionality to accept URL as a parameter

Checks for redefinitions of functions that check TLS/SSL certificate verification. This can lead to vulnerabilities, as simple errors in the code can result in lack of proper certificate validation. This should only be used for debugging purposes because it leads to vulnerability to MTM attacks.

Detects direct creations of SSLConnectionSocketFactories that don't disallow SSL v2, SSL v3, and TLS v1. SSLSocketFactory can be used to validate the identity of the HTTPS server against a list of trusted certificates. These protocols are deprecated due to POODLE, man in the middle attacks, and other vulnerabilities.

Detects setting client protocols to insecure versions of TLS and SSL. These protocols are deprecated due to POODLE, man in the middle attacks, and other vulnerabilities.

Checks for cases where java applications are allowing unsafe renegotiation. This leaves the application vulnerable to a man-in-the-middle attack where chosen plain text is injected as prefix to a TLS connection.

Checks for requests sent via Unirest to http:// URLS. This is dangerous because the server is attempting to connect to a website that does not encrypt traffic with TLS. Instead, send requests only to https:// URLS.

A hardcoded password in plain text is identified.

A hardcoded username in plain text is identified.

A hardcoded Key is identified.

A hardcoded secret is identified.

Detected SQL statement that is tainted by `$EVENT` object. This could lead to SQL injection if variables in the SQL statement are not properly sanitized. Use parameterized SQL queries or properly sanitize user input instead.

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.

Detected SHA1 hash algorithm which is considered insecure. SHA1 is not collision resistant and is therefore not suitable as a cryptographic signature. Instead, use PBKDF2 for password hashing or SHA256 or SHA512 for other hash function applications.

Marking code as privileged enables a piece of trusted code to temporarily enable access to more resources than are available directly to the code that called it. Be very careful in your use of the privileged construct, and always remember to make the privileged code section as small as possible.

Cross-site scripting detected in HttpServletResponse writer with variable '$VAR'. User input was detected going directly from the HttpServletRequest into output. Ensure your data is properly encoded using org.owasp.encoder.Encode.forHtml: 'Encode.forHtml($VAR)'.

XML external entities are enabled for this XMLInputFactory. This is vulnerable to XML external entity attacks. Disable external entities by setting "javax.xml.stream.isSupportingExternalEntities" to false.
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](https://tomcat.apache.org/) will disallow `\r\n` 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](https://commons.apache.org/proper/commons-text/) to escape the input: ``` public String escapeValue(String value) { return StringEscapeUtils.escapeJava(value); } ``` For more information on response splitting attacks see OWASP: https://owasp.org/www-community/attacks/HTTP_Response_Splitting
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](https://tomcat.apache.org/) 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](https://commons.apache.org/proper/commons-text/) to escape the input: ``` public String escapeValue(String value) { return StringEscapeUtils.escapeJava(value); } ``` For more information on response splitting attacks see OWASP: https://owasp.org/www-community/attacks/HTTP_Response_Splitting
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](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) 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: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin
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](https://en.wikipedia.org/wiki/Birthday_attack). 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: https://docs.oracle.com/en/java/javase/15/security/java-cryptography-architecture-jca-reference-guide.html
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: https://docs.oracle.com/en/java/javase/15/security/java-cryptography-architecture-jca-reference-guide.html
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: https://docs.oracle.com/en/java/javase/15/security/java-cryptography-architecture-jca-reference-guide.html
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: https://docs.oracle.com/en/java/javase/15/security/java-cryptography-architecture-jca-reference-guide.html
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: https://docs.oracle.com/en/java/javase/15/security/java-cryptography-architecture-jca-reference-guide.html
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: https://en.wikipedia.org/wiki/Padding_oracle_attack For more information on Java Cryptography see: https://docs.oracle.com/en/java/javase/15/security/java-cryptography-architecture-jca-reference-guide.html
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)); ```
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: https://docs.hazelcast.com/imdg/4.2/security/tls-ssl
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: http://ed25519.cr.yp.to/ For more information on Java Cryptography see: https://docs.oracle.com/en/java/javase/15/security/java-cryptography-architecture-jca-reference-guide.html
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: https://docs.oracle.com/en/java/javase/15/security/java-cryptography-architecture-jca-reference-guide.html
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](https://en.wikipedia.org/wiki/Chosen-plaintext_attack). 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: https://en.wikipedia.org/wiki/Optimal_asymmetric_encryption_padding For more information on Java Cryptography see: https://docs.oracle.com/en/java/javase/15/security/java-cryptography-architecture-jca-reference-guide.html
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: https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html
The `org.apache.http.impl.client.DefaultHttpClient` and `javax.net.ssl.SSLContext.getInstance` object instances do 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); ```
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: - https://docs.oracle.com/en/java/javase/11/docs/api/java.base/javax/net/ssl/SSLContext.html For more information on MiTM attacks see: - https://owasp.org/www-community/attacks/Manipulator-in-the-middle_attack
The application fails to protect against Cross-Site Request Forgery (CSRF) due to disabling Spring's CSRF protection features. 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. To remediate this issue, remove the call to `HttpSecurity.csrf().disable()` or remove the custom `CsrfConfigurer`. For more information on CSRF protection in Spring see: https://docs.spring.io/spring-security/reference/servlet/exploits/csrf.html#servlet-csrf 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](https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis-08#section-8.8.2) section of the SameSite RFC. For more information on CSRF see OWASP's guide: https://owasp.org/www-community/attacks/csrf
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: - For Google Cloud Platform consider [Cloud Key Management](https://cloud.google.com/kms/docs) - For Amazon Web Services consider [AWS Key Management](https://aws.amazon.com/kms/) - For on premise or other alternatives to cloud providers, consider [Hashicorp's Vault](https://www.vaultproject.io/) - For other cloud providers, please see their documentation
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.
Either the `HostnameVerifier` has been set to always return `true` or the `X509TrustManager` has been configured to return null, or both. This effectively disables the validation of server or client 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. It is recommended to not override the default `HostnameVerifiers`. 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. 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 see OWASP: https://cheatsheetseries.owasp.org/cheatsheets/Transport_Layer_Protection_Cheat_Sheet.html
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.
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.
The application was found to take data from user input and output it into a logger method. When data from an untrusted source is sent to a logger without validation, an attacker could forge log entries or include malicious content. 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). To mitigate this issue, encode values that come from user input with a package such as [Apache Commons Text](https://commons.apache.org/proper/commons-text/) to escape the input: ``` public String escapeValue(String value) { return StringEscapeUtils.escapeJava(value); } ``` For more information on log injection see OWASP: https://owasp.org/www-community/attacks/Log_Injection
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: https://cheatsheetseries.owasp.org/cheatsheets/OS_Command_Injection_Defense_Cheat_Sheet.html
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: ``` // Some userInput String userInput = "someUserInput"; // Your connection string String url = "..."; // Get a connection from the DB via the DriverManager Connection conn = DriverManager.getConnection(url); // Create a prepared statement PreparedStatement st = conn.prepareStatement("SELECT name FROM table where name=?"); // Set each parameters value by the index (starting from 1) st.setString(1, userInput); // Execute query and get the result set ResultSet rs = st.executeQuery(); // Iterate over results while (rs.next()) { // Get result for this row at the provided column number (starting from 1) String result = rs.getString(1); // ... } // Close the ResultSet rs.close(); // Close the PreparedStatement st.close(); ``` For more information on SQL Injection see OWASP: https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html
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.
The `org.springframework.web.servlet.ModelAndView` class and `HttpRequest.getRequestDispatcher()`'s `include` and `forward` methods may potentially allow access to restricted files if called with user-supplied input. For Spring MVC, 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. 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 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, userInput); // return the new model and view return new ModelAndView(viewValue); } ``` 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); ```
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: https://cheatsheetseries.owasp.org/cheatsheets/Server_Side_Request_Forgery_Prevention_Cheat_Sheet.html For more information on HTTP Parameter Pollution see: https://en.wikipedia.org/wiki/HTTP_parameter_pollution
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: https://docs.oracle.com/en/java/javase/20/docs/api/java.naming/javax/naming/directory/InitialDirContext.html#search(javax.naming.Name,java.lang.String,java.lang.Object[],javax.naming.directory.SearchControls) 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: https://cheatsheetseries.owasp.org/cheatsheets/LDAP_Injection_Prevention_Cheat_Sheet.html
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: https://struts.apache.org/security/#do-not-use-incoming-untrusted-user-input-in-forced-expression-evaluation
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: ``` // Some userInput String userInput = "someUserInput"; // Your connection string String url = "..."; // Get a connection from the DB via the DriverManager Connection conn = DriverManager.getConnection(url); // Create a prepared statement PreparedStatement st = conn.prepareStatement("SELECT name FROM table where name=?"); // Set each parameters value by the index (starting from 1) st.setString(1, userInput); // Execute query and get the result set ResultSet rs = st.executeQuery(); // Iterate over results while (rs.next()) { // Get result for this row at the provided column number (starting from 1) String result = rs.getString(1); // ... } // Close the ResultSet rs.close(); // Close the PreparedStatement st.close(); ``` For more information on SQL Injection see OWASP: https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html
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: https://cheatsheetseries.owasp.org/cheatsheets/LDAP_Injection_Prevention_Cheat_Sheet.html
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: - For Google Cloud Platform consider [Cloud Key Management](https://cloud.google.com/kms/docs) - For Amazon Web Services consider [AWS Key Management](https://aws.amazon.com/kms/) - For on premise or other alternatives to cloud providers, consider [Hashicorp's Vault](https://www.vaultproject.io/) - For other cloud providers, please see their documentation
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: - For Google Cloud Platform consider [Cloud Key Management](https://cloud.google.com/kms/docs) - For Amazon Web Services consider [AWS Key Management](https://aws.amazon.com/kms/) - For on premise or other alternatives to cloud providers, consider [Hashicorp's Vault](https://www.vaultproject.io/) - For other cloud providers, please see their documentation
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: https://docs.oracle.com/javase/8/docs/api/java/lang/RuntimePermission.html For more information on `ReflectPermission` see: https://docs.oracle.com/javase/8/docs/api/java/lang/reflect/ReflectPermission.html
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: https://en.wikipedia.org/wiki/File-system_permissions#Symbolic_notation
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 `DRBG` instance of `SecureRandom` be used. Example using `DRBG` with `SecureRandom`: ``` 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() ) ); } ``` For more information on Java Cryptography see: https://docs.oracle.com/en/java/javase/15/security/java-cryptography-architecture-jca-reference-guide.html
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(); } ```
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: https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/expression/spel/support/SimpleEvaluationContext.html
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(); ```
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](https://commons.apache.org/proper/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 ```
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: https://cheatsheetseries.owasp.org/cheatsheets/Server_Side_Request_Forgery_Prevention_Cheat_Sheet.html
The application is using `Integer.toHexString` on a digest array buffer which may lead to an incorrect version of values. Consider using the `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: https://docs.oracle.com/javase/9/docs/api/javax/xml/bind/DatatypeConverter.html#printHexBinary-byte:A-
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). It is recommended that the `SAXParser` is configured to disable DTD doctypes as this protects 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: https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html#java
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](https://docs.oracle.com/javase/9/docs/api/javax/xml/parsers/SAXParserFactory.html) 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: https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html#java
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). In most XML parsers, the recommendation to protect against XXE is to disable the doctype feature. Unfortunately use of the `XMLInputFactory` requires that the doctypes feature be enabled. Instead the application can set the `ACCESS_EXTERNAL_DTD` to an empty string and disable `javax.xml.stream.isSupportingExternalEntities`. Creates an `XMLInputFactory` stream parser, but disables accessing external DTD or entities: ``` // Create an XMLInputFactory XMLInputFactory factory = XMLInputFactory.newFactory(); // Set the ACCESS_EXTERNAL_DTD property to an empty string so it won't access // entities using protocols // (ref: https://docs.oracle.com/javase/8/docs/api/javax/xml/XMLConstants.html#ACCESS_EXTERNAL_DTD) factory.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, ""); // Additionally, disable support for resolving external entities factory.setProperty("javax.xml.stream.isSupportingExternalEntities", false); // Continue to work with the factory/stream parser ``` For more information on XML security see OWASP's guide: https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html#java
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 {{ 7*7 }} 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: - https://nightlies.apache.org/wicket/apidocs/9.x/org/apache/wicket/Component.html For more information on XSS see OWASP: - https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html
The application is returning user-supplied data from an HTTP request to an HTTP response's `sendError` method. 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. Note that Apache Tomcat 9 and above automatically encode the output and are not vulnerable. 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 {{ 7*7 }} 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 `sendError` message parameter. Regardless if the application server handles output encoding, consider encoding any user-supplied input that is used in the sendError method: Example using [Apache Commons Text](https://commons.apache.org/proper/commons-text/) `StringEscapeUtils.escapeHtml4`: ``` // Get user input String userInput = request.getParameter("key"); // Encode the input using the Html4 encoder String encoded = StringEscapeUtils.escapeHtml4(userInput); // Respond with the error code and value response.sendError(401, encoded); ``` For more information on XSS see OWASP: - https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html
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 {{ 7*7 }} 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 Text](https://commons.apache.org/proper/commons-text/) `StringEscapeUtils` 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: - https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.
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 a `Cookie`: ``` // Create an HttpOnly cookie. Cookie someCookie = new Cookie("SomeCookieName", "SomeValue"); // Set HttpOnly flag to true someCookie.setHttpOnly(true); ``` For more information see: https://jakarta.ee/specifications/servlet/4.0/apidocs/javax/servlet/http/cookie#setHttpOnly-boolean- Session cookies should be configured with the following security directives: - [HTTPOnly](https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#restrict_access_to_cookies) - [Secure](https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#restrict_access_to_cookies) - [SameSite](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite)
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: https://jakarta.ee/specifications/servlet/4.0/apidocs/javax/servlet/http/cookie#setSecure-boolean- Session cookies should be configured with the following security directives: - [HTTPOnly](https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#restrict_access_to_cookies) - [SameSite](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite) - [Secure](https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#restrict_access_to_cookies)

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Detected input from a HTTPServletRequest going into a SQL sink or statement. This could lead to SQL injection if variables in the SQL statement are not properly sanitized. Use parameterized SQL queries or properly sanitize user input instead.
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.
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.

`$X == $X` or `$X != $X` is always true. (Unless the value compared is a float or double). To test if `$X` is not-a-number, use `Double.isNaN($X)`.

Detected the decoding of a JWT token without a verify step. JWT tokens must be verified before use, otherwise the token's integrity is unknown. This means a malicious actor could forge a JWT token with any claims. Call '.verify()' before using the token.

Detected use of the 'none' algorithm in a JWT token. The 'none' algorithm assumes the integrity of the token has already been verified. This would allow a malicious actor to forge a JWT token that will automatically be verified. Do not explicitly use the 'none' algorithm. Instead, use an algorithm such as 'HS256'.

When a Restful webservice endpoint is configured to use wildcard mediaType {*/*} as a value for the @Consumes annotation, an attacker could abuse the SerializableProvider by sending a HTTP Request with a Content-Type of application/x-java-serialized-object. The body of that request would be processed by the SerializationProvider and could contain a malicious payload, which may lead to arbitrary code execution when calling the $Y.getObject method.

When a Restful webservice endpoint isn't configured with a @Consumes annotation, an attacker could abuse the SerializableProvider by sending a HTTP Request with a Content-Type of application/x-java-serialized-object. The body of that request would be processed by the SerializationProvider and could contain a malicious payload, which may lead to arbitrary code execution. Instead, add a @Consumes annotation to the function or class.

In $METHOD, $X is used to construct a SQL query via string concatenation.

Detected use of the 'none' algorithm in a JWT token. The 'none' algorithm assumes the integrity of the token has already been verified. This would allow a malicious actor to forge a JWT token that will automatically be verified. Do not explicitly use the 'none' algorithm. Instead, use an algorithm such as 'HS256'.

A hard-coded credential was detected. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module).

Triple DES (3DES or DESede) is considered deprecated. AES is the recommended cipher. Upgrade to use AES.

Cipher in ECB mode is detected. ECB mode produces the same output for the same input each time which allows an attacker to intercept and replay the data. Further, ECB mode does not provide any integrity checking. See https://find-sec-bugs.github.io/bugs.htm#CIPHER_INTEGRITY.

NullCipher was detected. This will not encrypt anything; the cipher text will be the same as the plain text. Use a valid, secure cipher: Cipher.getInstance("AES/CBC/PKCS7PADDING"). See https://owasp.org/www-community/Using_the_Java_Cryptographic_Extensions for more information.

Initialization Vectors (IVs) for block ciphers should be randomly generated each time they are used. Using a static IV means the same plaintext encrypts to the same ciphertext every time, weakening the strength of the encryption.

Using RSA without OAEP mode weakens the encryption.

Cryptographic algorithms are notoriously difficult to get right. By implementing a custom message digest, you risk introducing security issues into your program. Use one of the many sound message digests already available to you: MessageDigest sha256Digest = MessageDigest.getInstance("SHA256");

DefaultHttpClient is deprecated. Further, it does not support connections using TLS1.2, which makes using DefaultHttpClient a security hazard. Use HttpClientBuilder instead.

Detected use of a Java socket that is not encrypted. As a result, the traffic could be read by an attacker intercepting the network traffic. Use an SSLSocket created by 'SSLSocketFactory' or 'SSLServerSocketFactory' instead.

Default session middleware settings: `setSecure` not set to true. This ensures that the cookie is sent only over HTTPS to prevent cross-site scripting attacks.

A Spring 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.

Application redirects a user to a destination URL specified by a user supplied parameter that is not validated.

Detected a string argument from a public method contract in a raw SQL statement. This could lead to SQL injection if variables in the SQL statement are not properly sanitized. Use a prepared statements (java.sql.PreparedStatement) instead. You can obtain a PreparedStatement using 'connection.prepareStatement'.

Checks for outgoing connections to ftp servers via Spring plugin ftpSessionFactory. FTP does not encrypt traffic, possibly leading to PII being sent plaintext over the network.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Detected a potential path traversal. A malicious actor could control the location of this file, to include going backwards in the directory with '../'. To address this, ensure that user-controlled variables in file paths are sanitized. You may also consider using a utility method such as org.apache.commons.io.FilenameUtils.getName(...) to only retrieve the file name from the path.

Using CBC with PKCS5Padding is susceptible to padding oracle attacks. A malicious actor could discern the difference between plaintext with valid or invalid padding. Further, CBC mode does not include any integrity checks. Use 'AES/GCM/NoPadding' instead.

Detected empty trust manager implementations. This is dangerous because it accepts any certificate, enabling man-in-the-middle attacks. Consider using a KeyStore and TrustManagerFactory instead. See https://stackoverflow.com/questions/2642777/trusting-all-certificates-using-httpclient-over-https for more information.

Detected a potential path traversal. A malicious actor could control the location of this file, to include going backwards in the directory with '../'. To address this, ensure that user-controlled variables in file paths are sanitized. You may also consider using a utility method such as org.apache.commons.io.FilenameUtils.getName(...) to only retrieve the file name from the path.

JMS Object messages depend on Java Serialization for marshalling/unmarshalling of the message payload when ObjectMessage.getObject() is called. Deserialization of untrusted data can lead to security flaws; a remote attacker could via a crafted JMS ObjectMessage to execute arbitrary code with the permissions of the application listening/consuming JMS Messages. In this case, the JMS MessageListener consume an ObjectMessage type received inside the onMessage method, which may lead to arbitrary code execution when calling the $Y.getObject method.

Using a non-primitive class with Java RMI may be an insecure deserialization vulnerability. Depending on the underlying implementation. This object could be manipulated by a malicious actor allowing them to execute code on your system. Instead, use an integer ID to look up your object, or consider alternative serialization schemes such as JSON.

Using an arbitrary object ('Object $PARAM') with Java RMI is an insecure deserialization vulnerability. This object can be manipulated by a malicious actor allowing them to execute code on your system. Instead, use an integer ID to look up your object, or consider alternative serialization schemes such as JSON.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Detected input from a HTTPServletRequest going into a 'ProcessBuilder' or 'exec' command. This could lead to command injection if variables passed into the exec commands are not properly sanitized. Instead, avoid using these OS commands with user-supplied input, or, if you must use these commands, use a whitelist of specific values.

Detected input from a HTTPServletRequest going into the environment variables of an 'exec' command. Instead, call the command with user-supplied arguments by using the overloaded method with one String array as the argument. `exec({"command", "arg1", "arg2"})`.

Detected input from a HTTPServletRequest going into a session command, like `setAttribute`. User input into such a command could lead to an attacker inputting malicious code into your session parameters, blurring the line between what's trusted and untrusted, and therefore leading to a trust boundary violation. This could lead to programmers trusting unvalidated data. Instead, thoroughly sanitize user input before passing it into such function calls.

Detected a request with potential user-input going into a OutputStream or Writer object. This bypasses any view or template environments, including HTML escaping, which may expose this application to cross-site scripting (XSS) vulnerabilities. Consider using a view technology such as JavaServer Faces (JSFs) which automatically escapes HTML views.

Detected user input controlling a file path. An attacker could control the location of this file, to include going backwards in the directory with '../'. To address this, ensure that user-controlled variables in file paths are sanitized. You may also consider using a utility method such as org.apache.commons.io.FilenameUtils.getName(...) to only retrieve the file name from the path.

User data flows into this manually-constructed SQL string. User data can be safely inserted into SQL strings using prepared statements or an object-relational mapper (ORM). Manually-constructed SQL strings is a possible indicator of SQL injection, which could let an attacker steal or manipulate data from the database. Instead, use prepared statements (`connection.PreparedStatement`) or a safe library.

User data flows into the host portion of this manually-constructed URL. This could allow an attacker to send data to their own server, potentially exposing sensitive data such as cookies or authorization information sent with this request. They could also probe internal servers or other resources that the server runnig this code can access. (This is called server-side request forgery, or SSRF.) Do not allow arbitrary hosts. Instead, create an allowlist for approved hosts hardcode the correct host, or ensure that the user data can only affect the path or parameters.

Detected user input used to manually construct a SQL string. This is usually bad practice because manual construction could accidentally result in a SQL injection. An attacker could use a SQL injection to steal or modify contents of the database. Instead, use a parameterized query which is available by default in most database engines. Alternatively, consider using an object-relational mapper (ORM) such as Sequelize which will protect your queries.

Detected anonymous LDAP bind. This permits anonymous users to execute LDAP statements. Consider enforcing authentication for LDAP. See https://docs.oracle.com/javase/tutorial/jndi/ldap/auth_mechs.html for more information.

'Integer.toHexString()' strips leading zeroes from each byte if read byte-by-byte. This mistake weakens the hash value computed since it introduces more collisions. Use 'String.format("%02X", ...)' instead.

Using less than 128 bits for Blowfish is considered insecure. Use 128 bits or more, or switch to use AES instead.

A cookie was detected without setting the 'secure' flag. The 'secure' flag for cookies prevents the client from transmitting the cookie over insecure channels such as HTTP. Set the 'secure' flag by calling '$COOKIE.setSecure(true);'

Detected an HTTP request sent via HttpURLConnection. This could lead to sensitive information being sent over an insecure channel. Instead, it is recommended to send requests over HTTPS.

Insecure transport rules to catch socket connections to http, telnet, and ftp servers. This is dangerous because these are protocols that do not encrypt traffic.

Checks for attempts to connect through telnet. This is insecure as the telnet protocol supports no encryption, and data passes through unencrypted.

This rule has been deprecated.
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.

DOCTYPE declarations are enabled for this DocumentBuilderFactory. This is vulnerable to XML external entity attacks. Disable this by setting the feature "http://apache.org/xml/features/disallow-doctype-decl" to true. Alternatively, allow DOCTYPE declarations and only prohibit external entities declarations. This can be done by setting the features "http://xml.org/sax/features/external-general-entities" and "http://xml.org/sax/features/external-parameter-entities" to false.

Detected MD5 hash algorithm which is considered insecure. MD5 is not collision resistant and is therefore not suitable as a cryptographic signature. Use HMAC instead.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.

A parameter being passed directly into CloseableHttpClient functions most likely lead to SSRF.

Non-exhaustive list of Libraries that provide functionality to accept XML as an input

The value of `$X` is being ignored and will be used in the conditional test

A formatted or concatenated string was detected as input to a java.lang.Runtime call. This is dangerous if a variable is controlled by user input and could result in a command injection. Ensure your variables are not controlled by users or sufficiently sanitized.

A cookie was detected without setting the 'HttpOnly' flag. The 'HttpOnly' flag for cookies instructs the browser to forbid client-side scripts from reading the cookie. Set the 'HttpOnly' flag by calling 'cookie.setHttpOnly(true);'

Detected cookie without the SameSite attribute.

Detected potential code injection using ScriptEngine. Ensure user-controlled data cannot enter '.eval()', otherwise, this is a code injection vulnerability.

Detected a formatted string in a SQL statement. This could lead to SQL injection if variables in the SQL statement are not properly sanitized. Use a prepared statements (java.sql.PreparedStatement) instead. You can obtain a PreparedStatement using 'connection.prepareStatement'.

DES is considered deprecated. AES is the recommended cipher. Upgrade to use AES. See https://www.nist.gov/news-events/news/2005/06/nist-withdraws-outdated-data-encryption-standard for more information.

Detected a formatted string in a SQL statement. This could lead to SQL injection if variables in the SQL statement are not properly sanitized. Use a prepared statements (java.sql.PreparedStatement) instead. You can obtain a PreparedStatement using 'connection.prepareStatement'.

CSRF protection is disabled for this configuration. This is a security risk.

Checks for requests sent via Java Spring RestTemplate API to http:// URLS. This is dangerous because the server is attempting to connect to a website that does not encrypt traffic with TLS. Instead, send requests only to https:// URLS.

Checks for redefinitions of the checkServerTrusted function in the X509TrustManager class that disables TLS/SSL certificate verification. This should only be used for debugging purposes because it leads to vulnerability to MTM attacks.

Checks for outgoing connections to ftp servers. FTP does not encrypt traffic, possibly leading to PII being sent plaintext over the network.

Checks for requests sent via Apache HTTP Components to http:// URLS. This is dangerous because the server is attempting to connect to a website that does not encrypt traffic with TLS. Instead, send requests only to https:// URLS.

A formatted or concatenated string was detected as input to a ProcessBuilder call. This is dangerous if a variable is controlled by user input and could result in a command injection. Ensure your variables are not controlled by users or sufficiently sanitized.

Seam Logging API support an expression language to introduce bean property to log messages. The expression language can also be the source to unwanted code execution. In this context, 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.
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: https://owasp.org/www-community/attacks/Path_Traversal
Cryptographic keys should not be kept in the source code. The source code can be widely shared in an enterprise environment, and is certainly shared in open source. To be managed safely, passwords and secret keys should be stored in separate configuration files or keystores.
Cryptographic keys should not be kept in the source code. The source code can be widely shared in an enterprise environment, and is certainly shared in open source. To be managed safely, passwords and secret keys should be stored in separate configuration files or keystores.
Cryptographic keys should not be kept in the source code. The source code can be widely shared in an enterprise environment, and is certainly shared in open source. To be managed safely, passwords and secret keys should be stored in separate configuration files or keystores.
Cryptographic keys should not be kept in the source code. The source code can be widely shared in an enterprise environment, and is certainly shared in open source. To be managed safely, passwords and secret keys should be stored in separate configuration files or keystores.
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); // ... ```
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: https://wiki.sei.cmu.edu/confluence/display/java/IDS11-J.+Perform+any+string+modifications+before+validation
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 > charcters 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: https://wiki.sei.cmu.edu/confluence/display/java/IDS01-J.+Normalize+strings+before+validating+them
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.
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.
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(true)` is called. For more information on how this issue can be exploited see: https://developer.okta.com/blog/2018/02/27/a-breakdown-of-the-new-saml-authentication-bypass-vulnerability For more information on SAML security see OWASP: https://cheatsheetseries.owasp.org/cheatsheets/SAML_Security_Cheat_Sheet.html
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); } throw new ClassNotFoundException(name); } }); ``` For more information on XML security see OWASP's guide: https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html#java For more details on deserialization attacks in general, see OWASP's guide: https://cheatsheetseries.owasp.org/cheatsheets/Deserialization_Cheat_Sheet.html It should be noted that [tools exist](https://github.com/frohoff/ysoserial) to automatically create exploit code for these vulnerabilities.
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: https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html#java For more information on the secure processing feature see: - https://xml.apache.org/xalan-j/features.html#secureprocessing
The application processes `XPath` queries with potentially malicious input. An adversary who is able to control the XPath query could potentially influence the logic of how data is retrieved, processed or even bypass protections. To protect against XPath injection, user input should be parameterized using a variable resolver. By creating a class that implements the `XPathVariableResolver` the application can ensure that the xpath query and user-supplied input are treated separately. Example implementation of an XPathVariableResolver: ``` // Create a class which implements the XPathVariableResolver interface public static class SimpleXPathVariableResolver implements XPathVariableResolver { // Use a map or lookup table to store variables for resolution private HashMap<QName, String> variables = new HashMap<>(); // Allow caller to set variables public void setVariable(QName name, String value) { variables.put(name, value); } // Implement the resolveVariable to return the value @Override public Object resolveVariable(QName name) { return variables.getOrDefault(name, ""); } } public static void xpathQuery(String userInput) throws ParseException, ParserConfigurationException, SAXException, IOException, XPathExpressionException { // Create our DocumentFactory DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance(); // Enable namespace awareness domFactory.setNamespaceAware(true); // Enable secure processing domFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); // Create our DocumentBuilder DocumentBuilder builder = domFactory.newDocumentBuilder(); // Parse our XML document Document doc = builder.parse("inventory.xml"); // Create a new instance of an XPath object XPath xpathProcessor = XPathFactory.newInstance().newXPath(); // Create our XPathVariableResolver SimpleXPathVariableResolver resolver = new SimpleXPathVariableResolver(); // Add user input as a variable value resolver.setVariable(new QName("author"), userInput); // Configure the processor to use our variable resolver xpathProcessor.setXPathVariableResolver(resolver); // Evaluate the XPath query String result = xpathProcessor.compile("//author[contains(., $author)]").evaluate(doc); // Work with the result // ... } ``` For more information on XPath Injection see: - https://owasp.org/www-community/attacks/XPATH_Injection

GCM detected, please check that IV/nonce is not reused, an Initialization Vector (IV) is a nonce used to randomize the encryption, so that even if multiple messages with identical plaintext are encrypted, the generated corresponding ciphertexts are different. Unlike the Key, the IV usually does not need to be secret, rather it is important that it is random and unique. Certain encryption schemes the IV is exchanged in public as part of the ciphertext. Reusing same Initialization Vector with the same Key to encrypt multiple plaintext blocks allows an attacker to compare the ciphertexts and then, with some assumptions on the content of the messages, to gain important information about the data being encrypted.

GCM IV/nonce is reused: encryption can be totally useless

Semgrep found potential reverse shell behavior