apisecurity, xss, cross-site-scripting, rest-api,

Why Appropriate Content-Type Header Matters In REST API Security: Ft. JSON XSS.

Manikanta S Manikanta S Follow Dec 28, 2023 · 2 mins read
Why Appropriate Content-Type Header Matters In REST API Security: Ft. JSON XSS.
Share this

Before diving into the specifics of the Content-Type header, let’s quickly recap what REST APIs are all about. REST is an architectural style for designing networked applications. It is based on a set of constraints that encourage the use of standardized HTTP methods like GET, POST, PUT, and DELETE for communication between a client (usually a web or mobile application) and a server.

In a RESTful interaction, data is exchanged using various HTTP headers, such as “Accept” and “Content-Type.” These headers provide essential information about the content and structure of the data being sent or received.

The Content-Type header is an essential part of HTTP headers used to convey information about the media type or format of the data in the body of an HTTP message, whether it’s a request or a response. This information is vital for both the client and server to interpret and handle the data correctly.

Cross-Site Scripting in REST API

In general, Cross-Site Scripting (XSS) typically does not work in JSON API responses when the Content-Type header is set to “application/json” because the JSON format inherently does not allow the execution of scripts embedded within the response data.

When a web browser receives a response with a Content-Type of “application/json,” it treats the content as pure data and does not execute any JavaScript code within it. Unlike HTML, which can include script tags that execute JavaScript code, JSON is not processed in the same way.

How I got the Cross-Site Scripting via JSON response

In the recent bug hunting activity, I discovered an API endpoint that returns a 404 status code along with the query parameter value reflected in the response body. But the injected javascript payload will not be executed on the browser due to the “application/json” content-type value in the response.

Verify the “Accept” header.

Then I tied the acceptance of the “text/html” content type by replacing the “Accept” header value with “text/html”.

The API accept the “text/html” content-type. Observe the content-type header value in the below image.

How can we control the “Accept” header.

As per the MDN documentation, for navigation requests the “Accept” header default values are text/html, application/xhtml+xml, application/xml;q=0.9, */*;q=0.8. Therefore, the browser by default, sets the “Accept” header value with “text/html”

When a legitimate user makes a request to this API, their browser interprets the JSON data as HTML, executes the injected script.

Conclusion:

  • Ensure that your API requests and responses use the appropriate Content-Type header that accurately represents the data being exchanged. Use “application/json” for JSON data
  • Bug Hunters: Verify the “text/html” content-type acceptance to ensure the security of the API.
Join Newsletter
Get the latest news right in your inbox. We never spam!
Manikanta S
Written by Manikanta S Follow
Hi, I am a computer security enthusiast, Indian security researcher, and BugHunter.