#python
Rulesets (26)
Default ruleset for Python, curated by Semgrep.
Use Semgrep as a universal linter to identify vulnerabilities in your code base with the bandit (https://github.com/PyCQA/bandit) rule pack.

Default ruleset for Django, by Semgrep

Default ruleset for Flask, by Semgrep.
A collection of opinionated rules for best practices in popular languages. Recommended for users who want really strict coding standards.

Secure defaults for XSS prevention
Find common bugs, errors, and logic issues in popular languages.

Ensure your code communicates over encrypted channels instead of plaintext.
Rules for detecting secrets checked into version control

Ruleset accompanying Semgrep OWASP presentation.

Secure defaults for XSS prevention in Django

Rules for OWASP security checks for python
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).
Written by the Trail of Bits security experts. See https://github.com/trailofbits/semgrep-rules for more.

Omni pack for insecure transport rules
Leverage all Gitlab provided rules with the gitlab rulepack.
Use Semgrep as a universal linter to identify vulnerabilities in your code base with the bandit (https://github.com/PyCQA/bandit) rule pack.

Ensure your code communicates over encrypted channels instead of plaintext.

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.

Ruleset for OWASP SF

Secure defaults for Command injection prevention

Python Meetup Check Ruleset
Rules (626)

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 data rendered directly to the end user via 'HttpResponse' or a similar object. This bypasses Django's built-in cross-site scripting (XSS) defenses and could result in an XSS vulnerability. Use Django's template engine to safely render HTML.
Insufficient permissions to view rule definition. This rule is only visible to logged in users. Log in to see this rule.
Try, Except, Pass
Probable insecure usage of temp file/directory.
Consider possible security implications associated with etree module.
Using various methods to parse untrusted XML data is known to be vulnerable to XML attacks. Replace vulnerable imports with the equivalent defusedxml package, or make sure defusedxml.defuse_stdlib() is called.
'mark_safe()' is used to mark a string as "safe" for HTML output. This disables escaping and could therefore subject the content to XSS attacks. Use 'django.utils.html.format_html()' to build HTML for rendering instead.

You should use ITEM.user_id rather than ITEM.user.id to prevent running an extra query.

These APIs are deprecated in Bokeh see https://docs.bokeh.org/en/latest/docs/releases.html#api-deprecations

Use `click.secho($X)` instead. It combines click.echo() and click.style().

You are using environment variables inside django app. Use `django-environ` as it a better alternative for deployment.

The weak argument to django.dispatch.signals.Signal.disconnect() is removed in Django 2.0.

QuerySet.extra' does not provide safeguards against SQL injection and requires very careful use. SQL injection can lead to critical data being stolen by attackers. Instead of using '.extra', use the Django ORM and parameterized queries such as `People.objects.get(name='Bob')`.

The django.forms.extras package is removed in Django 2.0.

The assignment_tag helper is removed in Django 2.0.

The host argument to assertRedirects is removed in Django 2.0.

Detected a django model `$MODEL` is not calling super().save() inside of the save method.

If a text field declares unique=True and blank=True, null=True must also be set to avoid unique constraint violations when saving multiple objects with blank values.

Found a FloatField used for variable $F. Use DecimalField for currency fields to avoid float-rounding errors.

Looks like you need to determine the number of records. Django provides the count() method which is more efficient than .len(). See https://docs.djangoproject.com/en/3.0/ref/models/querysets/

Looks like you are only accessing first element of an ordered QuerySet. Use `latest()` or `earliest()` instead. See https://docs.djangoproject.com/en/3.0/ref/models/querysets/#django.db.models.query.QuerySet.latest

code after return statement will not be executed

`return` only makes sense inside a function

Annotations passed to `typing.get_type_hints` are evaluated in `globals` and `locals` namespaces. Make sure that no arbitrary value can be written as the annotation and passed to `typing.get_type_hints` function.

if block checks for the same condition on both branches (`$X`)

Useless if statement; both blocks have the same body

.delete().where(...) results in a no-op in SQLAlchemy unless the command is executed, use .filter(...).delete() instead.

Using QUERY.count() instead of len(QUERY.all()) sends less data to the client since the SQLAlchemy method is performed server-side.

Rather than adding one element at a time, consider batch loading to improve performance.

This rule is deprecated.
Consider possible security implications associated with subprocess module.
The application was found using an unsafe version of `yaml` load which is vulnerable to deserialization attacks. Deserialization attacks exploit the process of reading serialized data and turning it back into an object. By constructing malicious objects and serializing them, an adversary may attempt to: - Inject code that is executed upon object construction, which occurs during the deserialization process. - Exploit mass assignment by including fields that are not normally a part of the serialized data but are read in during deserialization. To remediate this issue, use `safe_load()` or call `yaml.load()` with the `Loader` argument set to `yaml.SafeLoader`. Example loading YAML using `safe_load`: ``` import yaml # Use safe_load to load data into an intermediary object intermediary_object = yaml.safe_load("""user: name: 'test user'""" ) # Create our real object, copying over only the necessary fields user_object = {'user': { # Assign the deserialized data from intermediary object 'name': intermediary_object['user']['name'], # Add in protected data in object definition (or set it from a class constructor) 'is_admin': False, } } # Work with user_object # ... ``` For more details on deserialization attacks in general, see OWASP's guide: - https://cheatsheetseries.owasp.org/cheatsheets/Deserialization_Cheat_Sheet.html

Hardcoded variable `TESTING` detected. Use environment variables or config files instead

Hardcoded variable `SECRET_KEY` detected. Use environment variables or config files instead

Hardcoded variable `ENV` detected. Set this by using FLASK_ENV environment variable

Hardcoded variable `DEBUG` detected. Set this by using FLASK_DEBUG environment variable
Consider possible security implications associated with httpoxy module.
Using various methods to parse untrusted XML data is known to be vulnerable to XML attacks. Replace vulnerable imports with the equivalent defusedxml package, or make sure defusedxml.defuse_stdlib() is called.
Consider possible security implications associated with xmlrpclib module.

$X == $X is a useless equality check

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

The `flask.request.host` is used to construct an HTTP request. This can lead to host header injection issues. Vulnerabilities that generally occur due to this issue are authentication bypasses, password reset issues, Server-Side-Request-Forgery (SSRF), and many more. It is recommended to validate the URL before passing it to a request library, or using application logic such as authentication or password resets.

Accessing request object inside a route handle for HTTP GET command will throw due to missing request body.

Looks like `$R` is a flask function handler that registered to two different routes. This will cause a runtime error

deprecated Flask API

Found user-controlled request data passed into HttpResponse. This could be vulnerable to XSS, leading to attackers gaining access to user cookies and protected information. Ensure that the request data is properly escaped or sanitzed.

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. Otherwise, use templates (`flask.render_template`) which will safely render HTML instead.

Avoid using `torch.Tensor()` to directly create a tensor for efficiency and proper parsing
Possible hardcoded password

This expression is always True: `$X == $X` or `$X != $X`. If testing for floating point NaN, use `math.isnan($X)`, or `cmath.isnan($X)` if the number is complex.

path for `$URL` is uselessly assigned twice

The path for `$URL` is assigned once to view `$VIEW` and once to `$DIFFERENT_VIEW`, which can lead to unexpected behavior. Verify what the intended target view is and delete the other route.

path for `$URL` is assigned twice with different names

The name `$NAME` is used for both `$URL` and `$OTHER_URL`, which can lead to unexpected behavior when using URL reversing. Pick a unique name for each path.
The application may be vulnerable to a path traversal if it extracts untrusted archive files. This vulnerability is colloquially known as 'Zip Slip'. Archive files may contain folders which, when extracted, may write outside of the intended directory. This is exploited by including path traversal characters such as `../../other/directory` to overwrite or place files in system or application directories. Extra care must be taken when extracting archive files as there are numerous concerns: - If possible, generate unique filenames instead of using the archives file names, as it may be possible for users to overwrite files if the filenames are the same. - Validate file paths are written with a prefixed, known trusted directory. - Only process regular files and not symbolic links, as some applications may attempt to read/follow the symbolic link, leading to arbitrary file read / write vulnerabilities. Example of securely processing an archive file: ``` import tarfile import uuid # import os tar = tarfile.open('some.tar') # Max number of allowed files in our archive max_files = 10 # Max size for all files in archive max_size = 1024 * 1024 * 10 # 10MB # Max size per file in archive max_file_size = 1024 * 1024 # 1MB # Validate number of files in archive if len(tar.getmembers()) > max_files: raise Exception("Too many files in archive") total_size = 0 # Loop over all files to see if we exceed max size # if so, do not process any of them. for f in tar.getmembers(): total_size += f.size if total_size >= max_size: raise Exception("Archive files exceeded max file size") # Iterate over files now that we know the total size is within limits for f in tar.getmembers(): # Internally this calls TarInfo.isreg() which ensures # the file is a regular file and not a sym link or directory if not f.isfile(): continue # Optional, set a limit on each file size if f.size > max_file_size: raise Exception(f"File {f.name} too large: {f.size}") # If original names are required, ensure that only the # filename is used: # filename = os.path.basename(f.name) # More secure, generate a UUID4 value instead filename = uuid.uuid4().hex # Reset the archive filename to the basename # Newer versions of python (3.11.4+) should use: # new_tar = old_tar.replace(name=...new name...) f.name = filename # Extract the file into a restricted directory, with our # own user's attributes, not the file from the archive tar.extract(f, '/opt/app/restricted/', set_attrs=False) ``` For more information on tarfile see: - https://docs.python.org/3/library/tarfile.html
An IPMI-related module is being imported. IPMI is considered insecure. Use an encrypted protocol.
Possible hardcoded password
Detected SHA1 hash algorithm which is considered insecure. SHA1 is not collision resistant and is therefore not suitable as a cryptographic signature. Use SHA256 or SHA3 instead.
Cryptographic algorithms provide many different modes of operation, only some of which provide message integrity. Without message integrity it could be possible for an adversary to attempt to tamper with the ciphertext which could lead to compromising the encryption key. Newer algorithms apply message integrity to validate ciphertext has not been tampered with. Instead of using an algorithm that requires configuring a cipher mode, an algorithm that has built-in message integrity should be used. Consider using `ChaCha20Poly1305` or `AES-256-GCM` instead. For older applications that don't have support for `ChaCha20Poly1305`, `AES-256-GCM` is recommended, however it has many drawbacks: - Slower than `ChaCha20Poly1305`. - Catastrophic failure if nonce values are reused. Example using `ChaCha20Poly1305`: ``` import os # Import ChaCha20Poly1305 from cryptography from cryptography.hazmat.primitives.ciphers.aead import ChaCha20Poly1305 # Our plaintext to encrypt plain_text = b"Secret text to encrypt" # We do not require authenticated but unencrypted data, so set to None aad = None # Generate a secure key key = ChaCha20Poly1305.generate_key() # Create a new ChaCha20Poly1305 instance with our secure key chacha = ChaCha20Poly1305(key) # Note: nonce values _must_ be regenerated every time they are used. nonce = os.urandom(12) # Encrypt our plaintext cipher_text = chacha.encrypt(nonce, plain_text, aad) # Decrypt the plain text using the nonce and cipher_text chacha.decrypt(nonce, cipher_text, aad) ``` Example using `AESGCM`: ``` import os # Import AESGCM from cryptography from cryptography.hazmat.primitives.ciphers.aead import AESGCM # Our plaintext to encrypt plain_text = b"Secret text to encrypt" # We do not require authenticated but unencrypted data, so set to None aad = None # Generate a secure key key = AESGCM.generate_key(bit_length=128) # Create a new AESGCM instance with our secure key aesgcm = AESGCM(key) # Note: nonce values _must_ be regenerated every time they are used. nonce = os.urandom(12) # Encrypt our plaintext cipher_text = aesgcm.encrypt(nonce, plain_text, aad) # Decrypt the plain text using the nonce and cipher_text aesgcm.decrypt(nonce, cipher_text, aad) ``` For more information on the cryptography module see: - https://cryptography.io/en/latest/
The application was found using an FTP library. As FTP does not provide encryption, it is strongly recommended that any file transfers be done over a more secure transport such as SSH. The [paramiko](https://www.paramiko.org/) library can be used with an SCP module to allow secure file transfers. Example using `paramiko` SSH client and the `scp` module: ``` import paramiko import scp # Create an SSH client with paramiko.SSHClient() as ssh: # Load the system host keys so we can confirm the # host we are connecting to is legitimate ssh.load_system_host_keys('/home/appuser/.ssh/known_hosts') # Connect to the remote host using our SSH private key ssh.connect(hostname='example.org', port=22, username='appuser', key_filename='/home/appuser/.ssh/private_key') # Create an SCP client with the ssh transport and copy files with scp.SCPClient(ssh.get_transport()) as secure_copy: secure_copy.get('remote/test.file', 'local/test.file') secure_copy.put('local/some.file', 'remote/some.file') ``` For more information on the paramiko module see: - https://www.paramiko.org/ For more information on the scp module see: - https://github.com/jbardin/scp.py
The HTTPSConnection API has changed frequently with minor releases of Python.Ensure you are using the API for your version of Python securely. For example, Python 3 versions prior to 3.4.3 will not verify SSL certificates by default.
Telnet does not encrypt communications. Use SSH instead.
The Python `os` `tempnam|tmpnam` functions are vulnerable to symlink attacks
Detected a dynamic value being used with urllib. urllib supports `file://` schemes, so a dynamic value controlled by a malicious actor may allow them to read arbitrary files. Audit uses of urllib calls to ensure user data cannot control the URLs, or consider using the `requests` library instead.
Using various methods to parse untrusted XML data is known to be vulnerable to XML attacks. Replace vulnerable imports with the equivalent defusedxml package.
Using various methods to parse untrusted XML data is known to be vulnerable to XML attacks. Replace vulnerable imports with the equivalent defusedxml package, or make sure defusedxml.defuse_stdlib() is called.
Using various methods to parse untrusted XML data is known to be vulnerable to XML attacks. Replace vulnerable imports with the equivalent defusedxml package, or make sure defusedxml.defuse_stdlib() is called.
functions are being called. FTP is considered insecure. Use SSH/SFTP/SCP orsome other encrypted protocol
Consider possible security implications associated with pickle module.

Found a Flask cookie without secure, httponly, or samesite correctly set. Flask cookies should be handled securely by setting secure=True, httponly=True, and samesite='Lax' in response.set_cookie(...). If these parameters are not properly set, your cookies are not properly protected and are at risk of being stolen by an attacker. Include the 'secure=True', 'httponly=True', samesite='Lax' arguments or set these to be true in the Flask configuration.

Errors should only be logged when handled. The code logs the error and propogates the exception, consider reducing the level to warning or info.

Missing 'encoding' parameter. 'open()' uses device locale encodings by default, corrupting files with special characters. Specify the encoding to ensure cross-platform support when opening files in text mode (e.g. encoding="utf-8").

Synchronous time.sleep in async code will block the event loop and not allow other tasks to execute. Use asyncio.sleep() instead.

Found request data in a call to 'open'. Ensure the request data is validated or sanitized, otherwise it could result in path traversal attacks and therefore sensitive data being leaked. To mitigate, consider using os.path.abspath or os.path.realpath or the pathlib 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.

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.

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.

Having a `break`, `continue`, or `return` in a `finally` block will cause strange behaviors, like exceptions not being caught.

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.
Hardcoded password is used as a default argument to `$FUNC`. This could be dangerous if a real password is not supplied.
SQL Injection is a critical vulnerability that can lead to data or system compromise. By dynamically generating SQL query strings, user input may be able to influence the logic of the SQL statement. This could lead to an adversary accessing information they should not have access to, or in some circumstances, being able to execute OS functionality or code. Replace all dynamically generated SQL queries with parameterized queries. In situations where dynamic queries must be created, never use direct user input, but instead use a map or dictionary of valid values and resolve them using a user supplied key. For example, some database drivers do not allow parameterized queries for `>` or `<` comparison operators. In these cases, do not use a user supplied `>` or `<` value, but rather have the user supply a `gt` or `lt` value. The alphabetical values are then used to look up the `>` and `<` values to be used in the construction of the dynamic query. The same goes for other queries where column or table names are required but cannot be parameterized. The `QuerySet.extra` API method will be deprecated as it a source of SQL Injection vulnerabilities and other problems. This method is especially risky as callers will need to do their own escaping of any parameters that come from user-supplied information. To remediate this issue, do not use `extra` but use other `QuerySet` methods to achieve the same goals. If for some reason this is not feasible, consider using the `RawSQL` method and making sure that all arguments, including user-supplied ones, are only used in `params` While not recommended due to [potential SQL Injection](https://docs.djangoproject.com/en/4.2/ref/models/expressions/#raw-sql-expressions), below is an example using `RawSQL`, passing in user-supplied data as a `param` which will escape the input: ``` # If dealing with integer based user input, restrict the values to integers only using the # path configuration: path('<int:user_supplied_id>/someview/', views.some_view, name='someview'), # views.py def some_view(request, user_supplied_id): # Never use string interpolation in the `sql` parameter. # Never quote the `%s` string format such as `... where id='%s'` as this could lead to SQL Injection. # Pass the user supplied data only in the `params` parameter. for obj in DBObject.objects.all().annotate( val=RawSQL(sql="select id from some_secondary_table where id=%s", params=[user_supplied_id])): # Work with the results from the query # ... ``` For more information on QuerySet see: - https://docs.djangoproject.com/en/4.2/ref/models/querysets/#queryset-api For more information on SQL Injection see OWASP: - https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_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. To remediate this issue, do not use `raw` or `RawSQL` but use other `QuerySet` methods to achieve the same goals. If for some reason this is not feasible, ensure calls including user-supplied data pass it in to the `params` parameter of the `RawSQL` method. While not recommended due to [potential SQL Injection](https://docs.djangoproject.com/en/4.2/ref/models/expressions/#raw-sql-expressions), below is an example using `RawSQL`, passing in user-supplied data as a `param` which will escape the input: ``` # If dealing with integer based user input, restrict the values to integers only using the # path configuration: path('<int:user_supplied_id>/someview/', views.some_view, name='someview'), # views.py def some_view(request, user_supplied_id): # Never use string interpolation in the `sql` parameter. # Never quote the `%s` string format such as `... where id='%s'` as this could lead to SQL Injection. # Pass the user supplied data only in the `params` parameter. for obj in DBObject.objects.all().annotate( val=RawSQL(sql="select id from some_secondary_table where id=%s", params=[user_supplied_id])): # Work with the results from the query # ... ``` For more information on QuerySet see: - https://docs.djangoproject.com/en/4.2/ref/models/querysets/#queryset-api For more information on SQL Injection see OWASP: - https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html
The application was found using mako templates without `default_filters` being passed to the `Template` or `TemplateLookup` constructors. If using in the context of HTML, this could lead to Cross-Site Scripting (XSS) attacks when rendering with user-supplied input. Unfortunately, Jinja2 does not support context-aware escaping, meaning it is insufficient to protect against XSS for the various web contexts. It is important to encode the data depending on the specific context it is used in. There are at least six context types: - Inside HTML tags `<div>context 1</div>` - Inside attributes: `<div class="context 2"></div>` - Inside event attributes `<button onclick="context 3">button</button>` - Inside script blocks: `<script>var x = "context 4"</script>` - Unsafe element HTML assignment: `element.innerHTML = "context 5"` - Inside URLs: `<iframe src="context 6"></iframe><a href="context 6">link</a>` Script blocks alone have multiple ways they need to be encoded. Extra care must be taken if user input is ever output inside of script tags. User input that is displayed within the application must be encoded, sanitized or validated to ensure it cannot be treated as HTML or executed as Javascript code. Care must also be taken to not mix server-side templating with client-side templating, as the server-side templating will not encode things like {{ 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. To handle different contexts, one approach would be to write custom mako filters. Below is an example that escapes or encodes links and potentially malicious script, note this does not include other contexts such as CSS or attributes: ``` # filters.py module: def escape_link(value): bad_link = "#JinjatmplZ" # Block any values that start with // as that could be used to inject # links to third party pages see: https://en.wikipedia.org/wiki/Wikipedia:Protocol-relative_URL if value.startswith('//'): return bad_link # Only allow relative links # if you want to allow links that start with http or ws replace with below: # if not value.startswith('/'): and not value.startswith('http') and not value.startswith('ws') if not value.startswith('/'): return bad_link return value # Create a replacement table js_replacement = str.maketrans({ '\0': "\\u0000", '\t': "\\t", '\n': "\\n", '\v': "\\u000b", '\f': "\\f`", '\r': "\\r", '"': "\\u0022", '`': "\\u0060", '&': "\\u0026", '\'': "\\u0027", '+': "\\u002b", '/': "\\/", '<': "\\u003c", '>': "\\u003e", '\\': "\\\\", '(': "\\u0028", ')': "\\u0029", }) def escape_js(value): # Escape the input for use in <script> context, USE WITH CAUTION # It is strongly recommended to never pass user-supplied input to # the JavaScript context. # Translate any potential characters using our translation table return value.translate(js_replacement) ##################################################################### # main module: # ##################################################################### from mako.template import Template # Define our template, note the calls to our custom filters depending # on context template_text = """ <!DOCTYPE html> <html lang="en"> <head> <title>My Webpage</title> </head> <body> <h1>My Webpage</h1> ${html_context} <a href="${link_context | escape_link}">link</a> <script>${script_context | escape_js}</script> </body> </html> """ # Load our template with default filters and our imported filters for # usage in template files t = Template(template_text, # By default enable the html filter with 'h' default_filters=['h'], # Import our custom filters imports=["from filters import escape_link, escape_js"]) # Render our template print(t.render(html_context="<img src=x onerror=alert(1)>", link_context="/# onclick=alert(1)<script>alert(1)</script>", script_context="alert(1)<img src=x onerror=alert(1)>",) ) ```

The Python 'pickle' module is not secure against maliciously constructed input

The Python 'eval' function is not secure against maliciously constructed input

The Python 'exec' function is not secure against maliciously constructed input

The Python 'os' execution functions are not secure against maliciously constructed input

Detected 'create_subprocess_exec' function with argument tainted by `event` object. If this data can be controlled by a malicious actor, it may be an instance of command injection. Audit the use of this call to ensure it is not controllable by an external resource. You may consider using 'shlex.escape()'.

Detected subprocess function '$LOOP.subprocess_exec' with argument tainted by `event` object. If this data can be controlled by a malicious actor, it may be an instance of command injection. Audit the use of this call to ensure it is not controllable by an external resource. You may consider using 'shlex.escape()'.

Detected SQL statement that is tainted by `event` object. This could lead to SQL injection if the variable is user-controlled and not properly sanitized. In order to prevent SQL injection, use parameterized queries or prepared statements instead. You can use parameterized statements like so: `cursor.execute('SELECT * FROM projects WHERE status = %s', ('active'))`

Detected SQL statement that is tainted by `event` object. This could lead to SQL injection if the variable is user-controlled and not properly sanitized. In order to prevent SQL injection, use parameterized queries or prepared statements instead. You can use parameterized statements like so: `cursor.execute('SELECT * FROM projects WHERE status = %s', 'active')`

Detected SQL statement that is tainted by `event` object. This could lead to SQL injection if the variable is user-controlled and not properly sanitized. In order to prevent SQL injection, use parameterized queries or prepared statements instead. You can use parameterized statements like so: `cursor.execute('SELECT * FROM projects WHERE status = %s', 'active')`

Detected SQL statement that is tainted by `event` object. This could lead to SQL injection if the variable is user-controlled and not properly sanitized. In order to prevent SQL injection, use parameterized queries or prepared statements instead. You can use parameterized statements like so: `cursor.execute('SELECT * FROM projects WHERE status = %s', ('active'))`

Detected SQL statement that is tainted by `event` object. This could lead to SQL injection if the variable is user-controlled and not properly sanitized. In order to prevent SQL injection, use parameterized queries or prepared statements instead. You can use parameterized statements like so: `cursor.execute('SELECT * FROM projects WHERE status = ?', 'active')`

Detected the use of `exec/eval`.This can be dangerous if used to evaluate dynamic content. If this content can be input from outside the program, this may be a code injection vulnerability. Ensure evaluated content is not definable by external sources.

Detected user input flowing into an HTML response. 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.

Avoid using `pickle`, which is known to lead to code execution vulnerabilities. When unpickling, the serialized data could be manipulated to run arbitrary code. Instead, consider serializing the relevant data as JSON or a similar text-based serialization format.

Potential empty AES encryption key. Using an empty key in AES encryption can result in weak encryption and may allow attackers to easily decrypt sensitive data. Ensure that a strong, non-empty key is used for AES encryption.

Detected ARC4 cipher algorithm which is considered insecure. The algorithm is considered weak and has been deprecated. Use AES instead.

Detected Blowfish cipher algorithm which is considered insecure. The algorithm is considered weak and has been deprecated. Use AES instead.

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

Detected SHA1 hash algorithm which is considered insecure. SHA1 is not collision resistant and is therefore not suitable as a cryptographic signature. Use SHA256 or SHA3 instead.

Detected an insufficient key size for DSA. NIST recommends a key size of 2048 or higher.

Detected an insufficient curve size for EC. NIST recommends a key size of 224 or higher. For example, use 'ec.SECP256R1'.

Detected an insufficient key size for RSA. NIST recommends a key size of 2048 or higher.

Avoid using insecure deserialization library, backed by `pickle`, `_pickle`, `cpickle`, `dill`, `shelve`, or `yaml`, which are known to lead to remote code execution vulnerabilities.

'mark_safe()' is used to mark a string as "safe" for HTML output. This disables escaping and could therefore subject the content to XSS attacks. Use 'django.utils.html.format_html()' to build HTML for rendering instead.

Django REST framework configuration is missing default rate- limiting options. This could inadvertently allow resource starvation or Denial of Service (DoS) attacks. Add 'DEFAULT_THROTTLE_CLASSES' and 'DEFAULT_THROTTLE_RATES' to add rate-limiting to your application.

Found extension of custom expression: $CLASS. Extending expressions in this way could inadvertently lead to a SQL injection vulnerability, which can result in attackers exfiltrating sensitive data. Instead, ensure no user input enters this function or that user input is properly sanitized.

Detected the use of 'RawSQL' or 'raw' indicating the execution of a non-parameterized SQL query. This could lead to a SQL injection and therefore protected information could be leaked. Instead, use Django ORM and parameterized queries before raw SQL. An example of using the Django ORM is: `People.objects.get(name='Bob')`

Django cookies should be handled securely by setting secure=True, httponly=True, and samesite='Lax' in response.set_cookie(...). If your situation calls for different settings, explicitly disable the setting. If you want to send the cookie over http, set secure=False. If you want to let client-side JavaScript read the cookie, set httponly=False. If you want to attach cookies to requests for external sites, set samesite=None.

Detected Django filters flagged with 'is_safe'. 'is_safe' tells Django not to apply escaping on the value returned by this filter (although the input is escaped). Used improperly, 'is_safe' could expose your application to cross-site scripting (XSS) vulnerabilities. Ensure this filter does not 1) add HTML characters, 2) remove characters, or 3) use external data in any way. Consider instead removing 'is_safe' and explicitly marking safe content with 'mark_safe()'.

Passing a formatted string as first parameter to `format_html` disables the proper encoding of variables. Any HTML in the first parameter is not encoded. Using a formatted string as first parameter obscures which parameters are encoded. Correct use of `format_html` is passing a static format string as first parameter, and the variables to substitute as subsequent parameters.

Autoescape is globally disbaled for this Django application. If you are rendering any web pages, this exposes your application to cross-site scripting (XSS) vulnerabilities. Remove 'autoescape: False' or set it to 'True'.

The `__html__` method indicates to the Django template engine that the value is 'safe' for rendering. This means that normal HTML escaping will not be applied to the return value. This exposes your application to cross-site scripting (XSS) vulnerabilities. If you need to render raw HTML, consider instead using `mark_safe()` which more clearly marks the intent to render raw HTML than a class with a magic method.

Found user data in a call to 'eval'. This is extremely dangerous because it can enable an attacker to execute remote code. See https://owasp.org/www-community/attacks/Code_Injection for more information.

Found user data in a call to 'exec'. This is extremely dangerous because it can enable an attacker to execute arbitrary remote code on the system. Instead, refactor your code to not use 'eval' and instead use a safe library for the specific functionality you need.

Request data detected in os.system. This could be vulnerable to a command injection and should be avoided. If this must be done, use the 'subprocess' module instead and pass the arguments as a list. See https://owasp.org/www-community/attacks/Command_Injection for more information.

Detected user input entering a `subprocess` call unsafely. This could result in a command injection vulnerability. An attacker could use this vulnerability to execute arbitrary commands on the host, which allows them to download malware, scan sensitive data, or run any command they wish on the server. Do not let users choose the command to run. In general, prefer to use Python API versions of system commands. If you must use subprocess, use a dictionary to allowlist a set of commands.

Detected user input into a generated CSV file using the built-in `csv` module. If user data is used to generate the data in this file, it is possible that an attacker could inject a formula when the CSV is imported into a spreadsheet application that runs an attacker script, which could steal data from the importing user or, at worst, install malware on the user's computer. `defusedcsv` is a drop-in replacement with the same API that will attempt to mitigate formula injection attempts. You can use `defusedcsv` instead of `csv` to safely generate CSVs.

Found request data in an EmailMessage that is set to use HTML. This is dangerous because HTML emails are susceptible to XSS. An attacker could inject data into this HTML email, causing XSS.

Mass assignment detected. This can result in assignment to model fields that are unintended and can be exploited by an attacker. Instead of using '**request.$W', assign each field you want to edit individually to prevent mass assignment. You can read more about mass assignment at https://cheatsheetseries.owasp.org/cheatsheets/Mass_Assignment_Cheat_Sheet.html.

Data from request ($DATA) is passed to redirect(). This is an open redirect and could be exploited. Ensure you are redirecting to safe URLs by using django.utils.http.is_safe_url(). See https://cwe.mitre.org/data/definitions/601.html for more information.

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. Otherwise, use templates (`django.shortcuts.render`) which will safely render HTML instead.

Found user-controlled request data passed into a HttpResponseBadRequest. This could be vulnerable to XSS, leading to attackers gaining access to user cookies and protected information. Ensure that the request data is properly escaped or sanitzed.

Found user-controlled request data being passed into a file open, which is them passed as an argument into the FileResponse. This is dangerous because an attacker could specify an arbitrary file to read, which could result in leaking important data. Be sure to validate or sanitize the user-inputted filename in the request data before using it in FileResponse.

Found user-controlled request data passed into '.write(...)'. This could be dangerous if a malicious actor is able to control data into sensitive files. For example, a malicious actor could force rolling of critical log files, or cause a denial-of-service by using up available disk space. Instead, ensure that request data is properly escaped or sanitized.

User-controlled data from a request is passed to 'extra()'. This could lead to a SQL injection and therefore protected information could be leaked. Instead, use parameterized queries or escape the user-controlled data by using `params` and not using quote placeholders in the SQL string.

User-controlled data from request is passed to 'RawSQL()'. This could lead to a SQL injection and therefore protected information could be leaked. Instead, use parameterized queries or escape the user-controlled data by using `params` and not using quote placeholders in the SQL string.

User-controlled data from a request is passed to 'execute()'. This could lead to a SQL injection and therefore protected information could be leaked. Instead, use django's QuerySets, which are built with query parameterization and therefore not vulnerable to sql injection. For example, you could use `Entry.objects.filter(date=2006)`.

Data that is possible user-controlled from a python request is passed to `raw()`. This could lead to SQL injection and attackers gaining access to protected information. Instead, use django's QuerySets, which are built with query parameterization and therefore not vulnerable to sql injection. For example, you could use `Entry.objects.filter(date=2006)`.

Data from request object is passed to a new server-side request. This could lead to a server-side request forgery (SSRF). To mitigate, ensure that schemes and hosts are validated against an allowlist, do not forward the response to the user, and ensure proper authentication and transport-layer security in the proxied request. See https://owasp.org/www-community/attacks/Server_Side_Request_Forgery to learn more about SSRF vulnerabilities.

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 the Django object-relational mappers (ORM) instead of raw SQL queries.

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.

Found user input going directly into typecast for bool(), float(), or complex(). This allows an attacker to inject Python's not-a-number (NaN) into the typecast. This results in undefind behavior, particularly when doing comparisons. Either cast to a different type, or add a guard checking for all capitalizations of the string 'nan'.

Running flask app with host 0.0.0.0 could expose the server publicly.

top-level app.run(...) is ignored by flask. Consider putting app.run(...) behind a guard, like inside a function

Detected user input into a generated CSV file using the built-in `csv` module. If user data is used to generate the data in this file, it is possible that an attacker could inject a formula when the CSV is imported into a spreadsheet application that runs an attacker script, which could steal data from the importing user or, at worst, install malware on the user's computer. `defusedcsv` is a drop-in replacement with the same API that will attempt to mitigate formula injection attempts. You can use `defusedcsv` instead of `csv` to safely generate CSVs.

Found user input going directly into typecast for bool(), float(), or complex(). This allows an attacker to inject Python's not-a-number (NaN) into the typecast. This results in undefind behavior, particularly when doing comparisons. Either cast to a different type, or add a guard checking for all capitalizations of the string 'nan'.

User data detected in os.system. This could be vulnerable to a command injection and should be avoided. If this must be done, use the 'subprocess' module instead and pass the arguments as a list.

Detected user input entering a `subprocess` call unsafely. This could result in a command injection vulnerability. An attacker could use this vulnerability to execute arbitrary commands on the host, which allows them to download malware, scan sensitive data, or run any command they wish on the server. Do not let users choose the command to run. In general, prefer to use Python API versions of system commands. If you must use subprocess, use a dictionary to allowlist a set of commands.

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 SQLAlchemy which will protect your queries.

Detected user data flowing into eval. This is code injection and should be avoided.

Detected user data flowing into exec. This is code injection and should be avoided.

Detected a user-controlled `filename` that could flow to `flask.send_file()` function. This could lead to an attacker reading arbitrary file from the system, leaking private information. Make sure to properly sanitize filename or use `flask.send_from_directory`

Flask does not automatically escape Jinja templates unless they have .html, .htm, .xml, or .xhtml extensions. This could lead to XSS attacks. Use .html, .htm, .xml, or .xhtml for your template extensions. See https://flask.palletsprojects.com/en/1.1.x/templating/#jinja-setup for more information.

Flask response reflects unsanitized user input. This could lead to a cross-site scripting vulnerability (https://owasp.org/www-community/attacks/xss/) in which an attacker causes arbitrary code to be executed in the user's browser. To prevent, please sanitize the user input, e.g. by rendering the response in a Jinja2 template (see considerations in https://flask.palletsprojects.com/en/1.0.x/security/).

Detected direct use of jinja2. If not done properly, this may bypass HTML escaping which opens up the application to cross-site scripting (XSS) vulnerabilities. Prefer using the Flask method 'render_template()' and templates with a '.html' extension in order to prevent XSS.

Found dynamic content when spawning a process. This is dangerous if external data can reach this function call because it allows a malicious actor to execute commands. Ensure no external data reaches here.

Found user controlled content when spawning a process. This is dangerous because it allows a malicious actor to execute commands.

Found dynamic content when spawning a process. This is dangerous if external data can reach this function call because it allows a malicious actor to execute commands. Ensure no external data reaches here.

Found user controlled content when spawning a process. This is dangerous because it allows a malicious actor to execute commands.

Found dynamic content in `run_string`. This is dangerous if external data can reach this function call because it allows a malicious actor to run arbitrary Python code. Ensure no external data reaches here.

Found user controlled content in `run_string`. This is dangerous because it allows a malicious actor to run arbitrary Python code.

Detected subprocess function '$FUNC' with user controlled data. A malicious actor could leverage this to perform command injection. You may consider using 'shlex.escape()'.

This rule is deprecated. It will no longer produce findings.

Found dynamic content used in a system call. This is dangerous if external data can reach this function call because it allows a malicious actor to execute commands. Use the 'subprocess' module instead, which is easier to use without accidentally exposing a command injection vulnerability.

Found user-controlled data used in a system call. This could allow a malicious actor to execute commands. Use the 'subprocess' module instead, which is easier to use without accidentally exposing a command injection vulnerability.

Found dynamic content in `run_in_subinterp`. This is dangerous if external data can reach this function call because it allows a malicious actor to run arbitrary Python code. Ensure no external data reaches here.

Detected a dynamic value being used with urllib. urllib supports 'file://' schemes, so a dynamic value controlled by a malicious actor may allow them to read arbitrary files. Audit uses of urllib calls to ensure user data cannot control the URLs, or consider using the 'requests' library instead.

Detected the use of exec(). exec() can be dangerous if used to evaluate dynamic content. If this content can be input from outside the program, this may be a code injection vulnerability. Ensure evaluated content is not definable by external sources.

Detected possible formatted SQL query. Use parameterized queries instead.

Hardcoded password is used as a default argument to '$FUNC'. This could be dangerous if a real password is not supplied.

The HTTPSConnection API has changed frequently with minor releases of Python. Ensure you are using the API for your version of Python securely. For example, Python 3 versions prior to 3.4.3 will not verify SSL certificates by default. See https://docs.python.org/3/library/http.client.html#http.client.HTTPSConnection for more information.

Detected an unsecured transmission channel. 'URLopener.open(...)' is being used with 'http://'. Use 'https://' instead to secure the channel.

Detected 'urllib.urlretrieve()' using 'ftp://'. This request will not be encrypted. Use SFTP instead. urllib does not support SFTP, so consider switching to a library which supports SFTP.

Because portions of the logging configuration are passed through eval(), use of this function may open its users to a security risk. While the function only binds to a socket on localhost, and so does not accept connections from remote machines, there are scenarios where untrusted code could be run under the account of the process which calls listen(). To avoid this happening, use the `verify()` argument to `listen()` to prevent unrecognized configurations.

Mako templates do not provide a global HTML escaping mechanism. This means you must escape all sensitive data in your templates using '| u' for URL escaping or '| h' for HTML escaping. If you are using Mako to serve web content, consider using a system such as Jinja2 which enables global escaping.

The marshal module is not intended to be secure against erroneous or maliciously constructed data. Never unmarshal data received from an untrusted or unauthenticated source. See more details: https://docs.python.org/3/library/marshal.html?highlight=security

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 scrypt. You can use `hashlib.scrypt`.

certificate verification explicitly disabled, insecure connections possible

Detected HTTPConnectionPool. This will transmit data in cleartext. It is recommended to use HTTPSConnectionPool instead for to encrypt communications.

Unverified SSL context detected. This will permit insecure connections without verifying SSL certificates. Use 'ssl.create_default_context()' instead.

Detected a paramiko host key policy that implicitly trusts a server's host key. Host keys should be verified to ensure the connection is not to a malicious server. Use RejectPolicy or a custom subclass instead.

Detected usage of re.compile with an inefficient regular expression. This can lead to regular expression denial of service, which can result in service down time. Instead, check all regexes or use safer alternatives such as pyre2.

Detected string concatenation with a non-literal variable in a pg8000 Python SQL statement. This could lead to SQL injection if the variable is user-controlled and not properly sanitized. In order to prevent SQL injection, use parameterized queries or prepared statements instead. You can create parameterized queries like so: 'conn.run("SELECT :value FROM table", value=myvalue)'. You can also create prepared statements with 'conn.prepare': 'conn.prepare("SELECT (:v) FROM table")'

Detected string concatenation with a non-literal variable in a psycopg2 Python SQL statement. This could lead to SQL injection if the variable is user-controlled and not properly sanitized. In order to prevent SQL injection, use parameterized queries or prepared statements instead. You can use prepared statements by creating a 'sql.SQL' string. You can also use the pyformat binding style to create parameterized queries. For example: 'cur.execute(SELECT * FROM table WHERE name=%s, user_input)'

Detected the generation of a CSV file using the built-in `csv` module. If user data is used to generate the data in this file, it is possible that an attacker could inject a formula when the CSV is imported into a spreadsheet application that runs an attacker script, which could steal data from the importing user or, at worst, install malware on the user's computer. `defusedcsv` is a drop-in replacement with the same API that will attempt to mitigate formula injection attempts. You can use `defusedcsv` instead of `csv` to safely generate CSVs.

Detected Blowfish cipher algorithm which is considered insecure. This algorithm is not cryptographically secure and can be reversed easily. Use AES instead.

Detected DES cipher algorithm which is considered insecure. This algorithm is not cryptographically secure and can be reversed easily. Use AES instead.

Detected RC2 cipher algorithm which is considered insecure. This algorithm is not cryptographically secure and can be reversed easily. Use AES instead.

Detected ARC4 cipher algorithm which is considered insecure. This algorithm is not cryptographically secure and can be reversed easily. Use AES instead.

Detected MD2 hash algorithm which is considered insecure. MD2 is not collision resistant and is therefore not suitable as a cryptographic signature. Use SHA256 or SHA3 instead.

Detected MD4 hash algorithm which is considered insecure. MD4 is not collision resistant and is therefore not suitable as a cryptographic signature. Use SHA256 or SHA3 instead.

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

Warning MONGODB-CR was deprecated with the release of MongoDB 3.6 and is no longer supported by MongoDB 4.0 (see https://api.mongodb.com/python/current/examples/authentication.html for details).

Found a Pyramid Authentication Ticket cookie without the httponly option correctly set. Pyramid cookies should be handled securely by setting httponly=True. If this parameter is not properly set, your cookies are not properly protected and are at risk of being stolen by an attacker.

Found a Pyramid Authentication Ticket cookie without the httponly option correctly set. Pyramid cookies should be handled securely by setting httponly=True. If this parameter is not properly set, your cookies are not properly protected and are at risk of being stolen by an attacker.

Found a Pyramid Authentication Ticket without the samesite option correctly set. Pyramid cookies should be handled securely by setting samesite='Lax'. If this parameter is not properly set, your cookies are not properly protected and are at risk of being stolen by an attacker.

Found a Pyramid Authentication Ticket cookie using an unsafe default for the secure option. Pyramid cookies should be handled securely by setting secure=True. If this parameter is not properly set, your cookies are not properly protected and are at risk of being stolen by an attacker.

Found a Pyramid Authentication Ticket cookie without the secure option correctly set. Pyramid cookies should be handled securely by setting secure=True. If this parameter is not properly set, your cookies are not properly protected and are at risk of being stolen by an attacker.

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

Automatic check of the referrer for cross-site request forgery tokens has been explicitly disabled globally, which might leave views unprotected when an unsafe CSRF storage policy is used. Use 'pyramid.config.Configurator.set_default_csrf_options(check_origin=True)' to turn the automatic check for all unsafe methods (per RFC2616).

Origin check for the CSRF token is disabled for this view. This might represent a security risk if the CSRF storage policy is not known to be secure.

Found a Pyramid cookie using an unsafe default for the httponly option. Pyramid cookies should be handled securely by setting httponly=True in response.set_cookie(...). If this parameter is not properly set, your cookies are not properly protected and are at risk of being stolen by an attacker.

Found a Pyramid cookie without the httponly option correctly set. Pyramid cookies should be handled securely by setting httponly=True in response.set_cookie(...). If this parameter is not properly set, your cookies are not properly protected and are at risk of being stolen by an attacker.

Found a Pyramid cookie using an unsafe value for the samesite option. Pyramid cookies should be handled securely by setting samesite='Lax' in response.set_cookie(...). If this parameter is not properly set, your cookies are not properly protected and are at risk of being stolen by an attacker.

Found a Pyramid cookie without the samesite option correctly set. Pyramid cookies should be handled securely by setting samesite='Lax' in response.set_cookie(...). If this parameter is not properly set, your cookies are not properly protected and are at risk of being stolen by an attacker.

Found a Pyramid cookie using an unsafe default for the secure option. Pyramid cookies should be handled securely by setting secure=True in response.set_cookie(...). If this parameter is not properly set, your cookies are not properly protected and are at risk of being stolen by an attacker.

Found a Pyramid cookie without the secure option correctly set. Pyramid cookies should be handled securely by setting secure=True in response.set_cookie(...). If this parameter is not properly set, your cookies are not properly protected and are at risk of being stolen by an attacker.

Automatic check of cross-site request forgery tokens has been explicitly disabled globally, which might leave views unprotected. Use 'pyramid.config.Configurator.set_default_csrf_options(require_csrf=True)' to turn the automatic check for all unsafe methods (per RFC2616).

Detected data rendered directly to the end user via 'Response'. This bypasses Pyramid's built-in cross-site scripting (XSS) defenses and could result in an XSS vulnerability. Use Pyramid's template engines to safely render HTML.

Distinct, Having, Group_by, Order_by, and Filter in SQLAlchemy can cause sql injections if the developer inputs raw SQL into the before-mentioned clauses. This pattern captures relevant cases in which the developer inputs raw SQL into the distinct, having, group_by, order_by or filter clauses and injects user-input into the raw SQL with any function besides "bindparams". Use bindParams to securely bind user-input to SQL statements.

sqlalchemy.text passes the constructed SQL statement to the database mostly unchanged. This means that the usual SQL injection protections are not applied and this function is vulnerable to SQL injection if user input can reach here. Use normal SQLAlchemy operators (such as or_, and_, etc.) to construct SQL.

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.

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 the use of eval(). eval() can be dangerous if used to evaluate dynamic content. If this content can be input from outside the program, this may be a code injection vulnerability. Ensure evaluated content is not definable by external sources.

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. Otherwise, use templates which will safely render HTML instead.

Detected strings that are implicitly concatenated inside a list. Python will implicitly concatenate strings when not explicitly delimited. Was this supposed to be individual elements of the list?

It appears that `$DICT[$KEY]` is a dict with items being deleted while in a for loop. This is usually a bad idea and will likely lead to a RuntimeError: dictionary changed size during iteration

In Python3, a runtime `TypeError` will be thrown if you attempt to raise an object or class which does not inherit from `BaseException`

Data from request is passed to redirect(). This is an open redirect and could be exploited. Consider using 'url_for()' to generate links to known locations. If you must use a URL to unknown pages, consider using 'urlparse()' or similar and checking if the 'netloc' property is the same as your site's host name. See the references for more information.

Detected a file object that is redefined and never closed. This could leak file descriptors and unnecessarily consume system resources.

It appears that `$LIST` is a list that is being modified while in a for loop. This will likely cause a runtime error or an infinite loop.

pdb is an interactive debugging tool and you may have forgotten to remove it before committing your code

Using '$F.name' without '.flush()' or '.close()' may cause an error because the file may not exist when '$F.name' is used. Use '.flush()' or close the file before using '$F.name'.

Use tempfile.NamedTemporaryFile instead. From the official Python documentation: THIS FUNCTION IS UNSAFE AND SHOULD NOT BE USED. The file name may refer to a file that did not exist at some point, but by the time you get around to creating it, someone else may have beaten you to the punch.

Using strings as booleans in Python has unexpected results. `"one" and "two"` will return "two". `"one" or "two"` will return "one". In Python, strings are truthy, and strings with a non-zero length evaluate to True.

The file object '$FD' was opened in read mode, but is being written to. This will cause a runtime error.

Detected use of `exit`. Use `sys.exit` over the python shell `exit` built-in. `exit` is a helper for the interactive shell and may not be available on all Python implementations.

function `$FF` is defined inside a function but never used

Found a formatted string in BashOperator: $CMD. This could be vulnerable to injection. Be extra sure your variables are not controllable by external sources.

`return` should never appear inside a class __init__ function. This will cause a runtime error.
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 ChaCha20Poly1305 or AES-GCM instead of Blowfish. For older applications that don't have support for `ChaCha20Poly1305`, `AES-256-GCM` is recommended, however it has many drawbacks: - Slower than `ChaCha20Poly1305`. - Catastrophic failure if nonce values are reused. Note that the `Crypto` and `Cryptodome` Python packages are no longer recommended for new applications, instead consider using the [cryptography](https://cryptography.io/) package. Example using `ChaCha20Poly1305`: ``` import os # Import ChaCha20Poly1305 from cryptography from cryptography.hazmat.primitives.ciphers.aead import ChaCha20Poly1305 # Our plaintext to encrypt plain_text = b"Secret text to encrypt" # We do not require authenticated but unencrypted data, so set to None aad = None # Generate a secure key key = ChaCha20Poly1305.generate_key() # Create a new ChaCha20Poly1305 instance with our secure key chacha = ChaCha20Poly1305(key) # Note: nonce values _must_ be regenerated every time they are used. nonce = os.urandom(12) # Encrypt our plaintext cipher_text = chacha.encrypt(nonce, plain_text, aad) # Decrypt the plain text using the nonce and cipher_text chacha.decrypt(nonce, cipher_text, aad) ``` Example using `AESGCM`: ``` import os # Import AESGCM from cryptography from cryptography.hazmat.primitives.ciphers.aead import AESGCM # Our plaintext to encrypt plain_text = b"Secret text to encrypt" # We do not require authenticated but unencrypted data, so set to None aad = None # Generate a secure key key = AESGCM.generate_key(bit_length=128) # Create a new AESGCM instance with our secure key aesgcm = AESGCM(key) # Note: nonce values _must_ be regenerated every time they are used. nonce = os.urandom(12) # Encrypt our plaintext cipher_text = aesgcm.encrypt(nonce, plain_text, aad) # Decrypt the plain text using the nonce and cipher_text aesgcm.decrypt(nonce, cipher_text, aad) ``` For more information on the cryptography module see: - https://cryptography.io/en/latest/
DES, TripleDES, RC2 and RC4 are all considered broken or insecure cryptographic algorithms. Newer algorithms apply message integrity to validate ciphertext has not been tampered with. Consider using `ChaCha20Poly1305` instead as it is easier and faster than the alternatives such as `AES-256-GCM`. For older applications that don't have support for `ChaCha20Poly1305`, `AES-256-GCM` is recommended, however it has many drawbacks: - Slower than `ChaCha20Poly1305`. - Catastrophic failure if nonce values are reused. Note that the `Crypto` and `Cryptodome` Python packages are no longer recommended for new applications, instead consider using the [cryptography](https://cryptography.io/) package. Example using `ChaCha20Poly1305`: ``` import os # Import ChaCha20Poly1305 from cryptography from cryptography.hazmat.primitives.ciphers.aead import ChaCha20Poly1305 # Our plaintext to encrypt plain_text = b"Secret text to encrypt" # We do not require authenticated but unencrypted data, so set to None aad = None # Generate a secure key key = ChaCha20Poly1305.generate_key() # Create a new ChaCha20Poly1305 instance with our secure key chacha = ChaCha20Poly1305(key) # Note: nonce values _must_ be regenerated every time they are used. nonce = os.urandom(12) # Encrypt our plaintext cipher_text = chacha.encrypt(nonce, plain_text, aad) # Decrypt the plain text using the nonce and cipher_text chacha.decrypt(nonce, cipher_text, aad) ``` Example using `AESGCM`: ``` import os # Import AESGCM from cryptography from cryptography.hazmat.primitives.ciphers.aead import AESGCM # Our plaintext to encrypt plain_text = b"Secret text to encrypt" # We do not require authenticated but unencrypted data, so set to None aad = None # Generate a secure key key = AESGCM.generate_key(bit_length=128) # Create a new AESGCM instance with our secure key aesgcm = AESGCM(key) # Note: nonce values _must_ be regenerated every time they are used. nonce = os.urandom(12) # Encrypt our plaintext cipher_text = aesgcm.encrypt(nonce, plain_text, aad) # Decrypt the plain text using the nonce and cipher_text aesgcm.decrypt(nonce, cipher_text, aad) ``` For more information on the cryptography module see: - https://cryptography.io/en/latest/
DES, TripleDES, RC2 and RC4 are all considered broken or insecure cryptographic algorithms. Newer algorithms apply message integrity to validate ciphertext has not been tampered with. Consider using `ChaCha20Poly1305` instead as it is easier and faster than the alternatives such as `AES-256-GCM`. For older applications that don't have support for `ChaCha20Poly1305`, `AES-256-GCM` is recommended, however it has many drawbacks: - Slower than `ChaCha20Poly1305`. - Catastrophic failure if nonce values are reused. Note that the `Crypto` and `Cryptodome` Python packages are no longer recommended for new applications, instead consider using the [cryptography](https://cryptography.io/) package. Example using `ChaCha20Poly1305`: ``` import os # Import ChaCha20Poly1305 from cryptography from cryptography.hazmat.primitives.ciphers.aead import ChaCha20Poly1305 # Our plaintext to encrypt plain_text = b"Secret text to encrypt" # We do not require authenticated but unencrypted data, so set to None aad = None # Generate a secure key key = ChaCha20Poly1305.generate_key() # Create a new ChaCha20Poly1305 instance with our secure key chacha = ChaCha20Poly1305(key) # Note: nonce values _must_ be regenerated every time they are used. nonce = os.urandom(12) # Encrypt our plaintext cipher_text = chacha.encrypt(nonce, plain_text, aad) # Decrypt the plain text using the nonce and cipher_text chacha.decrypt(nonce, cipher_text, aad) ``` Example using `AESGCM`: ``` import os # Import AESGCM from cryptography from cryptography.hazmat.primitives.ciphers.aead import AESGCM # Our plaintext to encrypt plain_text = b"Secret text to encrypt" # We do not require authenticated but unencrypted data, so set to None aad = None # Generate a secure key key = AESGCM.generate_key(bit_length=128) # Create a new AESGCM instance with our secure key aesgcm = AESGCM(key) # Note: nonce values _must_ be regenerated every time they are used. nonce = os.urandom(12) # Encrypt our plaintext cipher_text = aesgcm.encrypt(nonce, plain_text, aad) # Decrypt the plain text using the nonce and cipher_text aesgcm.decrypt(nonce, cipher_text, aad) ``` For more information on the cryptography module see: - https://cryptography.io/en/latest/
DES, TripleDES, RC2 and RC4 are all considered broken or insecure cryptographic algorithms. Newer algorithms apply message integrity to validate ciphertext has not been tampered with. Consider using `ChaCha20Poly1305` instead as it is easier and faster than the alternatives such as `AES-256-GCM`. For older applications that don't have support for `ChaCha20Poly1305`, `AES-256-GCM` is recommended, however it has many drawbacks: - Slower than `ChaCha20Poly1305`. - Catastrophic failure if nonce values are reused. Note that the `Crypto` and `Cryptodome` Python packages are no longer recommended for new applications, instead consider using the [cryptography](https://cryptography.io/) package. Example using `ChaCha20Poly1305`: ``` import os # Import ChaCha20Poly1305 from cryptography from cryptography.hazmat.primitives.ciphers.aead import ChaCha20Poly1305 # Our plaintext to encrypt plain_text = b"Secret text to encrypt" # We do not require authenticated but unencrypted data, so set to None aad = None # Generate a secure key key = ChaCha20Poly1305.generate_key() # Create a new ChaCha20Poly1305 instance with our secure key chacha = ChaCha20Poly1305(key) # Note: nonce values _must_ be regenerated every time they are used. nonce = os.urandom(12) # Encrypt our plaintext cipher_text = chacha.encrypt(nonce, plain_text, aad) # Decrypt the plain text using the nonce and cipher_text chacha.decrypt(nonce, cipher_text, aad) ``` Example using `AESGCM`: ``` import os # Import AESGCM from cryptography from cryptography.hazmat.primitives.ciphers.aead import AESGCM # Our plaintext to encrypt plain_text = b"Secret text to encrypt" # We do not require authenticated but unencrypted data, so set to None aad = None # Generate a secure key key = AESGCM.generate_key(bit_length=128) # Create a new AESGCM instance with our secure key aesgcm = AESGCM(key) # Note: nonce values _must_ be regenerated every time they are used. nonce = os.urandom(12) # Encrypt our plaintext cipher_text = aesgcm.encrypt(nonce, plain_text, aad) # Decrypt the plain text using the nonce and cipher_text aesgcm.decrypt(nonce, cipher_text, aad) ``` For more information on the cryptography module see: - https://cryptography.io/en/latest/
The application was found using the `xor` algorithm, which can be trivially decoded. Newer algorithms apply message integrity to validate ciphertext has not been tampered with. Consider using `ChaCha20Poly1305` instead as it is easier and faster than the alternatives such as `AES-256-GCM`. For older applications that don't have support for `ChaCha20Poly1305`, `AES-256-GCM` is recommended, however it has many drawbacks: - Slower than `ChaCha20Poly1305`. - Catastrophic failure if nonce values are reused. Note that the `Crypto` and `Cryptodome` Python packages are no longer recommended for new applications, instead consider using the [cryptography](https://cryptography.io/) package. Example using `ChaCha20Poly1305`: ``` import os # Import ChaCha20Poly1305 from cryptography from cryptography.hazmat.primitives.ciphers.aead import ChaCha20Poly1305 # Our plaintext to encrypt plain_text = b"Secret text to encrypt" # We do not require authenticated but unencrypted data, so set to None aad = None # Generate a secure key key = ChaCha20Poly1305.generate_key() # Create a new ChaCha20Poly1305 instance with our secure key chacha = ChaCha20Poly1305(key) # Note: nonce values _must_ be regenerated every time they are used. nonce = os.urandom(12) # Encrypt our plaintext cipher_text = chacha.encrypt(nonce, plain_text, aad) # Decrypt the plain text using the nonce and cipher_text chacha.decrypt(nonce, cipher_text, aad) ``` Example using `AESGCM`: ``` import os # Import AESGCM from cryptography from cryptography.hazmat.primitives.ciphers.aead import AESGCM # Our plaintext to encrypt plain_text = b"Secret text to encrypt" # We do not require authenticated but unencrypted data, so set to None aad = None # Generate a secure key key = AESGCM.generate_key(bit_length=128) # Create a new AESGCM instance with our secure key aesgcm = AESGCM(key) # Note: nonce values _must_ be regenerated every time they are used. nonce = os.urandom(12) # Encrypt our plaintext cipher_text = aesgcm.encrypt(nonce, plain_text, aad) # Decrypt the plain text using the nonce and cipher_text aesgcm.decrypt(nonce, cipher_text, aad) ``` For more information on the cryptography module see: - https://cryptography.io/en/latest/
The application is generating an RSA key that is less than the recommended 2048 bits. The National Institute of Standards and Technology (NIST) deprecated signing Digital Certificates that contained RSA Public Keys of 1024 bits in December 2010. While 1024-bit RSA keys have not been factored yet, advances in compute may make it possible in the near future. Consider upgrading to the newer asymmetric algorithm such as `X25519` which handles the complexities of generating key pairs and choosing correct key sizes for you: ``` from cryptography.hazmat.primitives.asymmetric.x25519 import X25519PrivateKey # Generate a private key for use in the exchange. private_key = X25519PrivateKey.generate() # Work with private key/exchange with a peer's # public key to created a shared and derived key # ... ``` Otherwise use a key size greater than 2048 when generating RSA keys: ``` from cryptography.hazmat.primitives.asymmetric import rsa # Generate a private key of 4096 bits private_key = rsa.generate_private_key( # do not change the exponent value from 65537 public_exponent=65537, key_size=4096, ) # Work with the private key to sign/encrypt data # ... ``` For more information on using the cryptography module see: - https://cryptography.io/en/latest
The application was found using an insufficient curve size for the Elliptical Cryptography (EC) asymmetric algorithm. NIST recommends using a key size of 224 or greater. To remediate this issue, replace the current key size with `ec.SECP384R1`, Example using `ec.SECP384R1`: ``` from cryptography.hazmat.primitives.asymmetric import ec # Generate an EC private key using SECP384R1 private_key = ec.generate_private_key( ec.SECP384R1() ) # Work with/sign data using the key # ... ``` For more information on the cryptography module's EC section see: - https://cryptography.io/en/latest/hazmat/primitives/asymmetric/ec/
The application was found using an insecure or risky digest or signature algorithm. MD5 and SHA1 hash algorithms have been found to be vulnerable to producing collisions. This means that two different values, when hashed, can lead to the same hash value. If the application is trying to use these hash methods for storing passwords, then it is recommended to switch to a password hashing algorithm such as Argon2id or PBKDF2. It is strongly recommended that a standard digest algorithm be chosen instead as implementing a custom algorithm is prone to errors. Note that the `Crypto` and `Cryptodome` Python packages are no longer recommended for new applications, instead consider using the [cryptography](https://cryptography.io/) package. Example of creating a SHA-384 hash using the `cryptography` package: ``` from cryptography.hazmat.primitives import hashes # Create a SHA384 digest digest = hashes.Hash(hashes.SHA384()) # Update the digest with some initial data digest.update(b"some data to hash") # Add more data to the digest digest.update(b"some more data") # Finalize the digest as bytes result = digest.finalize() ``` For more information on secure password storage see OWASP: - https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html For more information on the cryptography module see: - https://cryptography.io/en/latest/
The application was found using an insecure or risky digest or signature algorithm. MD5 and SHA1 hash algorithms have been found to be vulnerable to producing collisions. This means that two different values, when hashed, can lead to the same hash value. If the application is trying to use these hash methods for storing passwords, then it is recommended to switch to a password hashing algorithm such as Argon2id or PBKDF2. It is strongly recommended that a standard digest algorithm be chosen instead as implementing a custom algorithm is prone to errors. Note that the `Crypto` and `Cryptodome` Python packages are no longer recommended for new applications, instead consider using the [cryptography](https://cryptography.io/) package. Example of creating a SHA-384 hash using the `cryptography` package: ``` from cryptography.hazmat.primitives import hashes # Create a SHA384 digest digest = hashes.Hash(hashes.SHA384()) # Update the digest with some initial data digest.update(b"some data to hash") # Add more data to the digest digest.update(b"some more data") # Finalize the digest as bytes result = digest.finalize() ``` For more information on secure password storage see OWASP: - https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html For more information on the cryptography module see: - https://cryptography.io/en/latest/
DES, TripleDES, RC2 and RC4 are all considered broken or insecure cryptographic algorithms. Newer algorithms apply message integrity to validate ciphertext has not been tampered with. Consider using `ChaCha20Poly1305` instead as it is easier and faster than the alternatives such as `AES-256-GCM`. For older applications that don't have support for `ChaCha20Poly1305`, `AES-256-GCM` is recommended, however it has many drawbacks: - Slower than `ChaCha20Poly1305`. - Catastrophic failure if nonce values are reused. Example using `ChaCha20Poly1305`: ``` import os # Import ChaCha20Poly1305 from cryptography from cryptography.hazmat.primitives.ciphers.aead import ChaCha20Poly1305 # Our plaintext to encrypt plain_text = b"Secret text to encrypt" # We do not require authenticated but unencrypted data, so set to None aad = None # Generate a secure key key = ChaCha20Poly1305.generate_key() # Create a new ChaCha20Poly1305 instance with our secure key chacha = ChaCha20Poly1305(key) # Note: nonce values _must_ be regenerated every time they are used. nonce = os.urandom(12) # Encrypt our plaintext cipher_text = chacha.encrypt(nonce, plain_text, aad) # Decrypt the plain text using the nonce and cipher_text chacha.decrypt(nonce, cipher_text, aad) ``` Example using `AESGCM`: ``` import os # Import AESGCM from cryptography from cryptography.hazmat.primitives.ciphers.aead import AESGCM # Our plaintext to encrypt plain_text = b"Secret text to encrypt" # We do not require authenticated but unencrypted data, so set to None aad = None # Generate a secure key key = AESGCM.generate_key(bit_length=128) # Create a new AESGCM instance with our secure key aesgcm = AESGCM(key) # Note: nonce values _must_ be regenerated every time they are used. nonce = os.urandom(12) # Encrypt our plaintext cipher_text = aesgcm.encrypt(nonce, plain_text, aad) # Decrypt the plain text using the nonce and cipher_text aesgcm.decrypt(nonce, cipher_text, aad) ``` For more information on the cryptography module see: - https://cryptography.io/en/latest/
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 ChaCha20Poly1305 or AES-GCM instead of Blowfish. For older applications that don't have support for `ChaCha20Poly1305`, `AES-256-GCM` is recommended, however it has many drawbacks: - Slower than `ChaCha20Poly1305`. - Catastrophic failure if nonce values are reused. Example using `ChaCha20Poly1305`: ``` import os # Import ChaCha20Poly1305 from cryptography from cryptography.hazmat.primitives.ciphers.aead import ChaCha20Poly1305 # Our plaintext to encrypt plain_text = b"Secret text to encrypt" # We do not require authenticated but unencrypted data, so set to None aad = None # Generate a secure key key = ChaCha20Poly1305.generate_key() # Create a new ChaCha20Poly1305 instance with our secure key chacha = ChaCha20Poly1305(key) # Note: nonce values _must_ be regenerated every time they are used. nonce = os.urandom(12) # Encrypt our plaintext cipher_text = chacha.encrypt(nonce, plain_text, aad) # Decrypt the plain text using the nonce and cipher_text chacha.decrypt(nonce, cipher_text, aad) ``` Example using `AESGCM`: ``` import os # Import AESGCM from cryptography from cryptography.hazmat.primitives.ciphers.aead import AESGCM # Our plaintext to encrypt plain_text = b"Secret text to encrypt" # We do not require authenticated but unencrypted data, so set to None aad = None # Generate a secure key key = AESGCM.generate_key(bit_length=128) # Create a new AESGCM instance with our secure key aesgcm = AESGCM(key) # Note: nonce values _must_ be regenerated every time they are used. nonce = os.urandom(12) # Encrypt our plaintext cipher_text = aesgcm.encrypt(nonce, plain_text, aad) # Decrypt the plain text using the nonce and cipher_text aesgcm.decrypt(nonce, cipher_text, aad) ``` For more information on the cryptography module see: - https://cryptography.io/en/latest/
The IDEA encryption algorithm was meant as a drop-in replacement for DES and was created in 1991. A number of [vulnerabilities and exploits](https://en.wikipedia.org/wiki/International_Data_Encryption_Algorithm#Security) have been identified to work against IDEA and it is no longer recommended. If possible consider using ChaCha20Poly1305 or AES-GCM instead of Blowfish. For older applications that don't have support for `ChaCha20Poly1305`, `AES-256-GCM` is recommended, however it has many drawbacks: - Slower than `ChaCha20Poly1305`. - Catastrophic failure if nonce values are reused. Example using `ChaCha20Poly1305`: ``` import os # Import ChaCha20Poly1305 from cryptography from cryptography.hazmat.primitives.ciphers.aead import ChaCha20Poly1305 # Our plaintext to encrypt plain_text = b"Secret text to encrypt" # We do not require authenticated but unencrypted data, so set to None aad = None # Generate a secure key key = ChaCha20Poly1305.generate_key() # Create a new ChaCha20Poly1305 instance with our secure key chacha = ChaCha20Poly1305(key) # Note: nonce values _must_ be regenerated every time they are used. nonce = os.urandom(12) # Encrypt our plaintext cipher_text = chacha.encrypt(nonce, plain_text, aad) # Decrypt the plain text using the nonce and cipher_text chacha.decrypt(nonce, cipher_text, aad) ``` Example using `AESGCM`: ``` import os # Import AESGCM from cryptography from cryptography.hazmat.primitives.ciphers.aead import AESGCM # Our plaintext to encrypt plain_text = b"Secret text to encrypt" # We do not require authenticated but unencrypted data, so set to None aad = None # Generate a secure key key = AESGCM.generate_key(bit_length=128) # Create a new AESGCM instance with our secure key aesgcm = AESGCM(key) # Note: nonce values _must_ be regenerated every time they are used. nonce = os.urandom(12) # Encrypt our plaintext cipher_text = aesgcm.encrypt(nonce, plain_text, aad) # Decrypt the plain text using the nonce and cipher_text aesgcm.decrypt(nonce, cipher_text, aad) ``` For more information on the cryptography module see: - https://cryptography.io/en/latest/
The application was found using an insecure or risky digest or signature algorithm. MD2, MD5 and SHA1 hash algorithms have been found to be vulnerable to producing collisions. This means that two different values, when hashed, can lead to the same hash value. If the application is trying to use these hash methods for storing passwords, then it is recommended to switch to a password hashing algorithm such as Argon2id or PBKDF2. Note that the `Crypto` and `Cryptodome` Python packages are no longer recommended for new applications, instead consider using the [cryptography](https://cryptography.io/) package. Example of creating a SHA-384 hash using the `cryptography` package: ``` from cryptography.hazmat.primitives import hashes # Create a SHA384 digest digest = hashes.Hash(hashes.SHA384()) # Update the digest with some initial data digest.update(b"some data to hash") # Add more data to the digest digest.update(b"some more data") # Finalize the digest as bytes result = digest.finalize() ``` For more information on secure password storage see OWASP: - https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html For more information on the cryptography module see: - https://cryptography.io/en/latest/
The application was found using an insecure or risky digest or signature algorithm. MD2, MD4, MD5 and SHA1 hash algorithms have been found to be vulnerable to producing collisions. This means that two different values, when hashed, can lead to the same hash value. If the application is trying to use these hash methods for storing passwords, then it is recommended to switch to a password hashing algorithm such as Argon2id or PBKDF2. Note that the `Crypto` and `Cryptodome` Python packages are no longer recommended for new applications, instead consider using the [cryptography](https://cryptography.io/) package. Example of creating a SHA-384 hash using the `cryptography` package: ``` from cryptography.hazmat.primitives import hashes # Create a SHA384 digest digest = hashes.Hash(hashes.SHA384()) # Update the digest with some initial data digest.update(b"some data to hash") # Add more data to the digest digest.update(b"some more data") # Finalize the digest as bytes result = digest.finalize() ``` For more information on secure password storage see OWASP: - https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html For more information on the cryptography module see: - https://cryptography.io/en/latest/
The application was found using an insecure or risky digest or signature algorithm. MD2, MD4, MD5 and SHA1 hash algorithms have been found to be vulnerable to producing collisions. This means that two different values, when hashed, can lead to the same hash value. If the application is trying to use these hash methods for storing passwords, then it is recommended to switch to a password hashing algorithm such as Argon2id or PBKDF2. Note that the `Crypto` and `Cryptodome` Python packages are no longer recommended for new applications, instead consider using the [cryptography](https://cryptography.io/) package. Example of creating a SHA-384 hash using the `cryptography` package: ``` from cryptography.hazmat.primitives import hashes # Create a SHA384 digest digest = hashes.Hash(hashes.SHA384()) # Update the digest with some initial data digest.update(b"some data to hash") # Add more data to the digest digest.update(b"some more data") # Finalize the digest as bytes result = digest.finalize() ``` For more information on secure password storage see OWASP: - https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html For more information on the cryptography module see: - https://cryptography.io/en/latest/
The application was detected importing `pycrypto`. This package has been deprecated as it contains security vulnerabilities. To remediate this issue, consider using the [cryptography](https://cryptography.io/) package instead.
The application was found using `dill` which is vulnerable to deserialization attacks. Deserialization attacks exploit the process of reading serialized data and turning it back into an object. By constructing malicious objects and serializing them, an adversary may attempt to: - Inject code that is executed upon object construction, which occurs during the deserialization process. - Exploit mass assignment by including fields that are not normally a part of the serialized data but are read in during deserialization. Consider safer alternatives such as serializing data in the JSON format. Ensure any format chosen allows the application to specify exactly which object types are allowed to be deserialized. To protect against mass assignment, only allow deserialization of the specific fields that are required. If this is not easily done, consider creating an intermediary type that can be serialized with only the necessary fields exposed. Example JSON deserializer using an intermediary type that is validated against a schema to ensure it is safe from mass assignment: ``` import jsonschema # Create a schema to validate our user-supplied input against # an intermediary object intermediary_schema = { "type" : "object", "properties" : { "name": {"type" : "string"} }, "required": ["name"], # Protect against random properties being added to the object "additionalProperties": False, } # If a user attempted to add "'is_admin': True" it would cause a validation error intermediary_object = {'name': 'test user'} try: # Validate the user supplied intermediary object against our schema jsonschema.validate(instance=intermediary_object, schema=intermediary_schema) user_object = {'user': { # Assign the deserialized data from intermediary object 'name': intermediary_object['name'], # Add in protected data in object definition (or set it from a class constructor) 'is_admin': False, } } # Work with the user_object except jsonschema.exceptions.ValidationError as ex: # Gracefully handle validation errors # ... ``` For more details on deserialization attacks in general, see OWASP's guide: - https://cheatsheetseries.owasp.org/cheatsheets/Deserialization_Cheat_Sheet.html
The application was found calling the `eval` function with a non-literal variable. If the variable comes from user-supplied input, an adversary could compromise the entire system by executing arbitrary python code. To remediate this issue, remove all calls to `eval` and consider alternative methods for executing the necessary business logic. There is almost no safe method of calling `eval` with user-supplied input. If the application only needs to convert strings into objects, consider using `json.loads`. In some cases `ast.literal_eval` is recommended, but this should be avoided as it can still suffer from other issues such as the ability for malicious code to crash the python interpreter or application. Example using `json.loads`` to load in arbitrary data to create data structures: ``` # User supplied data as a blob of JSON user_supplied_data = """{"user": "test", "metadata": [1,2,3]}""" # Load the JSON user_object = json.loads(user_supplied_data) # Manually add protected properties _after_ loading, never before user_object["is_admin"] = False # Work with the object ```
Detected use of the wildcard character in a system call that spawns a shell.This subjects the wildcard to normal shell expansion, which can have unintended consequencesif there exist any non-standard file names. Consider a file named `-e sh script.sh`.
Starting a process with a shell; seems safe, but may be changed in the future, consider rewriting without shell
Starting a process with a shell; seems safe, but may be changed in the future, consider rewriting without shell
Unverified SSL context detected. This will permit insecure connections without `verifyingSSL` certificates. Use `ssl.create_default_context()` instead.
Found dynamic content when spawning a process. This is dangerous if externaldata can reach this function call because it allows a malicious actor toexecute commands. Ensure no external data reaches here.
Python possesses many mechanisms to invoke an external executable. However, doing so may present a security issue if appropriate care is not taken to sanitize any user provided or variable input. This plugin test is part of a family of tests built to check for process spawning and warn appropriately. Specifically, this test looks for the spawning of a subprocess without the use of a command shell. This type of subprocess invocation is not vulnerable to shell injection attacks, but care should still be taken to ensure validity of input.
Found `subprocess` function `$FUNC` with `shell=True`. This is dangerous because this call will spawn the command using a shell process. Doing so propagates current shell settings and variables, which makes it much easier for a malicious actor to execute commands. Use `shell=False` instead.
subprocess call - check for execution of untrusted input
The application was found calling the `logging.config.listen`` function, which provides the ability to listen for external configuration files over a socket server. This listen socket parses part of the configuration and calls `eval` on the supplied configuration file. A local user, or an adversary who is able to exploit a Server Side Request Forgery (SSRF) attack to communicate over localhost, would be able to execute arbitrary code by passing in a logging config that contains python code. To remediate the issue, remove the call to `logging.config.listen` method. For more information on the listen functionality see: - https://docs.python.org/3/library/logging.config.html#logging.config.listen
Depending on the context, generating weak random numbers may expose cryptographic functions, which rely on these numbers, to be exploitable. When generating numbers for sensitive values such as tokens, nonces, and cryptographic keys, it is recommended that the `secrets` module be used instead. Example using the secrets module: ``` import secrets # Generate a secure random 64 byte array random_bytes = secrets.token_bytes(64) print(random_bytes) # Generate a secure random 64 byte array as a hex string random_bytes_hex = secrets.token_hex(64) # Generate a secure random 64 byte array base64 encoded for use in URLs random_string = secrets.token_urlsafe(64) ``` For more information on the `secrets` module see: - https://docs.python.org/3/library/secrets.html
The application was found using the `requests` module without configuring a timeout value for connections. This could lead to uncontrolled resource consumption where the application could run out of socket descriptors, effectively causing a Denial of Service (DoS). To remediate this issue, pass in a `timeout=` argument to each `requests` call. Example using a timeout for an HTTP GET request: ``` # Issue a GET request to https://example.com with a timeout of 10 seconds response = requests.get('https://example.com', timeout=10) # Work with the response object # ... ``` For more information on using the requests module see: - https://requests.readthedocs.io/en/latest/api/
SQL Injection is a critical vulnerability that can lead to data or system compromise. By dynamically generating SQL query strings, user input may be able to influence the logic of the SQL statement. This could lead to an adversary accessing information they should not have access to, or in some circumstances, being able to execute OS functionality or code. Replace all dynamically generated SQL queries with parameterized queries. In situations where dynamic queries must be created, never use direct user input, but instead use a map or dictionary of valid values and resolve them using a user supplied key. For example, some database drivers do not allow parameterized queries for `>` or `<` comparison operators. In these cases, do not use a user supplied `>` or `<` value, but rather have the user supply a `gt` or `lt` value. The alphabetical values are then used to look up the `>` and `<` values to be used in the construction of the dynamic query. The same goes for other queries where column or table names are required but cannot be parameterized. Example using `PreparedStatement` queries: ``` import sqlite3 # Create a new database (in memory) con = sqlite3.connect(":memory:") # Get a cursor from the connection cur = con.cursor() # Create a tuple of the value to be used in the parameterized query params = ('user-input',) # execute the statement, passing in the params for the value cur.execute("select name from sqlite_master where name = ?", params) # work with the result result = cur.fetchall() ``` For more information on SQL Injection see OWASP: https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html
The application was found calling an SSL module with SSL or TLS protocols that have known deficiencies. It is strongly recommended that newer applications use TLS 1.2 or 1.3 and `SSLContext.wrap_socket`. If using the `pyOpenSSL` module, please note that it has been deprecated and the Python Cryptographic Authority strongly suggests moving to use the [pyca/cryptography](https://github.com/pyca/cryptography) module instead. To remediate this issue for the `ssl` module, create a new TLS context and pass in `ssl.PROTOCOL_TLS_CLIENT` for clients or `ssl.PROTOCOL_TLS_SERVER` for servers to the `ssl.SSLContext(...)` `protocol=` argument. When converting the socket to a TLS socket, use the new `SSLContext.wrap_socket` method instead. Example creating a TLS 1.3 client socket connection by using a newer version of Python (3.11.4) and the SSL module: ``` import ssl import socket # Create our initial socket with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock: # Connect the socket sock.connect(('www.example.org', 443)) # Create a new SSLContext with protocol set to ssl.PROTOCOL_TLS_CLIENT # This will auto-select the highest grade TLS protocol version (1.3) context = ssl.SSLContext(protocol=ssl.PROTOCOL_TLS_CLIENT) # Load our a certificates for server certificate authentication context.load_verify_locations('cert.pem') # Create our TLS socket, and validate the server hostname matches with context.wrap_socket(sock, server_hostname="www.example.org") as tls_sock: # Send some bytes over the socket (HTTP request in this case)\ data = bytes('GET / HTTP/1.1\r\nHost: example.org\r\n\r\n', 'utf-8') sent_bytes = tls_sock.send(data) # Validate number of sent bytes # ... # Read the response resp = tls_sock.recv() # Work with the response # ... ``` For more information on the ssl module see: - https://docs.python.org/3/library/ssl.html For more information on pyca/cryptography and openssl see: - https://cryptography.io/en/latest/openssl/
The application was found creating a SSL context using the `_create_unverified_context`. This effectively disables the validation of server certificates. This allows for an adversary who is in between the application and the target host to intercept potentially sensitive information or transmit malicious data. To remediate this issue remove the call to `_create_unverified_context` and either create a default context using `ssl.create_default_context` or create a context with TLS 1.3. Example creating a TLS 1.3 client socket connection by using a newer version of Python (3.11.4) and the SSL module: ``` import ssl import socket # Create our initial socket with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock: # Connect the socket sock.connect(('www.example.org', 443)) # Create a new SSLContext with protocol set to ssl.PROTOCOL_TLS_CLIENT # This will auto-select the highest grade TLS protocol version (1.3) context = ssl.SSLContext(protocol=ssl.PROTOCOL_TLS_CLIENT) # Load our a certificates for server certificate authentication context.load_verify_locations('cert.pem') # Create our TLS socket, and validate the server hostname matches with context.wrap_socket(sock, server_hostname="www.example.org") as tls_sock: # Send some bytes over the socket (HTTP request in this case)\ data = bytes('GET / HTTP/1.1\r\nHost: example.org\r\n\r\n', 'utf-8') sent_bytes = tls_sock.send(data) # Validate number of sent bytes # ... # Read the response resp = tls_sock.recv() # Work with the response # ... ``` Unverified SSL context detected. This will permit insecure connections without `verifyingSSL` certificates. Use `ssl.create_default_context()` instead.
The application was found creating files in shared system temporary directories (`/tmp` or `/var/tmp`) without using the `tempfile.TemporaryFile` function. Depending on how the application uses this temporary file, an attacker may be able to create symlinks that point to other files prior to the application creating or writing to the target file, leading to unintended files being created or overwritten. Example using `tempfile.TemporaryFile` to write a file: ``` import tempfile # Open a new temporary file using a context manager with tempfile.TemporaryFile() as fp: # Write some data to the temporary file fp.write(b'Some data') # Seek back to beginning of file fp.seek(0) # Read it data = fp.read() # File is automatically closed/removed once we exit the with context ``` For more information on alternative tempfile functions see: - https://docs.python.org/3/library/tempfile.html
The application was found passing in a non-literal value to the `urllib` methods which issue requests. `urllib` supports the `file://` scheme, which may allow an adversary who can control the URL value to read arbitrary files on the file system. To remediate this issue either hardcode the URLs being used in urllib or use the `requests` module instead. Example using the `requests` module to issue an HTTPS request: ``` import requests # Issue a GET request to https://example.com with a timeout of 10 seconds response = requests.get('https://example.com', timeout=10) # Work with the response object # ... ```
Pysnmp was detected using versions SNMPv1 or SNMPv2. SNPMv1 and SNMPv2 are insecure and should no longer be used as they do not offer encryption. If possible, query SNMP devices using SNMPv3 instead. Example querying a device using SNMPv3 with SHA-AES: ``` from pysnmp.hlapi import * # Create the snpm iterator iterator = getCmd( SnmpEngine(), # Configure using SHA AES UsmUserData('usr-sha-aes', 'authkey1', 'privkey1', authProtocol=USM_AUTH_HMAC96_SHA, privProtocol=USM_PRIV_CFB128_AES), UdpTransportTarget(('demo.snmplabs.com', 161)), ContextData(), ObjectType(ObjectIdentity('SNMPv2-MIB', 'sysDescr', 0)) ) ``` For more information on using SNMPv3 with `Pysnmp` see: - https://pysnmp.readthedocs.io/en/latest/examples/hlapi/v3arch/asyncore/sync/manager/cmdgen/snmp-versions.html#snmpv3-auth-sha-privacy-aes128
Pysnmp was detected using SNMPv3 without authentication or encryption protections enabled. When calling `UsmUserData`, the first argument should be in the format of `usr-<authtype>-<encryption type>`. To remediate this issue, the `UsmUserData` should be configured with `usr-sha-aes` for SHA authentication and AES encryption. Example querying a device using SNMPv3 with SHA-AES: ``` from pysnmp.hlapi import * # Create the snpm iterator iterator = getCmd( SnmpEngine(), # Configure using SHA AES UsmUserData('usr-sha-aes', 'authkey1', 'privkey1', authProtocol=USM_AUTH_HMAC96_SHA, privProtocol=USM_PRIV_CFB128_AES), UdpTransportTarget(('demo.snmplabs.com', 161)), ContextData(), ObjectType(ObjectIdentity('SNMPv2-MIB', 'sysDescr', 0)) ) ``` For more information on using SNMPv3 with `Pysnmp` see: - https://pysnmp.readthedocs.io/en/latest/examples/hlapi/v3arch/asyncore/sync/manager/cmdgen/snmp-versions.html#snmpv3-auth-sha-privacy-aes128
The application was found to ignore host keys. Host keys are important as they provide assurance that the client can prove that the host is trusted. By ignoring these host keys, it is impossible for the client to validate the connection is to a trusted host. To remediate this issue, remove the call to `set_missing_host_key_policy(...)` which sets the host key policy. Instead, load key files using either `load_system_host_keys` or `load_host_keys` to only allow known good hosts. By not setting a host key policy for unknown hosts, `paramiko`'s default policy is to use `RejectPolicy`. Example configuration connecting to a known, trusted host, and not allowing connections to unknown hosts: ``` import paramiko # Create an SSH client with paramiko.SSHClient() as ssh: # Load the system host keys so we can confirm the # host we are connecting to is legitimate ssh.load_system_host_keys('/home/appuser/.ssh/known_hosts') # Connect to the remote host using our SSH private key ssh.connect(hostname='example.org', port=22, username='appuser', key_filename='/home/appuser/.ssh/private_key') ``` For more information on `set_missing_host_key_policy` see: - https://docs.paramiko.org/en/stable/api/client.html#paramiko.client.SSHClient.set_missing_host_key_policy
The application was found using the `xml.etree` package for processing XML. Pythons default xml processors suffer from various XML parsing vulnerabilities and care must be taken when handling XML data. Additionally, depending on the version of Python, more critical vulnerabilities such as eXternal XML Entity injection maybe exploitable. The `etree` package suffers from the following security risks as of Python 3.7.1: * Billion laughs / exponential entity expansion - May allow an adversary to cause a Denial of Service (DoS) against the application parsing arbitrary XML. * Quadratic blowup entity expansion - Similar to above, but requires a larger input to cause the Denial of Service. To remediate the above issues, consider using the [defusedxml](https://pypi.org/project/defusedxml/) library when processing untrusted XML. Example parsing an XML document using defusedxml: ``` from defusedxml.ElementTree import parse # Parse the inventory.xml file et = parse('inventory.xml') # Get the root element root = et.getroot() # Work with the root element # ... ``` For more information on the various XML parsers and their vulnerabilities please see: - https://docs.python.org/3/library/xml.html#xml-vulnerabilities For more information on XML security see OWASP's guide: - https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html#python
The application was found using the `xml.etree` package for processing XML. Pythons default xml processors suffer from various XML parsing vulnerabilities and care must be taken when handling XML data. Additionally, depending on the version of Python, more critical vulnerabilities such as eXternal XML Entity injection maybe exploitable. The `etree` package suffers from the following security risks as of Python 3.7.1: * Billion laughs / exponential entity expansion - May allow an adversary to cause a Denial of Service (DoS) against the application parsing arbitrary XML. * Quadratic blowup entity expansion - Similar to above, but requires a larger input to cause the Denial of Service. To remediate the above issues, consider using the [defusedxml](https://pypi.org/project/defusedxml/) library when processing untrusted XML. Example parsing an XML document using defusedxml: ``` from defusedxml.ElementTree import parse # Parse the inventory.xml file et = parse('inventory.xml') # Get the root element root = et.getroot() # Work with the root element # ... ``` For more information on the various XML parsers and their vulnerabilities please see: - https://docs.python.org/3/library/xml.html#xml-vulnerabilities For more information on XML security see OWASP's guide: - https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html#python
The application was found using the `lxml.etree` package for processing XML. Python's default XML processors suffer from various XML parsing vulnerabilities and care must be taken when handling XML data. Additionally, depending on the version of Python, more critical vulnerabilities such as eXternal XML Entity injection maybe exploitable. The `etree` package suffers from the following security risks as of Python 3.7.1: * Billion laughs / exponential entity expansion - May allow an adversary to cause a Denial of Service (DoS) against the application parsing arbitrary XML. * Quadratic blowup entity expansion - Similar to above, but requires a larger input to cause the Denial of Service. To remediate the above issues, consider using the [defusedxml](https://pypi.org/project/defusedxml/) library when processing untrusted XML. Example parsing an XML document using defusedxml: ``` from defusedxml.ElementTree import parse # Parse the inventory.xml file et = parse('inventory.xml') # Get the root element root = et.getroot() # Work with the root element # ... ``` For more information on the various XML parsers and their vulnerabilities please see: - https://docs.python.org/3/library/xml.html#xml-vulnerabilities For more information on XML security see OWASP's guide: - https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html#python

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 subprocess function '$FUNC' without a static string. If this data can be controlled by a malicious actor, it may be an instance of command injection. Audit the use of this call to ensure it is not controllable by an external resource. You may consider using 'shlex.escape()'.

Detected MD5 hash algorithm which is considered insecure. MD5 is not collision resistant and is therefore not suitable as a cryptographic signature. Use SHA256 or SHA3 instead.
The application was found using the `xml.dom.expatbuilder` which calls the `xml.dom.minidom` package for processing XML. Python's default XML processors suffer from various XML parsing vulnerabilities and care must be taken when handling XML data. Additionally, depending on the version of Python, more critical vulnerabilities such as eXternal XML Entity injection maybe exploitable. The `xml.dom.minidom` package suffers from the following security risks as of Python 3.7.1: * Billion laughs / exponential entity expansion - May allow an adversary to cause a Denial of Service (DoS) against the application parsing arbitrary XML. * Quadratic blowup entity expansion - Similar to above, but requires a larger input to cause the Denial of Service. To remediate the above issues, consider using the [defusedxml](https://pypi.org/project/defusedxml/) library when processing untrusted XML. Example parsing an XML document using defusedxml: ``` from defusedxml.ElementTree import parse # Parse the inventory.xml file et = parse('inventory.xml') # Get the root element root = et.getroot() # Work with the root element # ... ``` For more information on the various XML parsers and their vulnerabilities please see: - https://docs.python.org/3/library/xml.html#xml-vulnerabilities For more information on XML security see OWASP's guide: - https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html#python
The application was found using the `xml.sax.expatreader` package for processing XML. Python's default XML processors suffer from various XML parsing vulnerabilities and care must be taken when handling XML data. Additionally, depending on the version of Python, more critical vulnerabilities such as eXternal XML Entity injection maybe exploitable. The `xml.sax` package suffers from the following security risks as of Python 3.7.1: * Billion laughs / exponential entity expansion - May allow an adversary to cause a Denial of Service (DoS) against the application parsing arbitrary XML. * Quadratic blowup entity expansion - Similar to above, but requires a larger input to cause the Denial of Service. To remediate the above issues, consider using the [defusedxml](https://pypi.org/project/defusedxml/) library when processing untrusted XML. Example parsing an XML document using defusedxml: ``` from defusedxml.ElementTree import parse # Parse the inventory.xml file et = parse('inventory.xml') # Get the root element root = et.getroot() # Work with the root element # ... ``` For more information on the various XML parsers and their vulnerabilities please see: - https://docs.python.org/3/library/xml.html#xml-vulnerabilities For more information on XML security see OWASP's guide: - https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html#python
The application was found using the `xml.dom.minidom` package for processing XML. Python's default XML processors suffer from various XML parsing vulnerabilities and care must be taken when handling XML data. Additionally, depending on the version of Python, more critical vulnerabilities such as eXternal XML Entity injection maybe exploitable. The `xml.dom.minidom` package suffers from the following security risks as of Python 3.7.1: * Billion laughs / exponential entity expansion - May allow an adversary to cause a Denial of Service (DoS) against the application parsing arbitrary XML. * Quadratic blowup entity expansion - Similar to above, but requires a larger input to cause the Denial of Service. To remediate the above issues, consider using the [defusedxml](https://pypi.org/project/defusedxml/) library when processing untrusted XML. Example parsing an XML document using defusedxml: ``` from defusedxml.ElementTree import parse # Parse the inventory.xml file et = parse('inventory.xml') # Get the root element root = et.getroot() # Work with the root element # ... ``` For more information on the various XML parsers and their vulnerabilities please see: - https://docs.python.org/3/library/xml.html#xml-vulnerabilities For more information on XML security see OWASP's guide: - https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html#python
The application was found using the `xml.dom.pulldom` package for processing XML. Python's default XML processors suffer from various XML parsing vulnerabilities and care must be taken when handling XML data. Additionally, depending on the version of Python, more critical vulnerabilities such as eXternal XML Entity injection maybe exploitable. The `xml.dom.pulldom` package suffers from the following security risks as of Python 3.7.1: * Billion laughs / exponential entity expansion - May allow an adversary to cause a Denial of Service (DoS) against the application parsing arbitrary XML. * Quadratic blowup entity expansion - Similar to above, but requires a larger input to cause the Denial of Service. To remediate the above issues, consider using the [defusedxml](https://pypi.org/project/defusedxml/) library when processing untrusted XML. Example parsing an XML document using defusedxml: ``` from defusedxml.ElementTree import parse # Parse the inventory.xml file et = parse('inventory.xml') # Get the root element root = et.getroot() # Work with the root element # ... ``` For more information on the various XML parsers and their vulnerabilities please see: - https://docs.python.org/3/library/xml.html#xml-vulnerabilities For more information on XML security see OWASP's guide: - https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html#python
The application was found using the `xml.sax` package for processing XML. Python's default XML processors suffer from various XML parsing vulnerabilities and care must be taken when handling XML data. Additionally, depending on the version of Python, more critical vulnerabilities such as eXternal XML Entity injection maybe exploitable. The `xml.sax` package suffers from the following security risks as of Python 3.7.1: * Billion laughs / exponential entity expansion - May allow an adversary to cause a Denial of Service (DoS) against the application parsing arbitrary XML. * Quadratic blowup entity expansion - Similar to above, but requires a larger input to cause the Denial of Service. To remediate the above issues, consider using the [defusedxml](https://pypi.org/project/defusedxml/) library when processing untrusted XML. Example parsing an XML document using defusedxml: ``` from defusedxml.ElementTree import parse # Parse the inventory.xml file et = parse('inventory.xml') # Get the root element root = et.getroot() # Work with the root element # ... ``` For more information on the various XML parsers and their vulnerabilities please see: - https://docs.python.org/3/library/xml.html#xml-vulnerabilities For more information on XML security see OWASP's guide: - https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html#python

Unsafe usage of mutable initializer with attr.s decorator. Multiple instances of this class will re-use the same data structure, which is likely not the desired behavior. Consider instead: replace assignment to mutable initializer (ex. dict() or {}) with attr.ib(factory=type) where type is dict, set, or list

Use 'django.db.models.OneToOneField' instead of 'ForeignKey' with unique=True. 'OneToOneField' is used to create one-to-one relationships.

Avoid using null on string-based fields such as CharField and TextField. If a string-based field has null=True, that means it has two possible values for "no data": NULL, and the empty string. In most cases, it's redundant to have two possible values for "no data;" the Django convention is to use the empty string, not NULL.

Flask class method GET with side effects

Detected explicitly unescaped content using 'Markup()'. This permits the unescaped data to include unescaped HTML which could result in cross-site scripting. Ensure this data is not externally controlled, or consider rewriting to not use 'Markup()'.

Password is exposed through JWT token payload. This is not encrypted and the password could be compromised. Do not store passwords in JWT tokens.

Hardcoded JWT secret or private key is used. This is a Insufficiently Protected Credentials weakness: https://cwe.mitre.org/data/definitions/522.html Consider using an appropriate security mechanism to protect the credentials (e.g. keeping secrets in environment variables)

Detected JWT token decoded with 'verify=False'. This bypasses any integrity checks for the token which means the token could be tampered with by malicious actors. Ensure that the JWT token is verified.

The 'FTP' class sends information unencrypted. Consider using the 'FTP_TLS' class instead.

Detected a request using 'http://'. This request will be unencrypted. Use 'https://' instead.

Detected a request using 'http://'. This request will be unencrypted. Use 'https://' instead.

The 'ssl' module disables insecure cipher suites by default. Therefore, use of 'set_ciphers()' should only be used when you have very specialized requirements. Otherwise, you risk lowering the security of the SSL channel.

Detected an unsecured transmission channel. 'OpenerDirector.open(...)' is being used with 'ftp://'. Information sent over this connection will be unencrypted. Consider using SFTP instead. urllib does not support SFTP, so consider a library which supports SFTP.

Detected a 'urllib.request.Request()' object using an insecure transport protocol, 'ftp://'. This connection will not be encrypted. Consider using SFTP instead. urllib does not support SFTP natively, so consider using a library which supports SFTP.

Detected a 'urllib.request.Request()' object using an insecure transport protocol, 'http://'. This connection will not be encrypted. Use 'https://' instead.

Detected 'urllib.urlopen()' using 'http://'. This request will not be encrypted. Use 'https://' instead.

Detected an insecure transmission channel. 'URLopener.open(...)' is being used with 'ftp://'. Use SFTP instead. urllib does not support SFTP, so consider using a library which supports SFTP.

Avoid using `shelve`, which uses `pickle`, which is known to lead to code execution vulnerabilities. When unpickling, the serialized data could be manipulated to run arbitrary code. Instead, consider serializing the relevant data as JSON or a similar text-based serialization format.

Detected SHA1 hash algorithm which is considered insecure. SHA1 is not collision resistant and is therefore not suitable as a cryptographic signature. Use SHA256 or SHA3 instead.

The requests library has a convenient shortcut for sending JSON requests, which lets you stop worrying about serializing the body yourself. To use it, replace `body=json.dumps(...)` with `json=...`.

Detected SHA1 hash algorithm which is considered insecure. SHA1 is not collision resistant and is therefore not suitable as a cryptographic signature. Use SHA256 or SHA3 instead.

Certificate verification has been explicitly disabled. This permits insecure connections to insecure servers. Re-enable certification validation.

Detected string concatenation or formatting in a call to a command via 'sh'. This could be a command injection vulnerability if the data is user-controlled. Instead, use a list and append the argument.

Distinct, Having, Group_by, Order_by, and Filter in SQLAlchemy can cause sql injections if the developer inputs raw SQL into the before-mentioned clauses. This pattern captures relevant cases in which the developer inputs raw SQL into the distinct, having, group_by, order_by or filter clauses and injects user-input into the raw SQL with any function besides "bindparams". Use bindParams to securely bind user-input to SQL statements.

Only comparison operators should be used inside SQLAlchemy filter expressions. Use `==` instead of `is`, `!=` instead of `is not`, `sqlalchemy.and_` instead of `and`, `sqlalchemy.or_` instead of `or`, `sqlalchemy.not_` instead of `not`, and `sqlalchemy.in_` instead of `in_`.

There's an HTTP request made with requests, but the raise_for_status() utility method isn't used. This can result in request errors going unnoticed and your code behaving in unexpected ways, such as if your authorization API returns a 500 error while you're only checking for a 401.

Detected a 'requests' call without a timeout set. By default, 'requests' calls wait until the connection is closed. This means a 'requests' call without a timeout will hang the program if a response is never received. Consider setting a timeout for all 'requests'.

The requests library has a convenient shortcut for reading JSON responses, which lets you stop worrying about deserializing the response yourself.

NumPy distutils is deprecated, and will be removed in the future

Compiling arbitrary code can result in code execution. Ensure the source code is from a trusted location

Using the NumPy RNG inside of a PyTorch dataset can lead to a number of issues with loading data, including identical augmentations. Instead, use the random number generators built into Python and PyTorch

Loading custom operator libraries can result in arbitrary code execution

Loading custom operator libraries can result in arbitrary code execution

Functions reliant on pickle can result in arbitrary code execution

Loading custom operator libraries can result in arbitrary code execution

Avoid importing torch.package - it can result in arbitrary code execution via pickle

Scikit `joblib` uses pickle under the hood. Functions reliant on pickle can result in arbitrary code execution. Consider using `skops` instead.

Possible path traversal through `tarfile.open($PATH).extractall()` if the source tar is controlled by an attacker

Loading custom operator libraries can result in arbitrary code execution

Not waiting for requests is a source of undefined behavior

Found a class extending 'SafeString', 'SafeText' or 'SafeData'. These classes are for bypassing the escaping engine built in to Django and should not be used directly. Improper use of this class exposes your application to cross-site scripting (XSS) vulnerabilities. If you need this functionality, use 'mark_safe' instead and ensure no user data can reach it.

If unverified user data can reach the `run` or `create` method it can result in running arbitrary container.

Detected the use of an insecure deserialization library in a Flask route. These libraries are prone to code execution vulnerabilities. Ensure user data does not enter this function. To fix this, try to avoid serializing whole objects. Consider instead using a serializer such as JSON.

Authentication detected over HTTP. HTTP does not provide any encryption or protection for these authentication credentials. This may expose these credentials to unauthorized parties. Use 'https://' instead.

Avoiding SQL string concatenation: untrusted input concatenated with raw SQL query can result in SQL Injection. In order to execute raw query safely, prepared statement should be used. SQLAlchemy provides TextualSQL to easily used prepared statement with named parameters. For complex SQL composition, use SQL Expression Language or Schema Definition Language. In most cases, SQLAlchemy ORM will be a better option.

These permissions `$BITS` are widely permissive and grant access to more people than may be necessary. A good default is `0o644` which gives read and write access to yourself and read access to everyone else.

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

The Python 'os' tempnam|tmpnam functions are vulnerable to symlink attacks

Insecure XML parsing functionality, prefer 'defusedxml'

The Python 'yaml' module's `load`, `load_all`, `dump`, and `dump_all` functions are not secure against maliciously constructed input

The Python 'compile' function is not secure against maliciously constructed input

The Python 'zipfile' extract|extractall functions are vulnerable to arbitrary file overwrites

The Python 'tarfile' extract|extractall functions are vulnerable to arbitrary file overwrites

The Python 'subprocess' module called with 'shell=True' may allow for shell injection

The Python 'dl' module may cause segmentation faults or other incorrect behavior

The Python 'gl' module may cause core dumps or other unsafe behavior

Detected 'create_subprocess_exec' function without a static string. If this data can be controlled by a malicious actor, it may be an instance of command injection. Audit the use of this call to ensure it is not controllable by an external resource. You may consider using 'shlex.escape()'.

Detected 'create_subprocess_exec' function with user controlled data. You may consider using 'shlex.escape()'.

Detected subprocess function '$LOOP.subprocess_exec' without a static string. If this data can be controlled by a malicious actor, it may be an instance of command injection. Audit the use of this call to ensure it is not controllable by an external resource. You may consider using 'shlex.escape()'.

Detected subprocess function '$LOOP.subprocess_exec' with user controlled data. You may consider using 'shlex.escape()'.

Detected asyncio subprocess function without a static string. If this data can be controlled by a malicious actor, it may be an instance of command injection. Audit the use of this call to ensure it is not controllable by an external resource. You may consider using 'shlex.escape()'.

Detected asyncio subprocess function with user controlled data. You may consider using 'shlex.escape()'.

Found dynamic content inside InteractiveConsole/InteractiveInterpreter method. This is dangerous if external data can reach this function call because it allows a malicious actor to run arbitrary Python code. Ensure no external data reaches here.

Found user controlled data inside InteractiveConsole/InteractiveInterpreter method. This is dangerous if external data can reach this function call because it allows a malicious actor to run arbitrary Python code.

Found user controlled content in `run_in_subinterp`. This is dangerous because it allows a malicious actor to run arbitrary Python code.

Found user controlled data inside InteractiveConsole/InteractiveInterpreter method. This is dangerous if external data can reach this function call because it allows a malicious actor to run arbitrary Python code.

Found user controlled content when spawning a process. This is dangerous because it allows a malicious actor to execute commands.

Found user controlled content when spawning a process. This is dangerous because it allows a malicious actor to execute commands.

Found user controlled content in `run_string`. This is dangerous because it allows a malicious actor to run arbitrary Python code.

Detected subprocess function '$FUNC' with user controlled data. A malicious actor could leverage this to perform command injection. You may consider using 'shlex.escape()'.

Found user-controlled data used in a system call. This could allow a malicious actor to execute commands. Use the 'subprocess' module instead, which is easier to use without accidentally exposing a command injection vulnerability.

Found user controlled content in `run_in_subinterp`. This is dangerous because it allows a malicious actor to run arbitrary Python code.

Found usage of the 'blocksize' argument in a HTTPConnection call. This is only available on Python 3.7+ and is therefore not backwards compatible. Remove this in order for this code to work in Python 3.6 and below.

Found usage of the 'blocksize' argument in a HTTPSConnection call. This is only available on Python 3.7+ and is therefore not backwards compatible. Remove this in order for this code to work in Python 3.6 and below.

Found usage of 'importlib.abc.ResourceReader'. This module is only available on Python 3.7+ and is therefore not backwards compatible. Instead, use another loader.

Class $C inherits from both `$A` and `$B` which both have a method named `$F`; one of these methods will be overwritten.

Function $F mutates default list $D. Python only instantiates default function arguments once and shares the instance across the function calls. If the default function argument is mutated, that will modify the instance used by all future function calls. This can cause unexpected results, or lead to security vulnerabilities whereby one function consumer can view or modify the data of another function consumer. Instead, use a default argument (like None) to indicate that no argument was provided and instantiate a new list at that time. For example: `if $D is None: $D = []`.

Found usage of 'importlib.abc.ResourceReader'. This module is only available on Python 3.7+ and is therefore not backwards compatible. Instead, use another loader.

IPv6Network.subnet_of is only available on Python 3.7+ and is therefore not backwards compatible. Instead, check if the subnet is in 'subnets'.

IPv6Network.supernet_of is only available on Python 3.7+ and is therefore not backwards compatible. Instead, check if the supernet is in 'supernet'.