diff --git a/python-checks/src/main/resources/org/sonar/l10n/py/rules/python/S1763.html b/python-checks/src/main/resources/org/sonar/l10n/py/rules/python/S1763.html index 899ccf0231..3f9004b810 100644 --- a/python-checks/src/main/resources/org/sonar/l10n/py/rules/python/S1763.html +++ b/python-checks/src/main/resources/org/sonar/l10n/py/rules/python/S1763.html @@ -1,3 +1,4 @@ +
Once control flow has been moved out of the current code block, any subsequent statements become effectively unreachable.
Jump statements (return
, break
, continue
, and raise
) move control flow out of the current code
block. So any statements that come after a jump are dead code.
When accessing a database, an empty password should be avoided as it introduces a weakness.
When relying on the password authentication mode for the database connection, a secure password should be chosen.
-This rule raises an issue when an empty password is used.
-Flask-SQLAlchemy
-+When a database does not require a password for authentication, it allows anyone to access and manipulate the data stored within it. Exploiting +this vulnerability typically involves identifying the target database and establishing a connection to it without the need for any authentication +credentials.
+What is the potential impact?
+Once connected, an attacker can perform various malicious actions, such as viewing, modifying, or deleting sensitive information, potentially +leading to data breaches or unauthorized access to critical systems. It is crucial to address this vulnerability promptly to ensure the security and +integrity of the database and the data it contains.
+Unauthorized Access to Sensitive Data
+When a database lacks a password for authentication, it opens the door for unauthorized individuals to gain access to sensitive data. This can +include personally identifiable information (PII), financial records, intellectual property, or any other confidential information stored in the +database. Without proper access controls in place, malicious actors can exploit this vulnerability to retrieve sensitive data, potentially leading to +identity theft, financial loss, or reputational damage.
+Compromise of System Integrity
+Without a password requirement, unauthorized individuals can gain unrestricted access to a database, potentially compromising the integrity of the +entire system. Attackers can inject malicious code, alter configurations, or manipulate data within the database, leading to system malfunctions, +unauthorized system access, or even complete system compromise. This can disrupt business operations, cause financial losses, and expose the +organization to further security risks.
+Unwanted Modifications or Deletions
+The absence of a password for database access allows anyone to make modifications or deletions to the data stored within it. This poses a +significant risk, as unauthorized changes can lead to data corruption, loss of critical information, or the introduction of malicious content. For +example, an attacker could modify financial records, tamper with customer orders, or delete important files, causing severe disruptions to business +processes and potentially leading to financial and legal consequences.
+Overall, the lack of a password configured to access a database poses a serious security risk, enabling unauthorized access, data breaches, system +compromise, and unwanted modifications or deletions. It is essential to address this vulnerability promptly to safeguard sensitive data, maintain +system integrity, and protect the organization from potential harm.
+How to fix it in MySQL Connector/Python
+Code examples
+The following code uses an empty password to connect to a MySQL database.
+The vulnerability can be fixed by using a strong password retrieved from an environment variable
+DB_PASSWORD
. This environment +variable is set during deployment. It should be strong and different for each database.Noncompliant code example
++from mysql.connector import connection + +connection.MySQLConnection(host='localhost', user='sonarsource', password='') # Noncompliant ++Compliant solution
++from mysql.connector import connection +import os + +db_password = os.getenv('DB_PASSWORD') +connection.MySQLConnection(host='localhost', user='sonarsource', password=db_password) ++Pitfalls
+Hard-coded passwords
+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. +Here are a few reasons why it is not recommended:
++
+- Security Vulnerability: Hard-coded passwords can be easily discovered by anyone who has access to the code, such as other developers or + attackers. This can lead to unauthorized access to the database and potential data breaches.
+- Lack of Flexibility: Hard-coded passwords make it difficult to change the password without modifying the code. If the password needs to be + updated, it would require recompiling and redeploying the code, which can be time-consuming and error-prone.
+- Version Control Issues: Storing passwords in code can lead to version control issues. If the code is shared or stored in a version control + system, the password will be visible to anyone with access to the repository, which is a security risk.
+To mitigate these risks, it is recommended to use secure methods for storing and retrieving passwords, such as using environment variables, +configuration files, or secure key management systems. These methods allow for better security, flexibility, and separation of sensitive information +from the codebase.
+How to fix it in SQLAlchemy
+Code examples
+The following code uses an empty password to connect to a Postgres database.
+The vulnerability can be fixed by using a strong password retrieved from an environment variable
+DB_PASSWORD
. This environment +variable is set during deployment. It should be strong and different for each database.Noncompliant code example
+def configure_app(app): app.config['SQLALCHEMY_DATABASE_URI'] = "postgresql://user:@domain.com" # Noncompliant-Django
-+Compliant solution
++def configure_app(app): + db_password = os.getenv('DB_PASSWORD') + app.config['SQLALCHEMY_DATABASE_URI'] = f"postgresql://user:{db_password}@domain.com" ++Pitfalls
+Hard-coded passwords
+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. +Here are a few reasons why it is not recommended:
++
+- Security Vulnerability: Hard-coded passwords can be easily discovered by anyone who has access to the code, such as other developers or + attackers. This can lead to unauthorized access to the database and potential data breaches.
+- Lack of Flexibility: Hard-coded passwords make it difficult to change the password without modifying the code. If the password needs to be + updated, it would require recompiling and redeploying the code, which can be time-consuming and error-prone.
+- Version Control Issues: Storing passwords in code can lead to version control issues. If the code is shared or stored in a version control + system, the password will be visible to anyone with access to the repository, which is a security risk.
+To mitigate these risks, it is recommended to use secure methods for storing and retrieving passwords, such as using environment variables, +configuration files, or secure key management systems. These methods allow for better security, flexibility, and separation of sensitive information +from the codebase.
+How to fix it in Django
+Code examples
+The following code uses an empty password to connect to a Postgres database.
+The vulnerability can be fixed by using a strong password retrieved from an environment variable
+DB_PASSWORD
. This environment +variable is set during deployment. It should be strong and different for each database.Noncompliant code example
+# settings.py DATABASES = { @@ -22,20 +110,8 @@-Noncompliant code example
} }mysql/mysql-connector-python
--from mysql.connector import connection - -connection.MySQLConnection(host='localhost', user='sonarsource', password='') # Noncompliant --Compliant solution
-Flask-SQLAlchemy
--def configure_app(app, pwd): - app.config['SQLALCHEMY_DATABASE_URI'] = f"postgresql://user:{pwd}@domain.com" # Compliant --Django
-+Compliant solution
+# settings.py import os @@ -44,21 +120,29 @@-Compliant solution
'ENGINE': 'django.db.backends.postgresql', 'NAME': 'quickdb', 'USER': 'sonarsource', - 'PASSWORD': os.getenv('DB_PASSWORD'), # Compliant + 'PASSWORD': os.getenv('DB_PASSWORD'), 'HOST': 'localhost', 'PORT': '5432' } }mysql/mysql-connector-python
--from mysql.connector import connection -import os - -db_password = os.getenv('DB_PASSWORD') -connection.MySQLConnection(host='localhost', user='sonarsource', password=db_password) # Compliant -+Pitfalls
+Hard-coded passwords
+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. +Here are a few reasons why it is not recommended:
++
+- Security Vulnerability: Hard-coded passwords can be easily discovered by anyone who has access to the code, such as other developers or + attackers. This can lead to unauthorized access to the database and potential data breaches.
+- Lack of Flexibility: Hard-coded passwords make it difficult to change the password without modifying the code. If the password needs to be + updated, it would require recompiling and redeploying the code, which can be time-consuming and error-prone.
+- Version Control Issues: Storing passwords in code can lead to version control issues. If the code is shared or stored in a version control + system, the password will be visible to anyone with access to the repository, which is a security risk.
+To mitigate these risks, it is recommended to use secure methods for storing and retrieving passwords, such as using environment variables, +configuration files, or secure key management systems. These methods allow for better security, flexibility, and separation of sensitive information +from the codebase.
Resources
+Standards
The following code contains examples of XML parsers that have external entity processing enabled. As a result, the parsers are vulnerable to XXE attacks if an attacker can control the XML file that is processed.
+import xml.sax parser = xml.sax.make_parser() @@ -33,7 +33,7 @@Noncompliant code example
Compliant solution
The SAX parser does not process general external entities by default since version 3.7.1.
-+import xml.sax parser = xml.sax.make_parser() diff --git a/python-checks/src/main/resources/org/sonar/l10n/py/rules/python/S3329.html b/python-checks/src/main/resources/org/sonar/l10n/py/rules/python/S3329.html index e4ddc1ed1d..64d2660040 100644 --- a/python-checks/src/main/resources/org/sonar/l10n/py/rules/python/S3329.html +++ b/python-checks/src/main/resources/org/sonar/l10n/py/rules/python/S3329.html @@ -67,14 +67,18 @@Compliant solution
How does this work?
Use unique IVs
-To ensure strong security, the initialization vectors for each encryption operation must be unique and random but they do not have to be -secret.
+To ensure high security, initialization vectors must meet two important criteria:
+
The IV does not need be secret, so the IV or information sufficient to determine the IV may be transmitted along with the ciphertext.
In the previous non-compliant example, the problem is not that the IV is hard-coded.
It is that the same IV is used for multiple encryption
attempts.
+from Crypto.Cipher import AES from Crypto.Random import get_random_bytes from Crypto.Util.Padding import pad @@ -85,7 +89,7 @@Noncompliant code example
Compliant solution
In this example, the code explicitly uses a number generator that is considered strong.
-+from Crypto.Cipher import AES from Crypto.Random import get_random_bytes from Crypto.Util.Padding import pad @@ -96,8 +100,12 @@Compliant solution
How does this work?
Use unique IVs
-To ensure strong security, the initialization vectors for each encryption operation must be unique and random but they do not have to be -secret.
+To ensure high security, initialization vectors must meet two important criteria:
+
The IV does not need be secret, so the IV or information sufficient to determine the IV may be transmitted along with the ciphertext.
In the previous non-compliant example, the problem is not that the IV is hard-coded.
It is that the same IV is used for multiple encryption
attempts.
+import ssl ssl.SSLContext(ssl.PROTOCOL_SSLv3) # NoncompliantCompliant solution
-+import ssl context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) @@ -70,13 +70,13 @@Use TLS v1.2 or TLS v1.3
How to fix it in OpenSSL
Code examples
Noncompliant code example
-+from OpenSSL import SSL SSL.Context(SSL.SSLv3_METHOD) # NoncompliantCompliant solution
-+from OpenSSL import SSL context = SSL.Context(SSL.TLS_SERVER_METHOD) diff --git a/python-checks/src/main/resources/org/sonar/l10n/py/rules/python/S4830.html b/python-checks/src/main/resources/org/sonar/l10n/py/rules/python/S4830.html index de1a99505a..70d059030f 100644 --- a/python-checks/src/main/resources/org/sonar/l10n/py/rules/python/S4830.html +++ b/python-checks/src/main/resources/org/sonar/l10n/py/rules/python/S4830.html @@ -24,7 +24,7 @@Code examples
Certificate validation is not enabled by default when
_create_unverified_context
is used. It is recommended to use_create_default_https_context
instead to create a secure context that validates certificates.Noncompliant code example
-+import ssl ctx1 = ssl._create_unverified_context() # Noncompliant @@ -34,7 +34,7 @@Noncompliant code example
ctx3.verify_mode = ssl.CERT_NONE # NoncompliantCompliant solution
-+import ssl ctx = ssl.create_default_context() @@ -67,7 +67,7 @@Noncompliant code example
ctx2.set_verify(SSL.VERIFY_NONE, verify_callback) # NoncompliantCompliant solution
-+from OpenSSL import SSL ctx = SSL.Context(SSL.TLSv1_2_METHOD) @@ -91,13 +91,13 @@Code examples
The certificate validation gets disabled by setting
verify
toFalse
. To enable validation set the value toTrue
or do not setverify
at all to use the secure default value.Noncompliant code example
-+import requests requests.request('GET', 'https://example.com', verify=False) # NoncompliantCompliant solution
-+import requests # By default, certificate validation is enabled diff --git a/python-checks/src/main/resources/org/sonar/l10n/py/rules/python/S5542.html b/python-checks/src/main/resources/org/sonar/l10n/py/rules/python/S5542.html index dc103083e2..890db491c2 100644 --- a/python-checks/src/main/resources/org/sonar/l10n/py/rules/python/S5542.html +++ b/python-checks/src/main/resources/org/sonar/l10n/py/rules/python/S5542.html @@ -30,13 +30,13 @@How to fix it in PyCrypto
Code examples
Noncompliant code example
Example with a symmetric cipher, AES:
-+from Crypto.Cipher import AES AES.new(key, AES.MODE_ECB) # NoncompliantExample with an asymmetric cipher, RSA:
-+from Crypto.Cipher import PKCS1_v1_5 PKCS1_v1_5.new(key) # Noncompliant @@ -44,13 +44,13 @@Noncompliant code example
Compliant solution
Since PyCrypto is not supported anymore, another library should be used. In the current context, Cryptodome uses a similar API.
For the AES symmetric cipher, use the GCM mode:
-+from Crypto.Cipher import AES AES.new(key, AES.MODE_GCM)For the RSA asymmetric cipher, use the Optimal Asymmetric Encryption Padding (OAEP):
-+from Crypto.Cipher import PKCS1_OAEP PKCS1_OAEP.new(key) @@ -167,14 +167,14 @@How to fix it in Cryptodome
Code examples
Noncompliant code example
Example with a symmetric cipher, AES:
-+from Crypto.Cipher import AES # pycryptodome from Cryptodome.Cipher import AES # pycryptodomex AES.new(key, AES.MODE_ECB) # NoncompliantExample with an asymmetric cipher, RSA:
-+from Crypto.Cipher import PKCS1_V1_5 # pycryptodome from Cryptodome.Cipher import PKCS1_V1_5 # pycryptodomex @@ -182,14 +182,14 @@Noncompliant code example
Compliant solution
For the AES symmetric cipher, use the GCM mode:
-+from Crypto.Cipher import AES # pycryptodome from Cryptodome.Cipher import AES # pycryptodomex AES.new(key, AES.MODE_GCM)For the RSA asymmetric cipher, use the Optimal Asymmetric Encryption Padding (OAEP):
-+from Crypto.Cipher import PKCS1_V1_5 # pycryptodome from Cryptodome.Cipher import PKCS1_V1_5 # pycryptodomex @@ -217,14 +217,14 @@For RSA: use the OAEP scheme
How to fix it in pyDes
Code examples
Noncompliant code example
-+import pyDes pyDes.des(key) # NoncompliantCompliant solution
Since pyDes only provides DES, it is recommended to use another library like pyca.
-+from cryptography.hazmat.primitives.ciphers import ( Cipher, algorithms, diff --git a/python-checks/src/main/resources/org/sonar/l10n/py/rules/python/S5547.html b/python-checks/src/main/resources/org/sonar/l10n/py/rules/python/S5547.html index 0fbb173d62..6324c1eeb5 100644 --- a/python-checks/src/main/resources/org/sonar/l10n/py/rules/python/S5547.html +++ b/python-checks/src/main/resources/org/sonar/l10n/py/rules/python/S5547.html @@ -49,14 +49,14 @@How to fix it in pyca
Code examples
The following code contains examples of algorithms that are not considered highly resistant to cryptanalysis and thus should be avoided.
Noncompliant code example
-+from cryptography.hazmat.primitives.ciphers import Cipher, algorithms from cryptography.hazmat.backends import default_backend cipher = Cipher(algorithms.TripleDES(key), mode=None, backend=default_backend()) # NoncompliantCompliant solution
-+from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes from cryptography.hazmat.backends import default_backend @@ -71,14 +71,14 @@How to fix it in PyCrypto
Code examples
The following code contains examples of algorithms that are not considered highly resistant to cryptanalysis and thus should be avoided.
Noncompliant code example
-+from Crypto.Cipher import DES cipher = DES.new(key) # NoncompliantCompliant solution
PyCrypto is deprecated, thus it is recommended to use another library like pyca.
-+from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes from cryptography.hazmat.backends import default_backend @@ -93,14 +93,14 @@How to fix it in pyDes
Code examples
The following code contains examples of algorithms that are not considered highly resistant to cryptanalysis and thus should be avoided.
Noncompliant code example
-+import pyDes cipher = pyDes.des(key) # NoncompliantCompliant solution
Since pyDes only provides DES, it is recommended to use another library like pyca.
-+from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes from cryptography.hazmat.backends import default_backend diff --git a/python-checks/src/main/resources/org/sonar/l10n/py/rules/python/S5659.html b/python-checks/src/main/resources/org/sonar/l10n/py/rules/python/S5659.html index b6a42101c7..1766690ba2 100644 --- a/python-checks/src/main/resources/org/sonar/l10n/py/rules/python/S5659.html +++ b/python-checks/src/main/resources/org/sonar/l10n/py/rules/python/S5659.html @@ -62,13 +62,13 @@How to fix it in python-jwt
Code examples
The following code contains an example of JWT decoding without verification of the signature.
Noncompliant code example
-+import python_jwt as jwt jwt.process_jwt(token) # NoncompliantCompliant solution
-+import python_jwt as jwt jwt.process_jwt(token) diff --git a/python-checks/src/main/resources/org/sonar/l10n/py/rules/python/S6317.html b/python-checks/src/main/resources/org/sonar/l10n/py/rules/python/S6317.html index 2c8e3e0e30..49a94feb2b 100644 --- a/python-checks/src/main/resources/org/sonar/l10n/py/rules/python/S6317.html +++ b/python-checks/src/main/resources/org/sonar/l10n/py/rules/python/S6317.html @@ -1,161 +1,32 @@ +Within IAM, identity-based policies grant permissions to users, groups, or roles, and enable specific actions to be performed on designated +resources. When an identity policy inadvertently grants more privileges than intended, certain users or roles might be able to perform more actions +than expected. This can lead to potential security risks, as it enables malicious users to escalate their privileges from a lower level to a higher +level of access.
Why is this an issue?
AWS Identity and Access Management (IAM) is the service that defines access to AWS resources. One of the core components of IAM is the policy -which, when attached to an identity or a resource, defines its permissions. Policies granting permission to an Identity (a User, a Group or Role) are -called identity-based policies. They add the ability to an identity to perform a predefined set of actions on a list of resources.
-Here is an example of a policy document defining a limited set of permission that grants a user the ability to manage his own access keys.
--{ - "Version": "2012-10-17", - "Statement": [ - { - "Action": [ - "iam:CreateAccessKey", - "iam:DeleteAccessKey", - "iam:ListAccessKeys", - "iam:UpdateAccessKey" - ], - "Resource": "arn:aws:iam::245500951992:user/${aws:username}", - "Effect": "Allow", - "Sid": "AllowManageOwnAccessKeys" - } - ] -} --Privilege escalation generally happens when an identity policy gives an identity the ability to grant more privileges than the ones it already has. -Here is another example of a policy document that hides a privilege escalation. It allows an identity to generate a new access key for any user from -the account, including users with high privileges.
--{ - "Version": "2012-10-17", - "Statement": [ - { - "Action": [ - "iam:CreateAccessKey", - "iam:DeleteAccessKey", - "iam:ListAccessKeys", - "iam:UpdateAccessKey" - ], - "Resource": "*", - "Effect": "Allow", - "Sid": "AllowManageOwnAccessKeys" - } - ] -} --Although it looks like it grants a limited set of permissions, this policy would, in practice, give the highest privileges to the identity it’s -attached to.
-Privilege escalation is a serious issue as it allows a malicious user to easily escalate to a high privilege identity from a low privilege identity -it took control of.
-The example above is just one of many permission escalation vectors. Here is the list of vectors that the rule can detect:
-
Vector name | -Summary | -
---|---|
Create Policy Version |
- Create a new IAM policy and set it as default |
-
Set Default Policy Version |
- Set a different IAM policy version as default |
-
Create AccessKey |
- Create a new access key for any user |
-
Create Login Profile |
- Create a login profile with a password chosen by the attacker |
-
Update Login Profile |
- Update the existing password with one chosen by the attacker |
-
Attach User Policy |
- Attach a permissive IAM policy like "AdministratorAccess" to a user the attacker controls |
-
Attach Group Policy |
- Attach a permissive IAM policy like "AdministratorAccess" to a group containing a user the attacker controls |
-
Attach Role Policy |
- Attach a permissive IAM policy like "AdministratorAccess" to a role that can be assumed by the user the attacker controls |
-
Put User Policy |
- Alter the existing inline IAM policy from a user the attacker controls |
-
Put Group Policy |
- Alter the existing inline IAM policy from a group containing a user that the attacker controls |
-
Put Role Policy |
- Alter an existing inline IAM role policy. The rule will then be assumed by the user that the attacker controls |
-
Add User to Group |
- Add a user that the attacker controls to a group that has a larger range of permissions |
-
Update Assume Role Policy |
- Update a role’s "AssumeRolePolicyDocument" to allow a user the attacker controls to assume it |
-
EC2 |
- Create an EC2 instance that will execute with high privileges |
-
Lambda Create and Invoke |
- Create a Lambda function that will execute with high privileges and invoke it |
-
Lambda Create and Add Permission |
- Create a Lambda function that will execute with high privileges and grant permission to invoke it to a user or a service |
-
Lambda triggered with an external event |
- Create a Lambda function that will execute with high privileges and link it to an external event |
-
Update Lambda code |
- Update the code of a Lambda function executing with high privileges |
-
CloudFormation |
- Create a CloudFormation stack that will execute with high privileges |
-
Data Pipeline |
- Create a Pipeline that will execute with high privileges |
-
Glue Development Endpoint |
- Create a Glue Development Endpoint that will execute with high privileges |
-
Update Glue Dev Endpoint |
- Update the associated SSH key for the Glue endpoint |
-
The general recommendation to protect against privilege escalation is to restrict the resources to which sensitive permissions are granted. The -first example above is a good demonstration of sensitive permissions being used with a narrow scope of resources and where no privilege escalation is -possible.
-The following policy allows an attacker to update the code of any Lambda function. An attacker can achieve privilege escalation by altering the -code of a Lambda that executes with high privileges.
-+which, when attached to an identity or a resource, defines its permissions. Policies granting permission to an identity (a user, a group or a role) +are called identity-based policies. They add the ability to an identity to perform a predefined set of actions on a list of resources. +For such policies, it is easy to define very broad permissions (by using wildcard
+"*"
permissions for example.) This is especially +true if it is not yet clear which permissions will be required for a specific workload or use case. However, it is important to limit the amount of +permissions that are granted and the amount of resources to which these permissions are granted. Doing so ensures that there are no users or roles +that have more permissions than they need.If this is not done, it can potentially carry security risks in the case that an attacker gets access to one of these identities.
+What is the potential impact?
+AWS IAM policies that contain overly broad permissions can lead to privilege escalation by granting users more access than necessary. They may be +able to perform actions beyond their intended scope.
+Privilege escalation
+When IAM policies are too permissive, they grant users more privileges than necessary, allowing them to perform actions that they should not be +able to. This can be exploited by attackers to gain unauthorized access to sensitive resources and perform malicious activities.
+For example, if an IAM policy grants a user unrestricted access to all S3 buckets in an AWS account, the user can potentially read, write, and +delete any object within those buckets. If an attacker gains access to this user’s credentials, they can exploit this overly permissive policy to +exfiltrate sensitive data, modify or delete critical files, or even launch further attacks within the AWS environment. This can have severe +consequences, such as data breaches, service disruptions, or unauthorized access to other resources within the AWS account.
+How to fix it in AWS CDK
+Code examples
+In this example, the IAM policy allows an attacker to update the code of any Lambda function. An attacker can achieve privilege escalation by +altering the code of a Lambda that executes with high privileges.
+Noncompliant code example
+from aws_cdk.aws_iam import Effect, PolicyDocument, PolicyStatement PolicyDocument( @@ -168,9 +39,9 @@-Noncompliant code example
] )Compliant solution
-Narrow the policy such that only updates to the code of certain Lambda functions are allowed.
-+Compliant solution
+The policy is narrowed such that only updates to the code of certain Lambda functions (without high privileges) are allowed.
+from aws_cdk.aws_iam import Effect, PolicyDocument, PolicyStatement PolicyDocument( @@ -185,11 +56,27 @@+Compliant solution
] )How does this work?
+Principle of least privilege
+When creating IAM policies, it is important to adhere to the principle of least privilege. This means that any user or role should only be granted +enough permissions to perform the tasks that they are supposed to, and nothing else.
+To successfully implement this, it is easier to start from nothing and gradually build up all the needed permissions. When starting from a policy +with overly broad permissions which is made stricter at a later time, it can be harder to ensure that there are no gaps that might be forgotten about. +In this case, it might be useful to monitor the users or roles to verify which permissions are used.
Resources
+Documentation
+
Instead, the preferred best practice to generate reproducible pseudorandom numbers is to instantiate a numpy.random.Generator
object
with a seed and reuse it in different parts of the code. This avoids the reliance on a global state. Whenever a new seed is needed, a new generator
may be created instead of mutating a global state.
Below is the list of legacy functions and their alternatives:
+Legacy function name |
+ numpy.random.Generator alternative |
+
numpy.random.RandomState.seed |
+ numpy.random.default_rng |
+
numpy.random.RandomState.rand |
+ numpy.random.Generator.random |
+
numpy.random.RandomState.randn |
+ numpy.random.Generator.standard_normal |
+
numpy.random.RandomState.randint |
+ numpy.random.Generator.integers |
+
numpy.random.RandomState.random_integers |
+ numpy.random.Generator.integers |
+
numpy.random.RandomState.random_sample |
+ numpy.random.Generator.random |
+
numpy.random.RandomState.choice |
+ numpy.random.Generator.choice |
+
numpy.random.RandomState.bytes |
+ numpy.random.Generator.bytes |
+
numpy.random.RandomState.shuffle |
+ numpy.random.Generator.shuffle |
+
numpy.random.RandomState.permutation |
+ numpy.random.Generator.permutation |
+
numpy.random.RandomState.beta |
+ numpy.random.Generator.beta |
+
numpy.random.RandomState.binomial |
+ numpy.random.Generator.binomial |
+
numpy.random.RandomState.chisquare |
+ numpy.random.Generator.chisquare |
+
numpy.random.RandomState.dirichlet |
+ numpy.random.Generator.dirichlet |
+
numpy.random.RandomState.exponential |
+ numpy.random.Generator.exponential |
+
numpy.random.RandomState.f |
+ numpy.random.Generator.f |
+
numpy.random.RandomState.gamma |
+ numpy.random.Generator.gamma |
+
numpy.random.RandomState.geometric |
+ numpy.random.Generator.geometric |
+
numpy.random.RandomState.gumbel |
+ numpy.random.Generator.gumbel |
+
numpy.random.RandomState.hypergeometric |
+ numpy.random.Generator.hypergeometric |
+
numpy.random.RandomState.laplace |
+ numpy.random.Generator.laplace |
+
numpy.random.RandomState.logistic |
+ numpy.random.Generator.logistic |
+
numpy.random.RandomState.lognormal |
+ numpy.random.Generator.lognormal |
+
numpy.random.RandomState.logseries |
+ numpy.random.Generator.logseries |
+
numpy.random.RandomState.multinomial |
+ numpy.random.Generator.multinomial |
+
numpy.random.RandomState.multivariate_normal |
+ numpy.random.Generator.multivariate_normal |
+
numpy.random.RandomState.negative_binomial |
+ numpy.random.Generator.negative_binomial |
+
numpy.random.RandomState.noncentral_chisquare |
+ numpy.random.Generator.noncentral_chisquare |
+
numpy.random.RandomState.noncentral_f |
+ numpy.random.Generator.noncentral_f |
+
numpy.random.RandomState.normal |
+ numpy.random.Generator.normal |
+
numpy.random.RandomState.pareto |
+ numpy.random.Generator.pareto |
+
numpy.random.RandomState.poisson |
+ numpy.random.Generator.poisson |
+
numpy.random.RandomState.power |
+ numpy.random.Generator.power |
+
numpy.random.RandomState.rayleigh |
+ numpy.random.Generator.rayleigh |
+
numpy.random.RandomState.standard_cauchy |
+ numpy.random.Generator.standard_cauchy |
+
numpy.random.RandomState.standard_exponential |
+ numpy.random.Generator.standard_exponential |
+
numpy.random.RandomState.standard_gamma |
+ numpy.random.Generator.standard_gamma |
+
numpy.random.RandomState.standard_normal |
+ numpy.random.Generator.standard_normal |
+
numpy.random.RandomState.standard_t |
+ numpy.random.Generator.standard_t |
+
numpy.random.RandomState.triangular |
+ numpy.random.Generator.triangular |
+
numpy.random.RandomState.uniform |
+ numpy.random.Generator.uniform |
+
numpy.random.RandomState.vonmises |
+ numpy.random.Generator.vonmises |
+
numpy.random.RandomState.wald |
+ numpy.random.Generator.wald |
+
numpy.random.RandomState.weibull |
+ numpy.random.Generator.weibull |
+
numpy.random.RandomState.zipf |
+ numpy.random.Generator.zipf |
+
numpy.random.beta |
+ numpy.random.Generator.beta |
+
numpy.random.binomial |
+ numpy.random.Generator.binomial |
+
numpy.random.bytes |
+ numpy.random.Generator.bytes |
+
numpy.random.chisquare |
+ numpy.random.Generator.chisquare |
+
numpy.random.choice |
+ numpy.random.Generator.choice |
+
numpy.random.dirichlet |
+ numpy.random.Generator.dirichlet |
+
numpy.random.exponential |
+ numpy.random.Generator.exponential |
+
numpy.random.f |
+ numpy.random.Generator.f |
+
numpy.random.gamma |
+ numpy.random.Generator.gamma |
+
numpy.random.geometric |
+ numpy.random.Generator.geometric |
+
numpy.random.gumbel |
+ numpy.random.Generator.gumbel |
+
numpy.random.hypergeometric |
+ numpy.random.Generator.hypergeometric |
+
numpy.random.laplace |
+ numpy.random.Generator.laplace |
+
numpy.random.logistic |
+ numpy.random.Generator.logistic |
+
numpy.random.lognormal |
+ numpy.random.Generator.lognormal |
+
numpy.random.logseries |
+ numpy.random.Generator.logseries |
+
numpy.random.multinomial |
+ numpy.random.Generator.multinomial |
+
numpy.random.multivariate_normal |
+ numpy.random.Generator.multivariate_normal |
+
numpy.random.negative_binomial |
+ numpy.random.Generator.negative_binomial |
+
numpy.random.noncentral_chisquare |
+ numpy.random.Generator.noncentral_chisquare |
+
numpy.random.noncentral_f |
+ numpy.random.Generator.noncentral_f |
+
numpy.random.normal |
+ numpy.random.Generator.normal |
+
numpy.random.pareto |
+ numpy.random.Generator.pareto |
+
numpy.random.permutation |
+ numpy.random.Generator.permutation |
+
numpy.random.poisson |
+ numpy.random.Generator.poisson |
+
numpy.random.power |
+ numpy.random.Generator.power |
+
numpy.random.rand |
+ numpy.random.Generator.random |
+
numpy.random.randint |
+ numpy.random.Generator.integers |
+
numpy.random.randn |
+ numpy.random.Generator.standard_normal |
+
numpy.random.random |
+ numpy.random.Generator.random |
+
numpy.random.random_integers |
+ numpy.random.Generator.integers |
+
numpy.random.random_sample |
+ numpy.random.Generator.random |
+
numpy.random.ranf |
+ numpy.random.Generator.random |
+
numpy.random.rayleigh |
+ numpy.random.Generator.rayleigh |
+
numpy.random.sample |
+ numpy.random.Generator.random |
+
numpy.random.seed |
+ numpy.random.default_rng |
+
numpy.random.shuffle |
+ numpy.random.Generator.shuffle |
+
numpy.random.standard_cauchy |
+ numpy.random.Generator.standard_cauchy |
+
numpy.random.standard_exponential |
+ numpy.random.Generator.standard_exponential |
+
numpy.random.standard_gamma |
+ numpy.random.Generator.standard_gamma |
+
numpy.random.standard_normal |
+ numpy.random.Generator.standard_normal |
+
numpy.random.standard_t |
+ numpy.random.Generator.standard_t |
+
numpy.random.triangular |
+ numpy.random.Generator.triangular |
+
numpy.random.uniform |
+ numpy.random.Generator.uniform |
+
numpy.random.vonmises |
+ numpy.random.Generator.vonmises |
+
numpy.random.wald |
+ numpy.random.Generator.wald |
+
numpy.random.weibull |
+ numpy.random.Generator.weibull |
+
numpy.random.zipf |
+ numpy.random.Generator.zipf |
+
To fix this issue, replace usages of numpy.random.RandomState
to numpy.random.Generator
.
object
and could hold any Python objects.
One of the characteristics of NumPy arrays is homogeneity, meaning all its elements are of the same type. Creating an array of objects allows the user to create heterogeneous array without raising any errors and creating such an array can lead to bugs further in the program.
-+arr = np.array(x**2 for x in range(10)) arr.reshape(1) diff --git a/python-checks/src/main/resources/org/sonar/l10n/py/rules/python/S6729.html b/python-checks/src/main/resources/org/sonar/l10n/py/rules/python/S6729.html index eec1ab122c..d83a0744de 100644 --- a/python-checks/src/main/resources/org/sonar/l10n/py/rules/python/S6729.html +++ b/python-checks/src/main/resources/org/sonar/l10n/py/rules/python/S6729.html @@ -37,7 +37,7 @@How to fix it
Code examples
Noncompliant code example
-+import numpy as np def bigger_than_two(): diff --git a/python-checks/src/main/resources/org/sonar/l10n/py/rules/python/S6730.json b/python-checks/src/main/resources/org/sonar/l10n/py/rules/python/S6730.json index 8133e2a396..61c71e1365 100644 --- a/python-checks/src/main/resources/org/sonar/l10n/py/rules/python/S6730.json +++ b/python-checks/src/main/resources/org/sonar/l10n/py/rules/python/S6730.json @@ -6,7 +6,10 @@ "func": "Constant\/Issue", "constantCost": "5min" }, - "tags": [], + "tags": [ + "numpy", + "data-science" + ], "defaultSeverity": "Major", "ruleSpecification": "RSPEC-6730", "sqKey": "S6730", diff --git a/sonarpedia.json b/sonarpedia.json index 8abdf954f9..79fde49fb5 100644 --- a/sonarpedia.json +++ b/sonarpedia.json @@ -3,7 +3,7 @@ "languages": [ "PY" ], - "latest-update": "2023-08-17T11:13:24.565991160Z", + "latest-update": "2023-09-25T08:37:06.879611Z", "options": { "no-language-in-filenames": true, "preserve-filenames": true