Monday, 7 December 2015

A Quick Glance at Modern Browsers's Protection Part #1

tl;dr in this blog post we are going to give a look at modern browsers's protection with some hands on example available at https://github.com/asanso/browsers-security and deployed in Heroku. This blog post is NOT about Same-origin policy

Introduction

In this blog post we are going to give a look at modern browsers's protection. More specifically if you are designing a REST API where the result response is driven by some user input, then why not have some help from the browser rather than brewing some ad hoc protection?
I am going to provide some demo deployed in Heroku .
If you prefer running them on your machine you might want to clone  https://github.com/asanso/browsers-security and drill down into the specific example.

Mind your content type

By definition Content-Type entity-header field indicates the media type of the entity-body sent to the recipient or, in the case of the HEAD method, the media type that would have been sent had the request been a GET
It turns out that returning the proper Content-Type might save a lot of headache. 




Or from your browsers-security check out:
So lets dig the response using curl:

curl -v -L "https://mysterious-ocean-4724.herokuapp.com/?name=<script>alert(document.domain)</script>"

>
< HTTP/1.1 200 OK
* Server Cowboy is not blacklisted
< Server: Cowboy
< Connection: keep-alive
< X-Powered-By: Express
< Content-Type: text/html; charset=utf-8
< Content-Length: 42
< Etag: W/"2a-QK3v/EQbwe/c0QdPJrXydw"
< Date: Wed, 02 Dec 2015 15:16:31 GMT
< Via: 1.1 vegur

{"helloWorld": "<script>alert(
document.domain)</script>"}

As you can see we are returning some JSON payload in the response but using the "wrong" Content-Type (aka text/html). This in combination with a malicious input provided by an attacker will make the browser to happily execute the provided javascript snippet.
Now of course output sanitization (this is always good BTW) would have stopped this attack but this would have required some effort. From the other hand just returning the right Content-Type (application/json in this example ) will make the browser displaying the JSON text content as in this example

https://mysterious-ocean-4724.herokuapp.com/?surname=%3Cscript%3Ealert%28document.domain%29%3C/script%3E

curl -v -L "https://mysterious-ocean-4724.herokuapp.com/?surname=<script>alert(document.domain)</script>" 

< HTTP/1.1 200 OK
* Server Cowboy is not blacklisted
< Server: Cowboy
< Connection: keep-alive
< X-Powered-By: Express
< Content-Type: application/json; charset=utf-8
< Content-Length: 56
< Etag: W/"38-AEX4mYlsmzOHSw8oOicxiQ"
< Date: Mon, 07 Dec 2015 09:39:53 GMT
< Via: 1.1 vegur
<
{"helloWorld":"<script>alert(document.domain)</script>"}


Bonus Part:  
The examples above where targetting a stored XSS. Those are cross browsers and if successful (namley some stored javascript is displayed in some not sanitized output) every browser will happiliy execute the javascript.  For  reflected XSS (where the input is bounced directly in the output) some browsers (Chrome, Safari, IE ) ship with an XSS filter. E.g. try to hit the follow link with Google Chrome


has the result 

The XSS Auditor refused to execute a script in 'https://mysterious-ocean-4724.herokuapp.com/?title=%3Cscript%3Ealert%28document.domain%29%3C/script%3E' because its source code was found within the request. 

and the XSS is then stopped by the browser. From the other hand Firefox would still be vulnerable.

Re-mind your content type

As returning a "wrong" content type you might imagine that not returning a Content-Type AT ALL is NOT a so great idea :) Indeed there are some browsers (did I say IE :)?) that trying to be extra clever and try to  intelligently interpret the response content in order to guess the right Content-Type. In the netsec jargon this is call sniffing. But let's the example talking on its own, using IE ONLY

https://protected-garden-1595.herokuapp.com?name=<script>alert(document.domain)</script>

Again if you prefer running in local then clone https://github.com/asanso/browsers-security/tree/master/noContentType

Trying to inspect the response we can see the total lack of content type:

curl -v -L "https://protected-garden-1595.herokuapp.com?name=<script>alert(document.domain)</script>"

< HTTP/1.1 200 OK
* Server Cowboy is not blacklisted
< Server: Cowboy
< Connection: keep-alive
< Date: Mon, 07 Dec 2015 10:52:54 GMT
< Content-Length: 51
< Via: 1.1 vegur
<
Hello World <script>alert(document.domain)</script>


The solution is obviously is to return the correct  Content-Type hence

TIL: mind you Content-Type

Coming soon...

This concludes the part #1. If you like this stuff you might watch this space for:
  • more about Content-Type
  • nosniff 
  • X-XSS-Protection
  • Content-Disposition
  • Content Security Policy (CSP)
  • Cross-origin resource sharing (CORS)
  • HTTP Strict Transport Security (HSTS)
  • Subresource Integrity (SRI)

2 comments:

欧阳锋 said...

where is part 2?

Antonio Sanso said...

part 2 is yet to come :)