Ricardo Tavares

May 10, 2023

XSS in JSON POST requests (demo included)

Cross-site-scripting (XSS) is often identified in web development as an issue with user-submitted content that allows for unexpected HTML/CSS/JS to run in the context of other users. Most web developers know that, for example, a field for the name of a user may allow for a script tag to be saved along with it and, if so, that Javascript will later run in the browser for every person that opens a list with that user. Often, this issue is managed by sanitizing these fields to make sure no HTML tags are present or by replacing those characters with HTML entities. This is not a simple matter as prevention should also involve some Content-Security-Policy header, but your average web dev is, at the very least, aware of how this vulnerability might work.

There are however other forms of XSS that do not happen directly inside a web UI and therefore may escape the radar of web devs. Some may not be aware that a vulnerable web service may also be leveraged by an attacker to execute code on its domain and therefore gain potencial access to cookies and local storage, for example. Such an attack is demonstrated in this repository:

t-var-s/xsspost: demo of reflected XSS in POST requests


In this case, the vulnerability exists mainly in the fact that the web service is reflecting parameters sent by the request. Some web devs may not be aware that having this happen in a POST method does not prevent the possibility of an attack. A form crafted by an attacker can POST to that endpoint and benefit from its parameters getting reflected. In this example, the vulnerability is leveraged by sending a simple survey to a victim that may be a user of the target domain. If the victim pays no attention to the jump between domains and how the ending page only shows up after a flash of JSON, the attacker can potentially steal private data without raising any suspicion. However, there are several factors than can prevent this attack. The servers.js file in the repository is annotated with several warnings that could help if followed: 

  • A broad solution would be to have a Content-Security-Policy with something like script-src 'none' since a web service responding with JSON most likely needs to run zero Javascript.
  • Another important header is to set Content-Type as application/json since that will make the browser apply HTML entities when rendering the JSON it gets as a response.
  • Another issue might be the fact that this web service not only accepts JSON requests, but also any urlencoded parameters that may come from a form. Is this necessary? 
  • Finally, the cookie set by this web service is not HTTP-only and is therefore exposed to the Javascript later ran by the attacker in its domain. 

I hope these factors may help you assess how serious a XSS vulnerability might be in a similar context. Perhaps your choice of framework already accounts for this, but sometimes there might be some unexpected behaviour, specially if you're managing any legacy code. On the other hand, if you find anything in the repository that might be wrong or could be improved, please raise an issue or make a pull request. Thank you for reading.  

About Ricardo Tavares

Creates things with computers to understand what problems they can solve. Passionate for an open web that anyone can contribute to. Works in domains where content is king and assumptions are validated quickly.

Mastodon  |  Twitter  |  GitHub

View From the Web