Skip to content

Commit d1532ce

Browse files
SONARJAVA-6460 Update rule metadata
1 parent 9e4c73a commit d1532ce

25 files changed

Lines changed: 570 additions & 512 deletions
Lines changed: 29 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,18 @@
1-
<p>Formatted SQL queries can be difficult to maintain, debug and can increase the risk of SQL injection when concatenating untrusted values into the
2-
query. However, this rule doesn’t detect SQL injections (unlike rule {rule:javasecurity:S3649}), the goal is only to highlight complex/formatted queries.</p>
3-
<h2>Ask Yourself Whether</h2>
4-
<ul>
5-
<li>Some parts of the query come from untrusted values (like user inputs).</li>
6-
<li>The query is repeated/duplicated in other parts of the code.</li>
7-
<li>The application must support different types of relational databases.</li>
8-
</ul>
9-
<p>There is a risk if you answered yes to any of those questions.</p>
10-
<h2>Recommended Secure Coding Practices</h2>
11-
<ul>
12-
<li>Use <a href="https://cheatsheetseries.owasp.org/cheatsheets/Query_Parameterization_Cheat_Sheet.html">parameterized queries, prepared statements,
13-
or stored procedures</a> and bind variables to SQL query parameters.</li>
14-
<li>Consider using ORM frameworks if there is a need to have an abstract layer to access data.</li>
15-
</ul>
16-
<h2>Sensitive Code Example</h2>
17-
<pre>
1+
<p>Dynamically building SQL query strings can result in broken SQL syntax and open SQL injection attacks.</p>
2+
<h2>Why is this an issue?</h2>
3+
<p>When SQL queries are constructed by concatenating or formatting user-supplied values directly into the query string, the structure of the query
4+
itself can be altered by a malicious input. This rule flags calls to SQL execution functions where the query string is built using string
5+
concatenation or format operators rather than parameterized queries or prepared statements. Unlike rule {rule:javasecurity:S3649}, this rule does not perform
6+
taint analysis — it flags all dynamically formatted SQL queries as a potential risk regardless of the data source.</p>
7+
<h3>What is the potential impact?</h3>
8+
<h4>SQL injection</h4>
9+
<p>If any part of a dynamically formatted query string originates from untrusted input, an attacker can manipulate the query to read, modify, or
10+
delete data they should not have access to, bypass authentication checks, or in some configurations execute operating system commands.</p>
11+
<h2>How to fix it</h2>
12+
<h3>Code examples</h3>
13+
<p>The following code builds a SQL query by concatenating a value directly into the query string.</p>
14+
<h4>Noncompliant code example</h4>
15+
<pre data-diff-id="1" data-diff-type="noncompliant">
1816
public User getUser(Connection con, String user) throws SQLException {
1917

2018
Statement stmt1 = null;
@@ -26,10 +24,10 @@ <h2>Sensitive Code Example</h2>
2624

2725
stmt2 = con.createStatement();
2826
ResultSet rs2 = stmt2.executeQuery("select FNAME, LNAME, SSN " +
29-
"from USERS where UNAME=" + user); // Sensitive
27+
"from USERS where UNAME=" + user); // Noncompliant
3028

3129
pstmt = con.prepareStatement("select FNAME, LNAME, SSN " +
32-
"from USERS where UNAME=" + user); // Sensitive
30+
"from USERS where UNAME=" + user); // Noncompliant
3331
ResultSet rs3 = pstmt.executeQuery();
3432

3533
//...
@@ -38,12 +36,12 @@ <h2>Sensitive Code Example</h2>
3836
public User getUserHibernate(org.hibernate.Session session, String data) {
3937

4038
org.hibernate.Query query = session.createQuery(
41-
"FROM students where fname = " + data); // Sensitive
39+
"FROM students where fname = " + data); // Noncompliant
4240
// ...
4341
}
4442
</pre>
45-
<h2>Compliant Solution</h2>
46-
<pre>
43+
<h4>Compliant solution</h4>
44+
<pre data-diff-id="1" data-diff-type="compliant">
4745
public User getUser(Connection con, String user) throws SQLException {
4846

4947
Statement stmt1 = null;
@@ -55,7 +53,7 @@ <h2>Compliant Solution</h2>
5553
ResultSet rs1 = stmt1.executeQuery("GETDATE()");
5654

5755
pstmt = con.prepareStatement(query);
58-
pstmt.setString(1, user); // Good; PreparedStatements escape their inputs.
56+
pstmt.setString(1, user);
5957
ResultSet rs2 = pstmt.executeQuery();
6058

6159
//...
@@ -66,22 +64,21 @@ <h2>Compliant Solution</h2>
6664

6765
org.hibernate.Query query = session.createQuery("FROM students where fname = ?");
6866
query = query.setParameter(0,data); // Good; Parameter binding escapes all input
69-
70-
org.hibernate.Query query2 = session.createQuery("FROM students where fname = " + data); // Sensitive
71-
// ...
7267
</pre>
73-
<h2>See</h2>
68+
<h2>Resources</h2>
69+
<h3>Articles &amp; blog posts</h3>
70+
<ul>
71+
<li>Derived from FindSecBugs rules <a href="https://h3xstream.github.io/find-sec-bugs/bugs.htm#SQL_INJECTION_JPA">Potential SQL/JPQL Injection
72+
(JPA)</a>, <a href="https://h3xstream.github.io/find-sec-bugs/bugs.htm#SQL_INJECTION_JDO">Potential SQL/JDOQL Injection (JDO)</a>, <a
73+
href="https://h3xstream.github.io/find-sec-bugs/bugs.htm#SQL_INJECTION_HIBERNATE">Potential SQL/HQL Injection (Hibernate)</a></li>
74+
</ul>
75+
<h3>Standards</h3>
7476
<ul>
7577
<li>OWASP - <a href="https://owasp.org/Top10/A03_2021-Injection/">Top 10 2021 Category A3 - Injection</a></li>
7678
<li>OWASP - <a href="https://owasp.org/www-project-top-ten/2017/A1_2017-Injection">Top 10 2017 Category A1 - Injection</a></li>
7779
<li>CWE - <a href="https://cwe.mitre.org/data/definitions/89">CWE-89 - Improper Neutralization of Special Elements used in an SQL Command</a></li>
78-
<li>CWE - <a href="https://cwe.mitre.org/data/definitions/564">CWE-564 - SQL Injection: Hibernate</a></li>
79-
<li>CWE - <a href="https://cwe.mitre.org/data/definitions/20">CWE-20 - Improper Input Validation</a></li>
8080
<li>CWE - <a href="https://cwe.mitre.org/data/definitions/943">CWE-943 - Improper Neutralization of Special Elements in Data Query Logic</a></li>
8181
<li><a
8282
href="https://cmu-sei.github.io/secure-coding-standards/sei-cert-oracle-coding-standard-for-java/rules/input-validation-and-data-sanitization-ids/ids00-j">CERT, IDS00-J.</a> - Prevent SQL injection</li>
83-
<li>Derived from FindSecBugs rules <a href="https://h3xstream.github.io/find-sec-bugs/bugs.htm#SQL_INJECTION_JPA">Potential SQL/JPQL Injection
84-
(JPA)</a>, <a href="https://h3xstream.github.io/find-sec-bugs/bugs.htm#SQL_INJECTION_JDO">Potential SQL/JDOQL Injection (JDO)</a>, <a
85-
href="https://h3xstream.github.io/find-sec-bugs/bugs.htm#SQL_INJECTION_HIBERNATE">Potential SQL/HQL Injection (Hibernate)</a></li>
8683
</ul>
8784

sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S2077.json

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
2-
"title": "Formatting SQL queries is security-sensitive",
3-
"type": "SECURITY_HOTSPOT",
2+
"title": "SQL queries should not be dynamically formatted",
3+
"type": "VULNERABILITY",
44
"code": {
55
"impacts": {
66
"MAINTAINABILITY": "LOW",
@@ -9,6 +9,7 @@
99
"attribute": "COMPLETE"
1010
},
1111
"status": "ready",
12+
"quickfix": "unknown",
1213
"remediation": {
1314
"func": "Constant\/Issue",
1415
"constantCost": "20min"
@@ -19,7 +20,8 @@
1920
"bad-practice",
2021
"cert",
2122
"hibernate",
22-
"sql"
23+
"sql",
24+
"former-hotspot"
2325
],
2426
"defaultSeverity": "Major",
2527
"ruleSpecification": "RSPEC-2077",
@@ -30,8 +32,8 @@
3032
"IDS00-J."
3133
],
3234
"CWE": [
33-
20,
34-
89
35+
89,
36+
943
3537
],
3638
"OWASP": [
3739
"A1"
@@ -51,6 +53,5 @@
5153
"5.3.4",
5254
"5.3.5"
5355
]
54-
},
55-
"quickfix": "unknown"
56+
}
5657
}

sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S2245.html

Lines changed: 30 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,42 @@
1-
<p>PRNGs are algorithms that produce sequences of numbers that only approximate true randomness. While they are suitable for applications like
2-
simulations or modeling, they are not appropriate for security-sensitive contexts because their outputs can be predictable if the internal state is
3-
known.</p>
4-
<p>In contrast, cryptographically secure pseudorandom number generators (CSPRNGs) are designed to be secure against prediction attacks. CSPRNGs use
5-
cryptographic algorithms to ensure that the generated sequences are not only random but also unpredictable, even if part of the sequence or the
6-
internal state becomes known. This unpredictability is crucial for security-related tasks such as generating encryption keys, tokens, or any other
7-
values that must remain confidential and resistant to guessing attacks.</p>
8-
<p>For example, the use of non-cryptographic PRNGs has led to vulnerabilities such as:</p>
9-
<ul>
10-
<li><a href="https://www.cve.org/CVERecord?id=CVE-2013-6386">CVE-2013-6386</a></li>
11-
<li><a href="https://www.cve.org/CVERecord?id=CVE-2006-3419">CVE-2006-3419</a></li>
12-
<li><a href="https://www.cve.org/CVERecord?id=CVE-2008-4102">CVE-2008-4102</a></li>
13-
</ul>
14-
<p>When software generates predictable values in a context requiring unpredictability, it may be possible for an attacker to guess the next value that
15-
will be generated, and use this guess to impersonate another user or access sensitive information. Therefore, it is critical to use CSPRNGs in any
16-
security-sensitive application to ensure the robustness and security of the system.</p>
17-
<p>As the <code>java.util.Random</code> class relies on a non-cryptographic pseudorandom number generator, this class and relating
18-
<code>java.lang.Math.random()</code> method should not be used for security-critical applications or for protecting sensitive data. In such context,
19-
the <code>java.security.SecureRandom</code> class which relies on a CSPRNG should be used in place.</p>
20-
<h2>Ask Yourself Whether</h2>
21-
<ul>
22-
<li>the code using the generated value requires it to be unpredictable. It is the case for all encryption mechanisms or when a secret value, such as
23-
a password, is hashed.</li>
24-
<li>the function you use is a non-cryptographic PRNG.</li>
25-
<li>the generated value is used multiple times.</li>
26-
<li>an attacker can access the generated value.</li>
27-
</ul>
28-
<p>There is a risk if you answered yes to any of those questions.</p>
29-
<h2>Recommended Secure Coding Practices</h2>
30-
<ul>
31-
<li>Use a cryptographically secure pseudo random number generator (CSPRNG) like "java.security.SecureRandom" in place of a non-cryptographic
32-
PRNG.</li>
33-
<li>Use the generated random values only once.</li>
34-
<li>You should not expose the generated random value. If you have to store it, make sure that the database or file is secure.</li>
35-
</ul>
36-
<h2>Sensitive Code Example</h2>
37-
<pre>
38-
Random random = new Random(); // Sensitive use of Random
1+
<p>Pseudorandom number generators (PRNGs) produce sequences that only approximate true randomness and are not suitable for security-sensitive
2+
contexts.</p>
3+
<h2>Why is this an issue?</h2>
4+
<p>When software generates predictable values in a context requiring unpredictability, an attacker who knows or can guess the internal state of the
5+
PRNG may predict the next value that will be generated. The rule flags the use of non-cryptographic PRNGs in contexts where a cryptographically secure
6+
pseudorandom number generator (CSPRNG) is required, such as generating encryption keys, tokens, or other secret values.</p>
7+
<p>As the <code>java.util.Random</code> class relies on a non-cryptographic pseudorandom number generator, this class and the related
8+
<code>java.lang.Math.random()</code> method should not be used for security-critical applications or for protecting sensitive data. In such contexts,
9+
the <code>java.security.SecureRandom</code> class which relies on a CSPRNG should be used instead.</p>
10+
<h3>What is the potential impact?</h3>
11+
<h4>Predictable values</h4>
12+
<p>If an attacker can predict the values generated by a PRNG, they may be able to guess session tokens, encryption keys, password reset links, or
13+
other secrets, leading to unauthorized access or impersonation.</p>
14+
<h4>Broken cryptography</h4>
15+
<p>Using a non-cryptographic PRNG to generate keys or initialization vectors weakens the security of the cryptographic scheme, potentially making it
16+
trivially breakable.</p>
17+
<h2>How to fix it</h2>
18+
<h3>Code examples</h3>
19+
<p>Use a cryptographically secure pseudorandom number generator (CSPRNG) instead of a non-cryptographic PRNG.</p>
20+
<h4>Noncompliant code example</h4>
21+
<pre data-diff-id="1" data-diff-type="noncompliant">
22+
Random random = new Random(); // Noncompliant
3923
byte bytes[] = new byte[20];
40-
random.nextBytes(bytes); // Check if bytes is used for hashing, encryption, etc...
24+
random.nextBytes(bytes);
4125
</pre>
42-
<h2>Compliant Solution</h2>
43-
<pre>
26+
<h4>Compliant solution</h4>
27+
<pre data-diff-id="1" data-diff-type="compliant">
4428
SecureRandom random = new SecureRandom();
4529
byte bytes[] = new byte[20];
4630
random.nextBytes(bytes);
4731
</pre>
48-
<h2>See</h2>
32+
<h2>Resources</h2>
33+
<h3>Documentation</h3>
4934
<ul>
5035
<li>OWASP - <a href="https://cheatsheetseries.owasp.org/cheatsheets/Cryptographic_Storage_Cheat_Sheet.html#secure-random-number-generation">Secure
5136
Random Number Generation Cheat Sheet</a></li>
37+
</ul>
38+
<h3>Standards</h3>
39+
<ul>
5240
<li>OWASP - <a href="https://owasp.org/Top10/A02_2021-Cryptographic_Failures/">Top 10 2021 Category A2 - Cryptographic Failures</a></li>
5341
<li>OWASP - <a href="https://owasp.org/www-project-top-ten/2017/A3_2017-Sensitive_Data_Exposure">Top 10 2017 Category A3 - Sensitive Data
5442
Exposure</a></li>

sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S2245.json

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,23 @@
11
{
2-
"title": "Using pseudorandom number generators (PRNGs) is security-sensitive",
3-
"type": "SECURITY_HOTSPOT",
2+
"title": "Pseudorandom number generators (PRNGs) should not be used in security contexts",
3+
"type": "VULNERABILITY",
44
"code": {
55
"impacts": {
6-
"SECURITY": "HIGH"
6+
"SECURITY": "MEDIUM"
77
},
88
"attribute": "TRUSTWORTHY"
99
},
1010
"status": "ready",
11+
"quickfix": "unknown",
1112
"remediation": {
1213
"func": "Constant\/Issue",
1314
"constantCost": "10min"
1415
},
1516
"tags": [
16-
"cwe"
17+
"cwe",
18+
"former-hotspot"
1719
],
18-
"defaultSeverity": "Critical",
20+
"defaultSeverity": "Major",
1921
"ruleSpecification": "RSPEC-2245",
2022
"sqKey": "S2245",
2123
"scope": "Main",
@@ -49,6 +51,5 @@
4951
"ASVS 4.0": [
5052
"6.2.4"
5153
]
52-
},
53-
"quickfix": "unknown"
54+
}
5455
}

sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S4036.html

Lines changed: 28 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,60 +1,40 @@
1-
<p>When you run an OS command, it is always important to protect yourself against the risk of accidental or malicious replacement of the executables
2-
in the production system.</p>
3-
<p>To do so, it is important to point to the specific executable that should be used.</p>
4-
<p>For example, if you call <code>git</code> (without specifying a path), the operating system will search for the executable in the directories
5-
specified in the <code>PATH</code> environment variable.
6-
<br>
7-
An attacker could have added, in a permissive directory covered by <code>PATH</code> , another executable called <code>git</code>, but with a
8-
completely different behavior, for example exfiltrating data or exploiting a vulnerability in your own code.</p>
9-
<p>However, by calling <code>/usr/bin/git</code> or <code>../git</code> (relative path) directly, the operating system will always use the intended
10-
executable.
11-
<br>
12-
Note that you still need to make sure that the executable is not world-writeable and potentially overwritten. This is not the scope of this
13-
rule.</p>
14-
<h2>Ask Yourself Whether</h2>
15-
<ul>
16-
<li>The PATH environment variable only contains fixed, trusted directories.</li>
17-
</ul>
18-
<p>There is a risk if you answered no to this question.</p>
19-
<h2>Recommended Secure Coding Practices</h2>
20-
<p>If you wish to rely on the <code>PATH</code> environment variable to locate the OS command, make sure that each of its listed directories is fixed,
21-
not susceptible to change, and not writable by unprivileged users.</p>
22-
<p>If you determine that these folders cannot be altered, and that you are sure that the program you intended to use will be used, then you can
23-
determine that these risks are under your control.</p>
24-
<p>A good practice you can use is to also hardcode the <code>PATH</code> variable you want to use, if you can do so in the framework you use.</p>
25-
<p>If the previous recommendations cannot be followed due to their complexity or other requirements, then consider using the absolute path of the
26-
command instead.</p>
27-
<pre>
28-
$ whereis git
29-
git: /usr/bin/git /usr/share/man/man1/git.1.gz
30-
$ ls -l /usr/bin/git
31-
-rwxr-xr-x 1 root root 3376112 Jan 28 10:13 /usr/bin/git
32-
</pre>
33-
<h2>Sensitive Code Example</h2>
34-
<p>The full path of the command is not specified and thus the executable will be searched in all directories listed in the <code>PATH</code>
35-
environment variable:</p>
36-
<pre>
37-
Runtime.getRuntime().exec("make"); // Sensitive
38-
Runtime.getRuntime().exec(new String[]{"make"}); // Sensitive
1+
<p>Executing an OS command without specifying an absolute or relative path exposes the application to PATH-hijacking attacks.</p>
2+
<h2>Why is this an issue?</h2>
3+
<p>When an OS command is executed using only its name (without an absolute or relative path), the operating system searches each directory listed in
4+
the <code>PATH</code> environment variable until it finds a matching executable. If an attacker can write to any directory listed in
5+
<code>PATH</code>, or can prepend a directory they control to <code>PATH</code>, they can place a malicious executable with the same name as the
6+
intended command. The next time the application executes the command, the malicious binary will run instead of the intended one.</p>
7+
<h3>What is the potential impact?</h3>
8+
<h4>Arbitrary command execution</h4>
9+
<p>If a directory in <code>PATH</code> is writable by an unprivileged user, or if an attacker can influence the value of <code>PATH</code>, they can
10+
substitute the expected executable with a malicious binary of the same name. This gives the attacker arbitrary code execution in the context of the
11+
application, which may lead to data exfiltration, privilege escalation, or full system compromise.</p>
12+
<h2>How to fix it</h2>
13+
<h3>Code examples</h3>
14+
<p>The following code executes a command by name only, causing the operating system to search <code>PATH</code> to locate the executable.</p>
15+
<h4>Noncompliant code example</h4>
16+
<pre data-diff-id="1" data-diff-type="noncompliant">
17+
Runtime.getRuntime().exec("make"); // Noncompliant
18+
Runtime.getRuntime().exec(new String[]{"make"}); // Noncompliant
3919

40-
ProcessBuilder builder = new ProcessBuilder("make"); // Sensitive
41-
builder.command("make"); // Sensitive
20+
ProcessBuilder builder = new ProcessBuilder("make"); // Noncompliant
21+
builder.command("make"); // Noncompliant
4222
</pre>
43-
<h2>Compliant Solution</h2>
44-
<p>The command is defined by its full path:</p>
45-
<pre>
23+
<h4>Compliant solution</h4>
24+
<pre data-diff-id="1" data-diff-type="compliant">
4625
Runtime.getRuntime().exec("/usr/bin/make");
4726
Runtime.getRuntime().exec(new String[]{"~/bin/make"});
4827

4928
ProcessBuilder builder = new ProcessBuilder("./bin/make");
5029
builder.command("../bin/make");
51-
builder.command(Arrays.asList("..\bin\make", "-j8"));
30+
builder.command(Arrays.asList("..\\bin\\make", "-j8"));
5231

53-
builder = new ProcessBuilder(Arrays.asList(".\make"));
54-
builder.command(Arrays.asList("C:\bin\make", "-j8"));
55-
builder.command(Arrays.asList("\\SERVER\bin\make"));
32+
builder = new ProcessBuilder(Arrays.asList(".\\make"));
33+
builder.command(Arrays.asList("C:\\bin\\make", "-j8"));
34+
builder.command(Arrays.asList("\\\\SERVER\\bin\\make"));
5635
</pre>
57-
<h2>See</h2>
36+
<h2>Resources</h2>
37+
<h3>Standards</h3>
5838
<ul>
5939
<li>OWASP - <a href="https://owasp.org/Top10/A08_2021-Software_and_Data_Integrity_Failures/">Top 10 2021 Category A8 - Software and Data Integrity
6040
Failures</a></li>

sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S4036.json

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,21 @@
11
{
2-
"title": "Searching OS commands in PATH is security-sensitive",
3-
"type": "SECURITY_HOTSPOT",
2+
"title": "OS commands should not rely on PATH resolution",
3+
"type": "VULNERABILITY",
44
"code": {
55
"impacts": {
66
"SECURITY": "LOW"
77
},
88
"attribute": "COMPLETE"
99
},
1010
"status": "ready",
11+
"quickfix": "unknown",
1112
"remediation": {
1213
"func": "Constant\/Issue",
1314
"constantCost": "15min"
1415
},
1516
"tags": [
16-
"cwe"
17+
"cwe",
18+
"former-hotspot"
1719
],
1820
"defaultSeverity": "Minor",
1921
"ruleSpecification": "RSPEC-4036",
@@ -30,6 +32,5 @@
3032
"OWASP Top 10 2021": [
3133
"A8"
3234
]
33-
},
34-
"quickfix": "unknown"
35+
}
3536
}

0 commit comments

Comments
 (0)