Alert Origin Spoofing

When we use one of the following JavaScript commands alert,confirm or prompt we always get a popup box with the following text “ says:”.
This prefix can seem negligible, but I assure you  it’s not.
I think this text is a very important security feather, it allows the user to understand what website is requesting or displaying data.

A few months ago I found a very interesting bug that allowed me to create alerts with no origin identification. I was also able to generate this alert on the current active tab as long as my website was running in one of the background tabs.

Since most browser are using the native device alert, when you set a timeout on an alert function it will still be visible from any tab.

$("button").click(function (){"");

The code above will let you run alerts on other domains as long as your using a mobile device. the down side is that it will still start with “ says:” so it’s not that interesting.

Luckily I also found a way to remove the origin, I did it by calling the alert function from from an origin-less page. the results were quite good, on iOS devices I completely remove the origin and on Android it was replaced to the word “JavaScript”.

iOS Simulator Screen Shot May 18, 2015, 2.10.18 PM  android

var myWindow;

$("button").click(function (){
       myWindow ="var password = prompt('Give me your password    please','');; window.close();");

// Callback function
function save(password){
   alert("Password is " + password);

This bug was reported and fixed by Google.


Back in July 2015 I reported an XSS issue to PayPal, it was a DOM XSS on “” 

It’s taken several months but with the issue now fixed I wanted to publish this post.


Let’s Start

I was poking around the checkout iframe PayPal integration on Github when I notice the clientApiUrl parameter contains a URL for a javascript file that the page automatically loads, when you try to change it you get a white page and a bunch of  JavaScript errors.

After a few minutes of digging I found the JavaScript code responsible for validating this URL.

return this._localhostRe.test(url) || this._braintreeDomainRe.test(url);

As you can see there are two validation methods, let’s take a look


The localhost validation regex is allowing any domain that starts with “http://localhost” (I guess the developers used it to test things on a local environment). So… I just need to create a subdomain named localhost on any domain and PayPal will happily load my script.

The exploit worked only on browsers that support mixed content due to the fact we can only load the script on http in order to pass the validation.

To exploit you’d just use the following|created_at=2015-09-30T18:45:01.236715762+0000&merchant_id=yrvvxhf7w35y8v9f&public_key=wmt6n4yhdfp47mbh&paypalBaseUrl=


Hope you guys found this post interesting, any questions or feedback, drop a comment below!