Can I rely on Content-Type: text / plain to mitigate malicious javascript execution in response?

We have a web application that returns


HTTP/1.1 400 Bad Request ... Content-Type: text/plain;charset=UTF-8 Content-Length: 57 Date: Tue, 14 Apr 2015 19:24:54 GMT Connection: close Invalid project area item id <script>alert(1086)</script> 

I understand that relying on Content-Type: text / plain; charset = UTF-8 as protection to prevent javascript from executing is NOT sufficient. Rather, the output should be encoded, and the input should probably be checked for input and garbage discarded.

What I'm looking for is some kind of crystal clear and official answer to the right approach for handling responses with javascript where the Content-Type was set to text / plain.

Who has a link (or answer) to an official example of this scenario and the correct way to handle it? Or Content-Type: text / plain; charset = utf-8 is all that is needed?

+6
source share
3 answers

Here are two scenarios.

Top level xss

In case an attacker can manipulate the top-level URL in response to an invalid request, for example

 HTTP/1.1 400 Bad Request ... <script>alert(document.cookie)</script> 

then setting Content-Type: text/plain mitigates the XSS attack (see detailed answer below).

AJAX XSS

If, however, an attacker can manipulate some AJAX function on the target web page and trick it into doing something like $("#result").html(xss_request_result) , and then efficiently load the text into the web context, and it will be analyzed by the browser (including JS), and all bets are disabled .

It is advisable to entity-encode or tag-strip the response of such error messages.


Regarding the first scenario, according to w3.org ,

The main subtype of the text is "simple." This indicates plain (unformatted) text. By default, Content-Type for Internet mail "text / plain; charset = us-ascii" describes existing Internet practice, that is, it is a body type defined by RFC 822.

This means that / plain text should not be interpreted or processed. However, Google (updated March 30, 2011) indicates

If the Content-Type matches one of the common values, for example application / octet-stream, application / unknown, or even text / plain , many browsers see this as a second-time resolution based on the above signals and try to come up with something more specific . The rationale for this step is that some poorly configured web servers revert to these types in all returned content.

According to a browser review sniffing under the title Is HTML falsified into text / plain documents (with or without a file extension in the URL)? , results:

  • Internet Explorer 9+: No
  • Firefox: No
  • Opera: No
  • Chrome: No
  • Android: No
  • Safari: Yes

So yes, setting the content type to text / plain with an explicit character set will reduce XSS attacks, but from the above review, Safari may be delayed.

Test your browser for this vulnerability. Go to the more generous PHP PHP site (e.g. http://phptester.net/ ) and do the following. You should not receive a popup.

 <?php header("Content-Type: text/plain"); echo "<script>alert(1)</script>"; 

Read more on XSS Attack Attacks (PDF)

+7
source

The Drakes answer above bothered me, so I created a simple proof of concept to make sure I was right. I. Even with Content-Type: text/plain;charset=UTF-8 application can be compromised with a simple XSS attack.

The reason I tried to explain below for the first time is because the data processing and the possible context of the final destination and data rendering are important. Transport is not so important. I created a simple servlet that returns a response in the same way as an OP, including the Content-Type header. Here is the answer:

 HTTP/1.1 400 Bad Request Server: Apache-Coyote/1.1 Cache-Control: no-cache Content-Type: text/plain;charset=UTF-8 Content-Length: 73 Date: Thu, 18 Jun 2015 22:49:01 GMT Connection: close Invalid project area item id <iframe src=javascript:alert(1)></iframe> 

And here is the image of the result. Please note that the attack payload has been executed: https://flic.kr/p/uRnSgo

Again, the reason is very simple. Data is not displayed in an AJAX request, but on a consumer web application page that has an HTML page.

In any case, I hope that in some cases it eliminates any doubts about the vulnerability ... especially when the response to the AJAX request that will be displayed on the consumption page.

----- Below is my initial answer. -----

A 400 response with an error message drops out of the REST API response.

If it was a REST request ( X-Requested-With: XMLHttpRequest or Accept: application/json in the request headers), you are facing a serious problem. Although this answer is not affected, the data is likely to be displayed and displayed in the end user UI on the consumption page. Since it is not correctly encoded, it performs . This is not always the answer you need to worry about, but the possible location of the attack payload. Assuming this is a response to an XMLHttpRequest or REST call, this is a serious error.

You can test using the <iframe src=javascript:alert(1)></iframe> attack payload, and I'm sure you will see that pop in the consuming application.

I would suggest: Invalid project area item id and leave an invalid value. The cheapest solution.

So you cannot rely on Content-Type at all to save you. Data may be displayed in a different context where .

Always check the input and correctly process the output, which may include encoding in some format or in another, depending on the context in which it will be displayed. Anyone who tells you otherwise is trying to get out of some necessary work. :-)

+1
source

https://tools.ietf.org/html/rfc2046 "text / plain" should not process the type of instruction and is considered simply as a linear sequence of characters.

0
source

Source: https://habr.com/ru/post/989296/


All Articles