Skip to content

Commit

Permalink
Update rule metadata. (#1643)
Browse files Browse the repository at this point in the history
  • Loading branch information
Jeremi Do Dinh committed Nov 13, 2023
1 parent 3c7b6b1 commit c957e33
Show file tree
Hide file tree
Showing 6 changed files with 319 additions and 291 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ <h2>Ask Yourself Whether</h2>
<h2>Recommended Secure Coding Practices</h2>
<p>Do not enable debugging features on production servers or applications distributed to end users.</p>
<h2>Sensitive Code Example</h2>
<pre>
<p>Django application startup:</p>
<pre data-diff-id="1" data-diff-type="noncompliant">
from django.conf import settings

settings.configure(DEBUG=True) # Sensitive when set to True
Expand All @@ -19,14 +20,40 @@ <h2>Sensitive Code Example</h2>
def custom_config(config):
settings.configure(default_settings=config, DEBUG=True) # Sensitive
</pre>
<p>Django’s "settings.py" or "global_settings.py" configuration file:</p>
<pre>
# NOTE: The following code raises issues only if the file is named "settings.py" or "global_settings.py". This is the default
# name of Django configuration file

<p>Inside <code>settings.py</code> or <code>global_settings.py</code>, which are the default configuration files for a Django application:</p>
<pre data-diff-id="2" data-diff-type="noncompliant">
DEBUG = True # Sensitive
DEBUG_PROPAGATE_EXCEPTIONS = True # Sensitive
</pre>
<p>Flask application startup:</p>
<pre data-diff-id="3" data-diff-type="noncompliant">
from flask import Flask

app = Flask()
app.debug = True # Sensitive
app.run(debug=True) # Sensitive
</pre>
<h2>Compliant Solution</h2>
<pre data-diff-id="1" data-diff-type="compliant">
from django.conf import settings

settings.configure(DEBUG=False)
settings.configure(DEBUG_PROPAGATE_EXCEPTIONS=False)

def custom_config(config):
settings.configure(default_settings=config, DEBUG=False)
</pre>
<pre data-diff-id="2" data-diff-type="compliant">
DEBUG = False
DEBUG_PROPAGATE_EXCEPTIONS = False
</pre>
<pre data-diff-id="3" data-diff-type="compliant">
from flask import Flask

app = Flask()
app.debug = False
app.run(debug=False)
</pre>
<h2>See</h2>
<ul>
<li> <a href="https://owasp.org/Top10/A05_2021-Security_Misconfiguration/">OWASP Top 10 2021 Category A5</a> - Security Misconfiguration </li>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,67 +113,6 @@ <h4>Using trusted certificates</h4>
<h4>Working with self-signed certificates or non-standard CAs</h4>
<p>In some cases, you might need to work with a server using a self-signed certificate, or a certificate issued by a CA not included in your trusted
roots. Rather than disabling certificate validation in your code, you can add the necessary certificates to your trust store.</p>
<h2>How to fix it in HTTPX</h2>
<h3>Code examples</h3>
<p>The following code contains examples of disabled certificate validation.</p>
<p>The certificate validation gets disabled by setting <code>verify</code> to <code>False</code>. To enable validation set the value to
<code>True</code> or do not set <code>verify</code> at all to use the secure default value.</p>
<h4>Noncompliant code example</h4>
<pre data-diff-id="31" data-diff-type="noncompliant">
import httpx

httpx.get('https://example.com', verify=False) # Noncompliant
</pre>
<h4>Compliant solution</h4>
<pre data-diff-id="31" data-diff-type="compliant">
import httpx

# By default, certificate validation is enabled
httpx.get('https://example.com')
</pre>
<h3>How does this work?</h3>
<p>Addressing the vulnerability of disabled TLS certificate validation primarily involves re-enabling the default validation.</p>
<p>To avoid running into problems with invalid certificates, consider the following sections.</p>
<h4>Using trusted certificates</h4>
<p>If possible, always use a certificate issued by a well-known, trusted CA for your server. Most programming environments come with a predefined list
of trusted root CAs, and certificates issued by these authorities are validated automatically. This is the best practice, and it requires no
additional code or configuration.</p>
<h4>Working with self-signed certificates or non-standard CAs</h4>
<p>In some cases, you might need to work with a server using a self-signed certificate, or a certificate issued by a CA not included in your trusted
roots. Rather than disabling certificate validation in your code, you can add the necessary certificates to your trust store.</p>
<h2>How to fix it in aiohttp</h2>
<h3>Code examples</h3>
<p>The following code contains examples of disabled certificate validation.</p>
<p>The certificate validation gets disabled by setting <code>verify_ssl</code> to <code>False</code>. To enable validation set the value to
<code>True</code> or do not set <code>verify_ssl</code> at all to use the secure default value.</p>
<h4>Noncompliant code example</h4>
<pre data-diff-id="41" data-diff-type="noncompliant">
import aiohttp

async def example():
async with aiohttp.ClientSession() as session:
session.get("https://example.com", verify_ssl=False) # Noncompliant
</pre>
<h4>Compliant solution</h4>
<pre data-diff-id="41" data-diff-type="compliant">
import aiohttp

# By default, certificate validation is enabled

async def example():
async with aiohttp.ClientSession() as session:
session.get("https://example.com")
</pre>
<h3>How does this work?</h3>
<p>Addressing the vulnerability of disabled TLS certificate validation primarily involves re-enabling the default validation.</p>
<p>To avoid running into problems with invalid certificates, consider the following sections.</p>
<h4>Using trusted certificates</h4>
<p>If possible, always use a certificate issued by a well-known, trusted CA for your server. Most programming environments come with a predefined list
of trusted root CAs, and certificates issued by these authorities are validated automatically. This is the best practice, and it requires no
additional code or configuration.</p>
<h4>Working with self-signed certificates or non-standard CAs</h4>
<p>In some cases, you might need to work with a server using a self-signed certificate, or a certificate issued by a CA not included in your trusted
roots. Rather than disabling certificate validation in your code, you can add the necessary certificates to your trust store.</p>
<h2>Resources</h2>
<h3>Standards</h3>
<ul>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,25 @@ <h4>Use a secure algorithm</h4>
<p>It is highly recommended to use an algorithm that is currently considered secure by the cryptographic community. A common choice for such an
algorithm is the Advanced Encryption Standard (AES).</p>
<p>For block ciphers, it is not recommended to use algorithms with a block size that is smaller than 128 bits.</p>
<h2>How to fix it in ssl</h2>
<h3>Code examples</h3>
<p>The following code contains examples of algorithms that are not considered highly resistant to cryptanalysis and thus should be avoided.</p>
<h4>Noncompliant code example</h4>
<pre data-diff-id="41" data-diff-type="noncompliant">
import ssl

ciphers = 'RC4-SHA:RC4-MD5'
ctx = ssl.create_default_context()
ctx.set_ciphers(ciphers) # Noncompliant
</pre>
<h4>Compliant solution</h4>
<pre data-diff-id="41" data-diff-type="compliant">
import ssl

ctx = ssl.create_default_context()
</pre>
<h3>How does this work?</h3>
<p>It is recommended to not override the ciphers but instead, use the secure default ciphers of the module, as they might change over time.</p>
<h2>Resources</h2>
<h3>Standards</h3>
<ul>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,49 @@ <h4>Rotate your secret keys</h4>
<p>Even with the strongest cipher algorithms, there is a risk that your secret keys may be compromised. Therefore, it is a good practice to
periodically rotate your secret keys. By doing so, you limit the amount of time that an attacker can misuse a stolen key. When you rotate keys, be
sure to allow a grace period where tokens signed with the old key are still accepted to prevent service disruptions.</p>
<h2>How to fix it in python-jose</h2>
<h3>Code examples</h3>
<p>The following code contains an example of JWT decoding without verification of the signature.</p>
<h4>Noncompliant code example</h4>
<pre data-diff-id="111" data-diff-type="noncompliant">
from jose import jwt

jwt.decode(token, None, options={"verify_signature": False}) # Noncompliant
</pre>
<h4>Compliant solution</h4>
<p>By default, verification is enabled for the methods <code>decode</code> and <code>verify</code>.</p>
<pre data-diff-id="111" data-diff-type="compliant">
from jose import jwt

jwt.decode(token, key, algorithms=["HS256"])
</pre>
<h3>How does this work?</h3>
<h4>Verify the signature of your tokens</h4>
<p>Resolving a vulnerability concerning the validation of JWT token signatures is mainly about incorporating a critical step into your process:
validating the signature every time a token is decoded. Just having a signed token using a secure algorithm is not enough. If you are not validating
signatures, they are not serving their purpose.</p>
<p>Every time your application receives a JWT, it needs to decode the token to extract the information contained within. It is during this decoding
process that the signature of the JWT should also be checked.</p>
<p>To resolve the issue follow these instructions:</p>
<ol>
<li> Use framework-specific functions for signature verification: Most programming frameworks that support JWTs provide specific functions to not
only decode a token but also validate its signature simultaneously. Make sure to use these functions when handling incoming tokens. </li>
<li> Handle invalid signatures appropriately: If a JWT’s signature does not validate correctly, it means the token is not trustworthy, indicating
potential tampering. The action to take on encountering an invalid token should be denying the request carrying it and logging the event for further
investigation. </li>
<li> Incorporate signature validation in your tests: When you are writing tests for your application, include tests that check the signature
validation functionality. This can help you catch any instances where signature verification might be unintentionally skipped or bypassed. </li>
</ol>
<p>By following these practices, you can ensure the security of your application’s JWT handling process, making it resistant to attacks that rely on
tampering with tokens. Validation of the signature needs to be an integral and non-negotiable part of your token handling process.</p>
<h3>Going the extra mile</h3>
<h4>Securely store your secret keys</h4>
<p>Ensure that your secret keys are stored securely. They should not be hard-coded into your application code or checked into your version control
system. Instead, consider using environment variables, secure key management systems, or vault services.</p>
<h4>Rotate your secret keys</h4>
<p>Even with the strongest cipher algorithms, there is a risk that your secret keys may be compromised. Therefore, it is a good practice to
periodically rotate your secret keys. By doing so, you limit the amount of time that an attacker can misuse a stolen key. When you rotate keys, be
sure to allow a grace period where tokens signed with the old key are still accepted to prevent service disruptions.</p>
<h2>Resources</h2>
<h3>Standards</h3>
<ul>
Expand Down

0 comments on commit c957e33

Please sign in to comment.