Don’t forget content type

Victor Mutai
1 min readApr 14, 2021

Giving back JSON responses from the backends directly to the browser is pretty common and simple. However, there are a few things to keep in mind:

  • JSON typically doesn’t escape/encode special characters (like “greater than”, “less than” signs). E.g. a JSON response can contain something like this:
{
"success": false, "message": "<script>malicious_payload()</script> not found"
}
  • If there is no content typeset for the response the browsers will treat it as HTML by default.
  • If the content type is HTML and the endpoint serving the JSON content is called directly from the browser the HTML content (e.g. malicious javascript code) in the JSON gets executed.

Example:

from django.http import HttpResponse
from rest_framework.views import APIView
class ExampleView(APIView):
return HttpResponse({
'code': '<script>console.log("executed")</script>'
})

By default, HttpResponse content-type is text/html that means any malicious code in the JSON response won’t be escaped and could lead to running arbitrary javascript code when calling the endpoint. In the above example, console.log will be executed every time the page loads.

The fix:

return HttpResponse({
'code': '<script>console.log("executed")</script>'
}, content_type='application/json')

Include content_type=’application/json’ in the Response.

--

--