Skip to content

Commit 0c49937

Browse files
author
Jeremi Do Dinh
authored
Update rule metadata. (#1581)
1 parent 9ceb464 commit 0c49937

File tree

18 files changed

+601
-233
lines changed

18 files changed

+601
-233
lines changed

python-checks/src/main/resources/org/sonar/l10n/py/rules/python/S1763.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
<p>Once control flow has been moved out of the current code block, any subsequent statements become effectively unreachable.</p>
12
<h2>Why is this an issue?</h2>
23
<p>Jump statements (<code>return</code>, <code>break</code>, <code>continue</code>, and <code>raise</code>) move control flow out of the current code
34
block. So any statements that come after a jump are dead code.</p>

python-checks/src/main/resources/org/sonar/l10n/py/rules/python/S2115.html

Lines changed: 114 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,102 @@
1+
<p>When accessing a database, an empty password should be avoided as it introduces a weakness.</p>
12
<h2>Why is this an issue?</h2>
2-
<p>When relying on the password authentication mode for the database connection, a secure password should be chosen.</p>
3-
<p>This rule raises an issue when an empty password is used.</p>
4-
<h3>Noncompliant code example</h3>
5-
<p>Flask-SQLAlchemy</p>
6-
<pre>
3+
<p>When a database does not require a password for authentication, it allows anyone to access and manipulate the data stored within it. Exploiting
4+
this vulnerability typically involves identifying the target database and establishing a connection to it without the need for any authentication
5+
credentials.</p>
6+
<h3>What is the potential impact?</h3>
7+
<p>Once connected, an attacker can perform various malicious actions, such as viewing, modifying, or deleting sensitive information, potentially
8+
leading to data breaches or unauthorized access to critical systems. It is crucial to address this vulnerability promptly to ensure the security and
9+
integrity of the database and the data it contains.</p>
10+
<h4>Unauthorized Access to Sensitive Data</h4>
11+
<p>When a database lacks a password for authentication, it opens the door for unauthorized individuals to gain access to sensitive data. This can
12+
include personally identifiable information (PII), financial records, intellectual property, or any other confidential information stored in the
13+
database. Without proper access controls in place, malicious actors can exploit this vulnerability to retrieve sensitive data, potentially leading to
14+
identity theft, financial loss, or reputational damage.</p>
15+
<h4>Compromise of System Integrity</h4>
16+
<p>Without a password requirement, unauthorized individuals can gain unrestricted access to a database, potentially compromising the integrity of the
17+
entire system. Attackers can inject malicious code, alter configurations, or manipulate data within the database, leading to system malfunctions,
18+
unauthorized system access, or even complete system compromise. This can disrupt business operations, cause financial losses, and expose the
19+
organization to further security risks.</p>
20+
<h4>Unwanted Modifications or Deletions</h4>
21+
<p>The absence of a password for database access allows anyone to make modifications or deletions to the data stored within it. This poses a
22+
significant risk, as unauthorized changes can lead to data corruption, loss of critical information, or the introduction of malicious content. For
23+
example, an attacker could modify financial records, tamper with customer orders, or delete important files, causing severe disruptions to business
24+
processes and potentially leading to financial and legal consequences.</p>
25+
<p>Overall, the lack of a password configured to access a database poses a serious security risk, enabling unauthorized access, data breaches, system
26+
compromise, and unwanted modifications or deletions. It is essential to address this vulnerability promptly to safeguard sensitive data, maintain
27+
system integrity, and protect the organization from potential harm.</p>
28+
<h2>How to fix it in MySQL Connector/Python</h2>
29+
<h3>Code examples</h3>
30+
<p>The following code uses an empty password to connect to a MySQL database.</p>
31+
<p>The vulnerability can be fixed by using a strong password retrieved from an environment variable <code>DB_PASSWORD</code>. This environment
32+
variable is set during deployment. It should be strong and different for each database.</p>
33+
<h4>Noncompliant code example</h4>
34+
<pre data-diff-id="101" data-diff-type="noncompliant">
35+
from mysql.connector import connection
36+
37+
connection.MySQLConnection(host='localhost', user='sonarsource', password='') # Noncompliant
38+
</pre>
39+
<h4>Compliant solution</h4>
40+
<pre data-diff-id="101" data-diff-type="compliant">
41+
from mysql.connector import connection
42+
import os
43+
44+
db_password = os.getenv('DB_PASSWORD')
45+
connection.MySQLConnection(host='localhost', user='sonarsource', password=db_password)
46+
</pre>
47+
<h3>Pitfalls</h3>
48+
<h4>Hard-coded passwords</h4>
49+
<p>It could be tempting to replace the empty password with a hard-coded one. Hard-coding passwords in the code can pose significant security risks.
50+
Here are a few reasons why it is not recommended:</p>
51+
<ol>
52+
<li> Security Vulnerability: Hard-coded passwords can be easily discovered by anyone who has access to the code, such as other developers or
53+
attackers. This can lead to unauthorized access to the database and potential data breaches. </li>
54+
<li> Lack of Flexibility: Hard-coded passwords make it difficult to change the password without modifying the code. If the password needs to be
55+
updated, it would require recompiling and redeploying the code, which can be time-consuming and error-prone. </li>
56+
<li> Version Control Issues: Storing passwords in code can lead to version control issues. If the code is shared or stored in a version control
57+
system, the password will be visible to anyone with access to the repository, which is a security risk. </li>
58+
</ol>
59+
<p>To mitigate these risks, it is recommended to use secure methods for storing and retrieving passwords, such as using environment variables,
60+
configuration files, or secure key management systems. These methods allow for better security, flexibility, and separation of sensitive information
61+
from the codebase.</p>
62+
<h2>How to fix it in SQLAlchemy</h2>
63+
<h3>Code examples</h3>
64+
<p>The following code uses an empty password to connect to a Postgres database.</p>
65+
<p>The vulnerability can be fixed by using a strong password retrieved from an environment variable <code>DB_PASSWORD</code>. This environment
66+
variable is set during deployment. It should be strong and different for each database.</p>
67+
<h4>Noncompliant code example</h4>
68+
<pre data-diff-id="103" data-diff-type="noncompliant">
769
def configure_app(app):
870
app.config['SQLALCHEMY_DATABASE_URI'] = "postgresql://user:@domain.com" # Noncompliant
971
</pre>
10-
<p>Django</p>
11-
<pre>
72+
<h4>Compliant solution</h4>
73+
<pre data-diff-id="103" data-diff-type="compliant">
74+
def configure_app(app):
75+
db_password = os.getenv('DB_PASSWORD')
76+
app.config['SQLALCHEMY_DATABASE_URI'] = f"postgresql://user:{db_password}@domain.com"
77+
</pre>
78+
<h3>Pitfalls</h3>
79+
<h4>Hard-coded passwords</h4>
80+
<p>It could be tempting to replace the empty password with a hard-coded one. Hard-coding passwords in the code can pose significant security risks.
81+
Here are a few reasons why it is not recommended:</p>
82+
<ol>
83+
<li> Security Vulnerability: Hard-coded passwords can be easily discovered by anyone who has access to the code, such as other developers or
84+
attackers. This can lead to unauthorized access to the database and potential data breaches. </li>
85+
<li> Lack of Flexibility: Hard-coded passwords make it difficult to change the password without modifying the code. If the password needs to be
86+
updated, it would require recompiling and redeploying the code, which can be time-consuming and error-prone. </li>
87+
<li> Version Control Issues: Storing passwords in code can lead to version control issues. If the code is shared or stored in a version control
88+
system, the password will be visible to anyone with access to the repository, which is a security risk. </li>
89+
</ol>
90+
<p>To mitigate these risks, it is recommended to use secure methods for storing and retrieving passwords, such as using environment variables,
91+
configuration files, or secure key management systems. These methods allow for better security, flexibility, and separation of sensitive information
92+
from the codebase.</p>
93+
<h2>How to fix it in Django</h2>
94+
<h3>Code examples</h3>
95+
<p>The following code uses an empty password to connect to a Postgres database.</p>
96+
<p>The vulnerability can be fixed by using a strong password retrieved from an environment variable <code>DB_PASSWORD</code>. This environment
97+
variable is set during deployment. It should be strong and different for each database.</p>
98+
<h4>Noncompliant code example</h4>
99+
<pre data-diff-id="102" data-diff-type="noncompliant">
12100
# settings.py
13101

14102
DATABASES = {
@@ -22,20 +110,8 @@ <h3>Noncompliant code example</h3>
22110
}
23111
}
24112
</pre>
25-
<p>mysql/mysql-connector-python</p>
26-
<pre>
27-
from mysql.connector import connection
28-
29-
connection.MySQLConnection(host='localhost', user='sonarsource', password='') # Noncompliant
30-
</pre>
31-
<h3>Compliant solution</h3>
32-
<p>Flask-SQLAlchemy</p>
33-
<pre>
34-
def configure_app(app, pwd):
35-
app.config['SQLALCHEMY_DATABASE_URI'] = f"postgresql://user:{pwd}@domain.com" # Compliant
36-
</pre>
37-
<p>Django</p>
38-
<pre>
113+
<h4>Compliant solution</h4>
114+
<pre data-diff-id="102" data-diff-type="compliant">
39115
# settings.py
40116
import os
41117

@@ -44,21 +120,29 @@ <h3>Compliant solution</h3>
44120
'ENGINE': 'django.db.backends.postgresql',
45121
'NAME': 'quickdb',
46122
'USER': 'sonarsource',
47-
'PASSWORD': os.getenv('DB_PASSWORD'), # Compliant
123+
'PASSWORD': os.getenv('DB_PASSWORD'),
48124
'HOST': 'localhost',
49125
'PORT': '5432'
50126
}
51127
}
52128
</pre>
53-
<p>mysql/mysql-connector-python</p>
54-
<pre>
55-
from mysql.connector import connection
56-
import os
57-
58-
db_password = os.getenv('DB_PASSWORD')
59-
connection.MySQLConnection(host='localhost', user='sonarsource', password=db_password) # Compliant
60-
</pre>
129+
<h3>Pitfalls</h3>
130+
<h4>Hard-coded passwords</h4>
131+
<p>It could be tempting to replace the empty password with a hard-coded one. Hard-coding passwords in the code can pose significant security risks.
132+
Here are a few reasons why it is not recommended:</p>
133+
<ol>
134+
<li> Security Vulnerability: Hard-coded passwords can be easily discovered by anyone who has access to the code, such as other developers or
135+
attackers. This can lead to unauthorized access to the database and potential data breaches. </li>
136+
<li> Lack of Flexibility: Hard-coded passwords make it difficult to change the password without modifying the code. If the password needs to be
137+
updated, it would require recompiling and redeploying the code, which can be time-consuming and error-prone. </li>
138+
<li> Version Control Issues: Storing passwords in code can lead to version control issues. If the code is shared or stored in a version control
139+
system, the password will be visible to anyone with access to the repository, which is a security risk. </li>
140+
</ol>
141+
<p>To mitigate these risks, it is recommended to use secure methods for storing and retrieving passwords, such as using environment variables,
142+
configuration files, or secure key management systems. These methods allow for better security, flexibility, and separation of sensitive information
143+
from the codebase.</p>
61144
<h2>Resources</h2>
145+
<h3>Standards</h3>
62146
<ul>
63147
<li> <a href="https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures/">OWASP Top 10 2021 Category A7</a> - Identification and
64148
Authentication Failures </li>

python-checks/src/main/resources/org/sonar/l10n/py/rules/python/S2115.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
"impacts": {
66
"SECURITY": "HIGH"
77
},
8-
"attribute": "COMPLETE"
8+
"attribute": "TRUSTWORTHY"
99
},
1010
"status": "ready",
1111
"remediation": {

python-checks/src/main/resources/org/sonar/l10n/py/rules/python/S2755.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ <h3>Code examples</h3>
2222
<p>The following code contains examples of XML parsers that have external entity processing enabled. As a result, the parsers are vulnerable to XXE
2323
attacks if an attacker can control the XML file that is processed.</p>
2424
<h4>Noncompliant code example</h4>
25-
<pre data-diff-id="1" data-diff-type="noncompliant">
25+
<pre data-diff-id="11" data-diff-type="noncompliant">
2626
import xml.sax
2727

2828
parser = xml.sax.make_parser()
@@ -33,7 +33,7 @@ <h4>Noncompliant code example</h4>
3333
</pre>
3434
<h4>Compliant solution</h4>
3535
<p>The SAX parser does not process general external entities by default since version 3.7.1.</p>
36-
<pre data-diff-id="1" data-diff-type="compliant">
36+
<pre data-diff-id="11" data-diff-type="compliant">
3737
import xml.sax
3838

3939
parser = xml.sax.make_parser()

python-checks/src/main/resources/org/sonar/l10n/py/rules/python/S3329.html

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -67,14 +67,18 @@ <h4>Compliant solution</h4>
6767
</pre>
6868
<h3>How does this work?</h3>
6969
<h4>Use unique IVs</h4>
70-
<p>To ensure strong security, the initialization vectors for each encryption operation must be unique and random but they do not have to be
71-
secret.</p>
70+
<p>To ensure high security, initialization vectors must meet two important criteria:</p>
71+
<ul>
72+
<li> IVs must be unique for each encryption operation. </li>
73+
<li> For CBC and CFB modes, a secure FIPS-compliant random number generator should be used to generate unpredictable IVs. </li>
74+
</ul>
75+
<p>The IV does not need be secret, so the IV or information sufficient to determine the IV may be transmitted along with the ciphertext.</p>
7276
<p>In the previous non-compliant example, the problem is not that the IV is hard-coded.<br> It is that the same IV is used for multiple encryption
7377
attempts.</p>
7478
<h2>How to fix it in Cryptodome</h2>
7579
<h3>Code examples</h3>
7680
<h4>Noncompliant code example</h4>
77-
<pre data-diff-id="1" data-diff-type="noncompliant">
81+
<pre data-diff-id="11" data-diff-type="noncompliant">
7882
from Crypto.Cipher import AES
7983
from Crypto.Random import get_random_bytes
8084
from Crypto.Util.Padding import pad
@@ -85,7 +89,7 @@ <h4>Noncompliant code example</h4>
8589
</pre>
8690
<h4>Compliant solution</h4>
8791
<p>In this example, the code explicitly uses a number generator that is considered <strong>strong</strong>.</p>
88-
<pre data-diff-id="1" data-diff-type="compliant">
92+
<pre data-diff-id="11" data-diff-type="compliant">
8993
from Crypto.Cipher import AES
9094
from Crypto.Random import get_random_bytes
9195
from Crypto.Util.Padding import pad
@@ -96,8 +100,12 @@ <h4>Compliant solution</h4>
96100
</pre>
97101
<h3>How does this work?</h3>
98102
<h4>Use unique IVs</h4>
99-
<p>To ensure strong security, the initialization vectors for each encryption operation must be unique and random but they do not have to be
100-
secret.</p>
103+
<p>To ensure high security, initialization vectors must meet two important criteria:</p>
104+
<ul>
105+
<li> IVs must be unique for each encryption operation. </li>
106+
<li> For CBC and CFB modes, a secure FIPS-compliant random number generator should be used to generate unpredictable IVs. </li>
107+
</ul>
108+
<p>The IV does not need be secret, so the IV or information sufficient to determine the IV may be transmitted along with the ciphertext.</p>
101109
<p>In the previous non-compliant example, the problem is not that the IV is hard-coded.<br> It is that the same IV is used for multiple encryption
102110
attempts.</p>
103111
<h2>Resources</h2>

python-checks/src/main/resources/org/sonar/l10n/py/rules/python/S4423.html

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,13 @@ <h4>Legal and compliance issues</h4>
4343
<h2>How to fix it in Python Standard Library</h2>
4444
<h3>Code examples</h3>
4545
<h4>Noncompliant code example</h4>
46-
<pre data-diff-id="1" data-diff-type="noncompliant">
46+
<pre data-diff-id="21" data-diff-type="noncompliant">
4747
import ssl
4848

4949
ssl.SSLContext(ssl.PROTOCOL_SSLv3) # Noncompliant
5050
</pre>
5151
<h4>Compliant solution</h4>
52-
<pre data-diff-id="1" data-diff-type="compliant">
52+
<pre data-diff-id="21" data-diff-type="compliant">
5353
import ssl
5454

5555
context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
@@ -70,13 +70,13 @@ <h4>Use TLS v1.2 or TLS v1.3</h4>
7070
<h2>How to fix it in OpenSSL</h2>
7171
<h3>Code examples</h3>
7272
<h4>Noncompliant code example</h4>
73-
<pre data-diff-id="1" data-diff-type="noncompliant">
73+
<pre data-diff-id="11" data-diff-type="noncompliant">
7474
from OpenSSL import SSL
7575

7676
SSL.Context(SSL.SSLv3_METHOD) # Noncompliant
7777
</pre>
7878
<h4>Compliant solution</h4>
79-
<pre data-diff-id="1" data-diff-type="compliant">
79+
<pre data-diff-id="11" data-diff-type="compliant">
8080
from OpenSSL import SSL
8181

8282
context = SSL.Context(SSL.TLS_SERVER_METHOD)

python-checks/src/main/resources/org/sonar/l10n/py/rules/python/S4830.html

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ <h3>Code examples</h3>
2424
<p>Certificate validation is not enabled by default when <code>_create_unverified_context</code> is used. It is recommended to use
2525
<code>_create_default_https_context</code> instead to create a secure context that validates certificates.</p>
2626
<h4>Noncompliant code example</h4>
27-
<pre data-diff-id="1" data-diff-type="noncompliant">
27+
<pre data-diff-id="21" data-diff-type="noncompliant">
2828
import ssl
2929

3030
ctx1 = ssl._create_unverified_context() # Noncompliant
@@ -34,7 +34,7 @@ <h4>Noncompliant code example</h4>
3434
ctx3.verify_mode = ssl.CERT_NONE # Noncompliant
3535
</pre>
3636
<h4>Compliant solution</h4>
37-
<pre data-diff-id="1" data-diff-type="compliant">
37+
<pre data-diff-id="21" data-diff-type="compliant">
3838
import ssl
3939

4040
ctx = ssl.create_default_context()
@@ -67,7 +67,7 @@ <h4>Noncompliant code example</h4>
6767
ctx2.set_verify(SSL.VERIFY_NONE, verify_callback) # Noncompliant
6868
</pre>
6969
<h4>Compliant solution</h4>
70-
<pre data-diff-id="1" data-diff-type="noncompliant">
70+
<pre data-diff-id="1" data-diff-type="compliant">
7171
from OpenSSL import SSL
7272

7373
ctx = SSL.Context(SSL.TLSv1_2_METHOD)
@@ -91,13 +91,13 @@ <h3>Code examples</h3>
9191
<p>The certificate validation gets disabled by setting <code>verify</code> to <code>False</code>. To enable validation set the value to
9292
<code>True</code> or do not set <code>verify</code> at all to use the secure default value.</p>
9393
<h4>Noncompliant code example</h4>
94-
<pre data-diff-id="1" data-diff-type="noncompliant">
94+
<pre data-diff-id="11" data-diff-type="noncompliant">
9595
import requests
9696

9797
requests.request('GET', 'https://example.com', verify=False) # Noncompliant
9898
</pre>
9999
<h4>Compliant solution</h4>
100-
<pre data-diff-id="1" data-diff-type="noncompliant">
100+
<pre data-diff-id="11" data-diff-type="compliant">
101101
import requests
102102

103103
# By default, certificate validation is enabled

0 commit comments

Comments
 (0)