Skip to main content

Insecure service configuration - BREACH Attack

Need

Secure service configuration to prevent BREACH attacks

Context

  • Usage of Python 3.0+ for developing Python applications
  • Usage of Django for building web applications in Python

Description

Non compliant code

# settings.py
from django.conf import settings

MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

# Enable gzip middleware
MIDDLEWARE.append('django.middleware.gzip.GZipMiddleware')

# views.py
from django.shortcuts import render
from django.views.decorators.csrf import csrf_exempt

@csrf_exempt
def user_input(request):
user_text = request.GET.get('user_text', '')
return render(request, 'input.html', {'user_text': user_text})

In the above code, we have a Django backend application with insecure service configuration that makes it vulnerable to BREACH attacks.

  1. GZip Middleware: The application uses GZip middleware which enables HTTP gzip compression. This is one of the conditions that make the application vulnerable to BREACH attacks.

  2. User Input Reflection: In the user_input view function, the application takes user input and reflects it back in the response. This is another condition that makes the application vulnerable to BREACH attacks.

  3. CSRF Exemption: The @csrf_exempt decorator is used to exempt the view from CSRF protection. This is a bad practice as it makes the application vulnerable to CSRF attacks, and in this context, it also contributes to the conditions for a BREACH attack.

  4. Secrets Storage: Django stores secrets such as session tokens and CSRF tokens. In a BREACH attack, an attacker can potentially guess these secrets by observing the size of encrypted responses.

To fix this vulnerability, you should disable HTTP compression, avoid reflecting user input in HTTP response bodies, ensure all views are protected by CSRF checks, and consider other measures to protect secrets such as using HTTPS and SameSite cookies.

Steps

  • Remove the GZipMiddleware from the middleware list in settings.py. This will disable HTTP gzip compression, which is one of the conditions for a BREACH attack.
  • Avoid reflecting user input directly on the site. In the user_input view, instead of directly passing the user_text to the template, consider using it in a way that doesn't reflect it directly in the HTML.
  • Implement a method to randomize the secrets (session tokens or anti-CSRF) per request. This can be done by using a different secret for each request or by adding a random number of bytes to the secret for each request.
  • Consider using HTTPS instead of HTTP. This will encrypt the data between the client and the server, making it harder for an attacker to exploit the BREACH vulnerability.

Compliant code

# settings.py
from django.conf import settings

MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

# views.py
from django.shortcuts import render
from django.views.decorators.csrf import csrf_protect

@csrf_protect
def user_input(request):
user_text = request.GET.get('user_text', '')
# Use the user_text in a way that doesn't reflect it directly in the HTML
# For example, you could store it in the session or use it to filter a queryset
request.session['user_text'] = user_text
return render(request, 'input.html')

The updated code includes several changes to mitigate the risk of a BREACH attack:

  1. HTTP gzip compression is disabled: The GZipMiddleware has been removed from the MIDDLEWARE list in settings.py. This middleware was responsible for compressing HTTP responses, which is one of the conditions that make a site vulnerable to BREACH attacks.

  2. User input is not directly reflected on the site: In the user_input view, the user_text is no longer passed directly to the template. Instead, it is stored in the session. This prevents the user input from being reflected directly in the HTML, which is another condition for a BREACH attack.

  3. CSRF protection is enforced: The csrf_exempt decorator has been replaced with the csrf_protect decorator. This ensures that the view is protected against cross-site request forgery attacks, which can be used to exploit a BREACH vulnerability.

  4. Secrets are randomized per request: Although not shown in the code, it is recommended to implement a method to randomize the secrets (session tokens or anti-CSRF) per request. This can be done by using a different secret for each request or by adding a random number of bytes to the secret for each request.

  5. HTTPS is recommended: Although not shown in the code, it is recommended to use HTTPS instead of HTTP. This will encrypt the data between the client and the server, making it harder for an attacker to exploit the BREACH vulnerability.

References