#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
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.
manually creating a defaultdict - use collections.defaultdict(set)
manually creating a defaultdict - use collections.defaultdict(list)
Class `$A` has defined `__eq__` which means it should also have defined `__hash__`;
file object opened without corresponding close
`pass` is the body of function $X. Consider removing this or raise NotImplementedError() if this is a TODO
`pass` is the body of for $X in $Y. Consider removing this or raise NotImplementedError() if this is a TODO
time.sleep() call; did you mean to leave this in?
this function is only available on Python 3.6+
the `errors` argument to Popen is only available on Python 3.6+
the `encoding` argument to Popen is only available on Python 3.6+
source_hash' is only available on Python 3.7+. This does not work in lower versions, and therefore is not backwards compatible. Instead, use another hash function.
Found 'importlib.resources', which is a module only available on Python 3.7+. This does not work in lower versions, and therefore is not backwards compatible. Use importlib_resources instead for older Python versions.
Detected use of the 'none' algorithm in a JWT token. The 'none' algorithm assumes the integrity of the token has already been verified. This would allow a malicious actor to forge a JWT token that will automatically be verified. Do not explicitly use the 'none' algorithm. Instead, use an algorithm such as 'HS256'.
.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.
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.
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
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
snapshot.assert_match makes use of pathlib to create files. Patching $METHOD may result in unexpected snapshot behavior
The application was found using `cPickle` 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
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.
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.
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'.
IPv4Network.subnet_of is only available on Python 3.7+ and is therefore not backwards compatible. Instead, check if the subnet is in 'subnets'.
IPv4Network.supernet_of is only available on Python 3.7+ and is therefore not backwards compatible. Instead, check if the supernet is in 'supernet'.
Found usage of the 'monetary' argument in a function call of 'locale.format_string'. This is only available on Python 3.7+ and is therefore not backwards compatible. Instead, remove the 'monetary' argument.
math.remainder is only available on Python 3.7+ and is therefore not backwards compatible. Instead, use math.fmod() or calculate $X - n* $Y.
multiprocessing.Process.close() is only available on Python 3.7+ and is therefore not backwards compatible. Instead, use join().
multiprocessing.Process.kill() is only available on Python 3.7+ and is therefore not backwards compatible. Instead, use terminate().
os.preadv() is only available on Python 3.7+ and is therefore not backwards compatible. Instead, use a combination of os.readv() and os.pread().
pdb.set_trace() with the header argument is only available on Python 3.7+ and is therefore not backwards compatible. Instead, use set_trace() without the header argument.
Found identical comparison using is. Ensure this is what you intended.
Found string comparison using 'is' operator. The 'is' operator is for reference equality, not value equality, and therefore should not be used to compare strings. For more information, see https://github.com/satwikkansal/wtfpython#-how-not-to-use-is-operator"
In Python 'X is not ...' is different from 'X is (not ...)'. In the latter the 'not' converts the '...' directly to boolean.
An insecure SSL version was detected. TLS versions 1.0, 1.1, and all SSL versions are considered weak encryption and are deprecated. Use 'ssl.PROTOCOL_TLSv1_2' or higher.
Detected a possible YAML deserialization vulnerability. `yaml.unsafe_load`, `yaml.Loader`, `yaml.CLoader`, and `yaml.UnsafeLoader` are all known to be unsafe methods of deserializing YAML. An attacker with control over the YAML input could create special YAML input that allows the attacker to run arbitrary Python code. This would allow the attacker to steal files, download and install malware, or otherwise take over the machine. Use `yaml.safe_load` or `yaml.SafeLoader` instead.
Avoid using unsafe `ruamel.yaml.YAML()`. `ruamel.yaml.YAML` can create arbitrary Python objects. A malicious actor could exploit this to run arbitrary code. Use `YAML(typ='rt')` or `YAML(typ='safe')` instead.
Avoid using `dill`, 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 use of an insecure MD4 or MD5 hash function. These functions have known vulnerabilities and are considered deprecated. Consider using 'SHA256' or a similar function instead.
The Python documentation recommends using `defusedxml` instead of `xml` because the native Python `xml` library is vulnerable to XML External Entity (XXE) attacks. These attacks can leak confidential data and "XML bombs" can cause denial of service.
Detected use of xmlrpc. xmlrpc is not inherently safe from vulnerabilities. Use defusedxml.xmlrpc instead.
Data from request is passed to a file name `$FILE`. This is a path traversal vulnerability, which can lead to sensitive data being leaked. To mitigate, consider using os.path.abspath or os.path.realpath or the pathlib library.
Data from request is passed to os.path.join() and to open(). This is a path traversal vulnerability, which can lead to sensitive data being leaked. To mitigate, consider using os.path.abspath or os.path.realpath or Path library.
Semgrep found a Python reverse shell using $BINPATH to $IP at $PORT
Detected user input used to manually construct a SQL string. This is usually bad practice because manual construction could accidentally result in a SQL injection. An attacker could use a SQL injection to steal or modify contents of the database. Instead, use a parameterized query which is available by default in most database engines. Alternatively, consider using an object-relational mapper (ORM) such as Sequelize which will protect your queries.
An encryption mode of operation is being used without proper message authentication. This can potentially result in the encrypted content to be decrypted by an attacker. Consider instead use an AEAD mode of operation like GCM.
An encryption mode of operation is being used without proper message authentication. This can potentially result in the encrypted content to be decrypted by an attacker. Consider instead use an AEAD mode of operation like GCM.
Detected asyncio subprocess 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 `os` function with argument tainted by `event` object. 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.
Detected subprocess 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 `os` function with argument tainted by `event` object. 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.
The Python third-party 'Crypto' module is unmaintained and has known vulnerabilities and exploits
'ssl.wrap_socket()' is deprecated. This function creates an insecure socket without server name indication or hostname matching. Instead, create an SSL context using 'ssl.SSLContext()' and use that to wrap a socket.
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.
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 consequences if there exist any non-standard file names. Consider a file named '-e sh script.sh' -- this will execute a script when 'rsync' is called. See https://www.defensecode.com/public/DefenseCode_Unix_WildCards_Gone_Wild.txt for more information.
The Python 'shelve' module is not secure against maliciously constructed input
'$VAR' is the empty string and is being used to set the password on '$MODEL'. If you meant to set an unusable password, set the password to None or call 'set_unusable_password()'.
'$VAR' is using the empty string as its default and is being used to set the password on '$MODEL'. If you meant to set an unusable password, set the default value to 'None' or call 'set_unusable_password()'.
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.
Found a template created with string formatting. This is susceptible to server-side template injection and cross-site scripting attacks.
Setting 'WTF_CSRF_ENABLED' to 'False' explicitly disables CSRF protection.
Be careful with `flask.make_response()`. If this response is rendered onto a webpage, this could create a cross-site scripting (XSS) vulnerability. `flask.make_response()` will not autoescape HTML. If you are rendering HTML, write your HTML in a template file and use `flask.render_template()` which will take care of escaping. If you are returning data from an API, consider using `flask.jsonify()`.
Found request data in a call to 'open'. Ensure the request data is validated or sanitized, otherwise it could result in path traversal attacks.
Try, Except, Continue
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
Detected an unsecured transmission channel. 'OpenerDirector.open(...)' is being used with 'http://'. Use 'https://' instead to secure the channel.
Detected 'urllib.urlretrieve()' using 'http://'. This request will not be encrypted. Use 'https://' instead.
The password on '$MODEL' is being set without validating the password. Call django.contrib.auth.password_validation.validate_password() with validation functions before setting the password. See https://docs.djangoproject.com/en/3.0/topics/auth/passwords/ for more information.
This expression will evaluate to be ONLY value the of the `else` clause if the condition `$EXPRESSION` is false. If you meant to do list concatenation, put parentheses around the entire concatenation expression, like this: `['a', 'b', 'c'] + (['d'] if x else ['e'])`. If this is the intended behavior, the expression may be confusing to others, and you may wish to add parentheses for readability.
Is "$FUNC" a function or an attribute? If it is a function, you may have meant $X.$FUNC() because $X.$FUNC is always true.
Generators can only be consumed once, so in most cases, caching them will cause an error when the already-consumed generator is retrieved from cache.
Detected a Jinja2 environment with 'autoescaping' disabled. This is dangerous if you are rendering to a browser because this allows for cross-site scripting (XSS) attacks. If you are in a web context, enable 'autoescaping' by setting 'autoescape=True.' You may also consider using 'jinja2.select_autoescape()' to only enable automatic escaping for certain file extensions.
Detected a Jinja2 environment without autoescaping. Jinja2 does not autoescape by default. This is dangerous if you are rendering to a browser because this allows for cross-site scripting (XSS) attacks. If you are in a web context, enable autoescaping by setting 'autoescape=True.' You may also consider using 'jinja2.select_autoescape()' to only enable automatic escaping for certain file extensions.
Socket is not closed if shutdown fails. When socket.shutdown fails on an OSError, socket.close is not called and the code fails to clean up the socket and allow garbage collection to release the memory used for it. The OSError on shutdown can occur when the remote side of the connection closes the connection first.
Values returned by thread pool map must be read in order to raise exceptions. Consider using `for _ in $EXECUTOR.map(...): pass`.
This is not checking the return value of this subprocess call; if it fails no exception will be raised. Consider subprocess.check_call() instead
Initializing a security context for Dask (`distributed`) without "require_encryption" keyword argument may silently fail to provide security.
If possible, it is better to rely on automatic pinning in PyTorch to avoid undefined behavior and for efficiency
Found usage of the `$FLAVOR` library, which is vulnerable to attacks such as XML external entity (XXE) attacks
Usage of NumPy library inside PyTorch `$MODULE` module was found. Avoid mixing these libraries for efficiency and proper ONNX loading
Functions reliant on pickle can result in arbitrary code execution. Consider using fickling or switching to a safer serialization method
Functions reliant on pickle can result in arbitrary code execution. Consider using fickling or switching to a safer serialization method
Functions reliant on pickle can result in arbitrary code execution. Consider loading from `state_dict`, using fickling, or switching to a safer serialization method like ONNX
key `$Y` in `$X` is assigned twice; the first assignment is useless
The Python 'tempfile.mktemp' function allows for race conditions
Warnings disabled on insecure network requests with Python 'urllib3' module
The Python 'marshal' module is not secure against maliciously constructed input
Weak or insecure 'ssl' module usage
The Python third-party 'requests' module used with SSL verification disabled
The Python 'xmlrpc' module used with 'allow_dotted_names' is not secure against maliciously constructed input
The Python 'commands' module is not secure against maliciously constructed input
The Python 'popen2' module is not secure against maliciously constructed input
The Python third-party 'duo_client' module used with SSL verfication disabled
Weak or insecure 'onelogin' module attribute usage
Weak or insecure 'hashlib' module usage
The Python 'urllib3' module used with SSL verfication disabled
Weak or insecure 'cryptography' module attribute usage
Weak or insecure 'xmlsec' module attribute usage
The Python third-party 'itsdangerous' module used with 'none' signing algorithm
A hard-coded credential was detected. It is not recommended to store credentials in source-code, as this risks secrets being leaked and used by either an internal or external malicious adversary. It is recommended to use environment variables to securely provide credentials or retrieve credentials from a secure vault or HSM (Hardware Security Module).
Detected IDEA cipher algorithm which is considered insecure. The algorithm is considered weak and has been deprecated. Use AES instead.
Detected ECB cipher mode which is considered insecure. The algorithm can potentially leak information about the plaintext. Use CBC mode instead.
Use JsonResponse instead
django.db.backends.base.BaseDatabaseOperations.check_aggregate_support() is removed in Django 2.0.
null=True should be set if blank=True is set on non-text fields.
Detected usage of @csrf_exempt, which indicates that there is no CSRF token set for this route. This could lead to an attacker manipulating the user's account and exfiltration of private data. Instead, create a function without this decorator.
Detected a Custom Expression ''$EXPRESSION'' calling ''as_sql(...).'' This could lead to SQL injection, which can result in attackers exfiltrating sensitive data. Instead, ensure no user input enters this function or that user input is properly sanitized.
This rule is deprecated.
Detected a Context with autoescape disabled. 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'.
`html_safe()` add the `__html__` magic method to the provided class. 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 request data as an index to 'globals()'. This is extremely dangerous because it allows an attacker to execute arbitrary code on the system. Refactor your code not to use 'globals()'.
Found user data in a call to 'eval'. 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.
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.
Found request data in 'send_mail(...)' that uses 'html_message'. This is dangerous because HTML emails are susceptible to XSS. An attacker could inject data into this HTML email, causing XSS.
Data from request object is passed to a new server-side request. This could lead to a server-side request forgery (SSRF), which could result in attackers gaining access to private organization data. 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.
Flask-caching doesn't cache query strings by default. You have to use `query_string=True`. Also you shouldn't cache verbs that can mutate state.
flask.jsonify() is a Flask helper method which handles the correct settings for returning JSON from Flask routes
Found a template created with string formatting. This is susceptible to server-side template injection and cross-site scripting attacks.
Detected Flask app with debug=True. Do not deploy to production with this flag enabled as it will leak sensitive information. Instead, consider using Flask configuration variables or setting 'debug' using system environment variables.
Detected Flask route directly returning a formatted string. This is subject to cross-site scripting if user input can reach the string. Consider using the template engine instead and rendering pages with 'render_template()'.
Detected hardcoded temp directory. Consider using 'tempfile.TemporaryFile' instead.
manually creating a defaultdict - use collections.defaultdict(dict)
The object is passed strictly to jwt.encode(...) Make sure that sensitive information is not exposed through JWT token payload.
manually creating a counter - use collections.Counter
Importing the python debugger; did you mean to leave this in?
os.pwritev() is only available on Python 3.3+ and is therefore not backwards compatible. Instead, use a combination of pwrite() and writev().
`yield` should never appear inside a class __init__ function. This will cause a runtime error.
Function $F mutates default dict $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 dictionary at that time. For example: `if $D is None: $D = {}`.
The Connection.recv() method automatically unpickles the data it receives, which can be a security risk unless you can trust the process which sent the message. Therefore, unless the connection object was produced using Pipe() you should only use the recv() and send() methods after performing some sort of authentication. See more dettails: https://docs.python.org/3/library/multiprocessing.html?highlight=security#multiprocessing.connection.Connection
Unverified SSL context detected. This will permit insecure connections without verifying SSL certificates. Use 'ssl.create_default_context' instead.
FTP does not encrypt communications by default. This can lead to sensitive data being exposed. Ensure use of FTP here does not expose sensitive data.
Telnet does not encrypt communications. Use SSH instead.
Detected a request using 'http://'. This request will be unencrypted, and attackers could listen into traffic on the network and be able to obtain sensitive information. Use 'https://' instead.
Detected 'urllib.urlopen()' using 'ftp://'. This request will not be encrypted. Consider using SFTP instead. urllib does not support SFTP, so consider switching to a library which supports SFTP.
Detected an insecure transmission channel. 'URLopener.retrieve(...)' is being used with 'ftp://'. Use SFTP instead. urllib does not support SFTP, so consider using a library which supports SFTP.
Detected an unsecured transmission channel. 'URLopener.retrieve(...)' is being used with 'http://'. Use 'https://' instead to secure the channel.
Detected a python logger call with a potential hardcoded secret $FORMAT_STRING being logged. This may lead to secret credentials being exposed. Make sure that the logger is not logging sensitive information.
Running `socket.bind` to 0.0.0.0, or empty string could unexpectedly expose the server publicly as it binds to all available interfaces. Consider instead getting correct address from an environment variable or configuration file.
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.
Avoid using `cPickle`, 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 XOR cipher algorithm which is considered insecure. This algorithm is not cryptographically secure and can be reversed easily. Use AES instead.
Detected an insufficient key size for DSA. NIST recommends a key size of 2048 or higher.
Detected an insufficient key size for RSA. NIST recommends a key size of 2048 or higher.
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.
Found non static data as an index to 'globals()'. This is extremely dangerous because it allows an attacker to execute arbitrary code on the system. Refactor your code not to use 'globals()'.
Method $METHOD in API controller $CLASS provides user arg $ARG to requests method $REQMETHOD
Detected string concatenation with a non-literal variable in an aiopg 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 instead. You can create parameterized queries like so: 'cur.execute("SELECT %s FROM table", (user_value,))'.
Detected string concatenation with a non-literal variable in a asyncpg 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.fetch("SELECT $1 FROM table", value)'. You can also create prepared statements with 'Connection.prepare': 'stmt = conn.prepare("SELECT $1 FROM table"); await stmt.fetch(user_value)'
`$X` is uselessly assigned twice inside the creation of the set
key `$X` is uselessly assigned twice
The application was found using `assert` in non-test code. Usually reserved for debug and test code, the `assert` function is commonly used to test conditions before continuing execution. However, enclosed code will be removed when compiling Python code to optimized byte code. Depending on the assertion and subsequent logic, this could lead to undefined behavior of the application or application crashes. To remediate this issue, remove the `assert` calls. If necessary, replace them with either `if` conditions or `try/except` blocks. Example using `try/except` instead of `assert`: ``` # Below try/except is equal to the assert statement of: # assert user.is_authenticated(), "user must be authenticated" try: if not user.is_authenticated(): raise AuthError("user must be authenticated") except AuthError as e: # Handle error # ... # Return, do not continue processing return ```
Binding to all network interfaces can potentially open up a service to traffic on unintended interfaces, that may not be properly documented or secured. By passing "0.0.0.0", "::" or an empty string as the address to the `socket.bind` function, the application will bind to all interfaces. Consider passing in the interface ip address through an environment variable, configuration file, or by determining the primary interface(s) IP address. Example getting the IP address from an environment variable `IP_ADDRESS`: ``` # Get the IP_ADDRESS env variable, or bind to # 127.0.0.1 if it is not set address = os.getenv("IP_ADDRESS", "127.0.0.1") # Create an internet socket sock = socket.socket(socket.AF_INET) # Set the port to listen on port = 9777 # Bind to the address and port combination sock.bind((address, port)) # Listen for connections sock.listen() # Handle the connection ```
The application was found calling the `exec` 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 `exec` 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 ```
The application was found setting file permissions to overly permissive values. Consider using the following values if the application user is the only process to access the file: - 0400 - read only access to the file - 0200 - write only access to the file - 0600 - read/write access to the file Example creating a file with read/write permissions for the application user: ``` # Use octal values to set 0o600 (read/write access to the file) for the current # user os.chmod('somefile.txt', 0o600) ``` For all other values please see: https://en.wikipedia.org/wiki/File-system_permissions#Numeric_notation
The application was found using `shelve` which is vulnerable to deserialization attacks as it calls `pickle` internally. 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
Detected MD2 hash algorithm which is considered insecure. This algorithm has many known vulnerabilities and has been deprecated. Use SHA256 or SHA3 instead.
Detected MD4 hash algorithm which is considered insecure. This algorithm has many known vulnerabilities and has been deprecated. 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.
The application was found creating temporary files with the insecure `mktemp` method. 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. To remediate this issue consider using `tempfile.TemporaryFile` instead. 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
Found use of the native Python XML libraries, which is vulnerable to XML external entity (XXE) attacks. The Python documentation recommends the 'defusedxml' library instead. Use 'defusedxml'. See https://github.com/tiran/defusedxml for more information.
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. It is strongly recommended that a standard digest algorithm be chosen instead as implementing a custom algorithm is prone to errors. Example using `hashlib.sha384()` to create a SHA384 hash: ``` import hashlib # Create a SHA384 digest digest = hashlib.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 digest.digest() ```
The application was found using a telnet library. As telnet does not provide encryption, it is strongly recommended that communications use a more secure transport such as SSH. The [paramiko](https://www.paramiko.org/) library can be used to initiate SSH connections. Example using `paramiko` SSH client: ``` 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') # Work with the connection ``` For more information on the paramiko module see: - https://www.paramiko.org/
The application was found using the `requests` module without configuring a timeout value for connections. The `verify=False` argument has been set, which 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 either remove the `verify=False` argument, or set `verify=True`to each `requests` call. Example verifying server certificates for an HTTP GET request: ``` # Issue a GET request to https://example.com with a timeout of 10 seconds and verify the # server certificate explicitly. response = requests.get('https://example.com', timeout=10, verify=True) # Work with the response object # ... ``` For more information on using the requests module see: - https://requests.readthedocs.io/en/latest/api/
An insecure SSL version was detected. TLS versions 1.0, 1.1, and all SSL versions are considered weak encryption and are deprecated. Use 'ssl.PROTOCOL_TLSv1_2' or higher.
The application was found calling `ssl.wrap_socket` without a TLS protocol version specified. Additionally, `ssl.wrap_socket` has been deprecated since Python 3.7. It is strongly recommended that newer applications use TLS 1.2 or 1.3 and `SSLContext.wrap_socket`. To remediate this issue, 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
`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.
The application was found using Jinja2 `Environment` without autoescaping enabled. 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 Jinja2 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: ``` from jinja2 import Environment, select_autoescape, FileSystemLoader from jinja2 import pass_eval_context from markupsafe import Markup, escape @pass_eval_context def escape_link(eval_ctx, 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 # Alternatively, you could only call escape if autoescape is true # if eval_ctx.autoescape: # return escape(value) # else # return value return escape(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", }) @pass_eval_context def escape_js(eval_ctx, 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. This may still be unsafe depending where used, it does not consider characters used in regular expressions for example. """ #if eval_ctx.autoescape: # value = escape(value) # Escape by default value = escape(value) # Translate any potential characters using our translation table return value.translate(js_replacement) # Create our environment, setting autoescape to use the default # select_autoescape function env = Environment( loader=FileSystemLoader(os.getcwd()+"/template"), autoescape=select_autoescape, ) # Add an escape link filter to be used in our template env.filters["escape_link"] = escape_link env.filters["escape_js"] = escape_js # Load our template file template = env.get_template("mytemplate.html") # Render with different variables which call our filters print(template.render( html_context="<img src=x onerror=alert(1)>", link_context="/# onclick=alert(1)<script>alert(1)</script>", script_context="alert(1);alert`1`",) ) # Sample template: """ <!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> """ ``` For more information on autoescape see: - https://jinja.palletsprojects.com/en/3.1.x/api/#autoescaping For more information on XSS see OWASP: - https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html
Detected DynamoDB query filter that is tainted by `$EVENT` object. This could lead to NoSQL injection if the variable is user-controlled and not properly sanitized. Explicitly assign query params instead of passing data from `$EVENT` directly to DynamoDB client.
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 `pickle` 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 Flask application is running with `debug=True` configured. By enabling this option, certain exceptions or errors could cause sensitive information to be leaked in HTTP responses. Additionally, it is not recommended to run a Flask application using `Flask.run(...)` in production. Instead, a WSGI server such as [gunicorn](https://flask.palletsprojects.com/en/2.3.x/deploying/gunicorn/) or [waitress](https://flask.palletsprojects.com/en/2.3.x/deploying/waitress/) be used instead. For more information on deployment options for Flask applications see: - https://flask.palletsprojects.com/en/2.3.x/deploying/
Detected hardcoded temp directory. Consider using 'tempfile.TemporaryFile' instead.
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. It is strongly recommended that a standard digest algorithm be chosen instead as implementing a custom algorithm is prone to errors. 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, 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 error. 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/
Using 'globals()' as a context to 'render(...)' is extremely dangerous. This exposes Python functions to the template that were not meant to be exposed. An attacker could use these functions to execute code that was not intended to run and could compromise the application. (This is server-side template injection (SSTI)). Do not use 'globals()'. Instead, specify each variable in a dictionary or 'django.template.Context' object, like '{"var1": "hello"}' and use that instead.
Using 'locals()' as a context to 'render(...)' is extremely dangerous. This exposes Python functions to the template that were not meant to be exposed. An attacker could use these functions to execute code that was not intended to run and could compromise the application. (This is server-side template injection (SSTI)). Do not use 'locals()'. Instead, specify each variable in a dictionary or 'django.template.Context' object, like '{"var1": "hello"}' and use that instead.
Untrusted user input in `importlib.import_module()` function allows an attacker to load arbitrary code. Avoid dynamic values in `importlib.import_module()` or use a whitelist to prevent running untrusted code.
Avoid using `jsonpickle`, 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 using `json` module.
Consider possible security implications associated with subprocess module.
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.
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.