Fix XSS in API Responses in Django
XSS in APIs is often overlooked. If your Django backend returns user-controlled strings in a response without the correct 'Content-Type' or proper serialization, you're handing an attacker a persistent or reflected XSS vector. The goal is to ensure the browser treats the payload as data, not as executable markup.
The Vulnerable Pattern
from django.http import HttpResponse
def user_api(request): # VULNERABLE: Manually building a string and returning it as text/html # An attacker can pass ?name= name = request.GET.get(‘name’, ‘guest’) payload = ’{“name”: “%s”}’ % name return HttpResponse(payload, content_type=‘text/html’)
The Secure Implementation
The vulnerability stems from using 'HttpResponse' with a 'text/html' MIME type while concatenating raw user input. This allows a browser to interpret the JSON-like string as HTML. The fix uses 'JsonResponse', which performs two critical actions: 1. It automatically sets the 'Content-Type' header to 'application/json', instructing the browser not to parse the body as HTML. 2. It utilizes Django's JSON encoder to properly escape characters, ensuring that even if the JSON is somehow rendered in a DOM context, the malicious script remains an inert string.
from django.http import JsonResponse
def user_api(request): # SECURE: Use JsonResponse to handle serialization and headers # This enforces ‘Content-Type: application/json’ and escapes the data name = request.GET.get(‘name’, ‘guest’) data = {‘name’: name} return JsonResponse(data)
Your API Responses API
might be exposed to XSS
74% of API Responses apps fail this check. Hackers use automated scanners to find this specific flaw. Check your codebase before they do.
Free Tier • No Credit Card • Instant Report
Verified by Ghost Labs Security Team
This content is continuously validated by our automated security engine and reviewed by our research team. Ghost Labs analyzes over 500+ vulnerability patterns across 40+ frameworks to provide up-to-date remediation strategies.