Friday, August 14, 2020

Leveraging JSONP to SOME via HTTP Parameter Pollution


When you see a callback control in a JSONP endpoint doesn't that make you want to execute XSS? But, there's always this "text/javascript" (or similar) content-type that stands in the way.

During BlackHat 2014 I presented Same Origin Method Execution (SOME) attack. This talk explains how to abuse callback endpoints to execute javascript methods in a vulnerable domain.

Nowadays, finding vulnerable callback endpoints got harder as passive content-types dominate the web. While the vulnerable, active content-types like "text/html", "Adobe Flash" or "ActiveX plugins" are less common. In the second SOME talk during HackInTheBox 2017, I shared the hint of my ongoing research:

"JSONP is NOT vulnerable without a chain"
(slide 16, under "What are the vulnerable endpoints?")

As I was always "too busy", on Jun 7, 2020, @kinugawamasato released the following tweet:
His callback challenge was similar and inspired me to share my research in the form of a my own XSS challenge.

The Challenge

The challenge goal was: chaining HPP to SOME, then bypass a strict CSP policy and get arbitrary cross-site scripting.

For almost 2 months (Jun 18, 2020 - Aug 14, 2020) only 4 players solved it. Even though, on July 1th, Masato released the solution to his challenge.

The following is a the original tweet:

Challenge Structure

The challenge was consisted of 3 pages:
  1. index.html - Static Page
  2. connect.php - JSONP endpoint 
  3. purify.js - Cure53's DOMPurify

Entry points

  • "client_id" - URL parameter
  • client_id - URL parameter - Limited control of up to 38 characters (<= 38)
  • callback - URL parameter:
    • Limited to classic callback characters:[^a-z0-9.]+/i
    • Blocked the string "write" to avoid using "document.write"

CSP Policy

The script-src directive only allow scripts with a valid nonce (I did not use a random nonce but players were instructed to assume it's dynamic for every page load).

The Challenge Workflow

On page load the index.html page:
  1. Calls "init();" to insert items from the rules array which is defined on the global scope. 
  2. Calls "connect(client_id)" to trigger the JSONP endpoint at "connect.php" while appending client_id as a parameter.
  3. Listen to JSONP which calls back with "callback(response, status)".
  4. Render the response as HTML safely using Purify's sanitize function.

Unintended Solution

Slightly after I uploaded the challenge it was possible to skip the harder steps of the challenge as I forgot to include "base-uri 'none'" - that was quickly fixed.

The Solution

To solve the challenge one had to complete several steps:

  1. Control the method execution using a callback (SOME attack).
  2. Abuse the lack of X-Frame-Options to obtain multiple method execution. 
  3. Inject arbitrary HTML limited to 38 characters.
  4. Bypass CSP to execute XSS while abusing "strict-dynamic".
  5. Navigating the DOM tree to overcome character limits.

During my talk in 2017, I already published the instructions for solving steps 1-2 and step 5 (slide 35) as part of SOME white paper and slides.

Before we dig into the details the following is the challenge solution:

Run the Solution

Here is a simplified version of the solution:

top.frame.rules.push("Error: '<iframe srcdoc='<script></script>'>'","406: Not Acceptable")
top.frame.init("Error: 'x'","406: Not Acceptable")
top.frame.itemsList.lastElementChild.previousSibling.previousSibling.previousSibling.firstElementChild.contentWindow.document.head.firstElementChild.append("Error: '';parent.x=parent.document.scripts//'","406: Not Acceptable")
top.frame.itemsList.lastElementChild.previousSibling.lastElementChild.contentWindow.document.head.firstElementChild.append("Error: '';alert(parent.x[0].nonce)//'","406: Not Acceptable")


Thankfully 4 of the players were above all others and solved this challenge relatively fast! All with the intended solution, though some used shorter and cleaner code to solve.
The first to solve was @kinugawamasato the great, followed by 3 other fantastic players: Roman Shafigullin (@shafigullin), terjanq (@terjanq) and Luan Herrera (@lbherrera_)

Deep Dive

Method Execution via HTTP Parameter Pollution

☑️  Method execution can quite simply be controlled by abusing HPP.

Injecting "%26callback=alert" to the client_id parameter allows us to overwrite the "connect.php" endpoint's callback parameter and therefore get control over the method to execute.

This however will only execute an alert, which will not allow stealing the CSP nonce or executing arbitrary XSS.

Multiple Method Execution

Multiple Method Execution is all about constructing a gadget and reusing existing code.

  1. Setting up 5-6 windows (iframes) based on the amount of methods we want to execute on the challenge page.
  2. Abusing the JSONP endpoint with designated callback parameter by navigating each window context.
  3. Controlling the execution order.

I've described the impact of executing multiple methods using SOME and how it can be as bad or nearly as bad as XSS throughout the SOME white-paper.

Pushing 38 Bytes of Arbitrary HTML

The first real step of the challenge was to "plant" HTML code into a globally defined array named "rules". This could be achieved using the native Array.push function:

	top.frame.rules.push("Error: '<iframe srcdoc='<script></script>'>'","406: Not Acceptable")

Once we have arbitrary HTML in "rules", it is possible to use the JSONP endpoint again, this time to execute the "init()" method defined in a whitelisted script. The code at "init" uses innerHTML to inject the rules array items along with the smuggled 38 bytes of HTML payload!

Injecting the HTML:
top.frame.init("Error: 'x'","406: Not Acceptable")
We now finally have arbitrary HTML injection!

☑️ HTML injection (of 38 bytes)

Bypassing Content Security Policy

The server was setup to block anything but allowed scripts using the following CSP directives:

Reading the policy, one can spot a bold hint I left there, that is the strict-dynamic directive.

This step made quite some players struggle, as it was about abusing strict-dynamic to make a non-"parser-inserted" script element execute javascript code.

What is strict-dynamic?

A simple explanation can be found in

The key super power of strict-dynamic is that it will allow whitelisted scripts to load additional scripts via non-"parser-inserted" script elements.

So how do you create a non-"parser-inserted" script element? Here's an example:
			var s = document.createElement('script');
s.src = "";

That is a great, but at this point in the challenge executing such code is impossible.

Yet, is that the only way we can create non-parser inserted scripts?

Empty Script Nodes

If we carefully read the HTML5 spec we can notice the following:

"A script element has a parser document, which is either null or a Document. Initially, its value must be null. It is set by the HTML parser and the XML parser on script elements they insert, and affects the processing of those elements. script elements with non-null parser documents are known as "parser-inserted"."

So if the script tag has content, it’s already considered as “parser inserted”.

Creating Scripts with null parser documents

The key point players had to figure out is that script tags's parser documents are initially null ("Initially, its value must be null") and therefore, an empty script has a null parser document and will not be executed by the html parser.

Here how to abuse this for solving the challenge:

<iframe srcdoc='<script></script>'></iframe>

Notice this payload is 44 bytes (>38) and is blocked by "connect.php" length limit. Luckily, we can drop the "</iframe>" and the browser will "guess" it needs to close the tag for us. Once we have a non-parser inserted script it is now finally possible to abuse strict-dynamic.

☑️ non-parser inserted scripts

XSS via Node.append

The final part in the challenge can be broken down into 2 main steps

  • Navigate the DOM to obtain a reference to the empty script, and
  • Find a method that allows adding content into the empty non-"parser inserted" script tag.

All there's left to do is to construct a valid javascript code and append it to the script node:

// Returns a refernce to the injected <script> Node
scriptNode.append("Error: '';alert(1337)//'","...")
// Adds content to the script tag and executes

☑️ Bypassing CSP for arbitrary XSS

Run the Solution

This writeup took longer than expected but I hope you enjoy it as much as I enjoyed writing it.

Thanks you all who played!

Thursday, June 18, 2015

Same Origin Method Execution (SOME)

This blog post is a brief presentation of "Same Origin Method Execution" (SOME). SOME is a web application attack which abuses callback endpoints (mainly Flash applets and JSONP endpoints to which OAuth dialogs often redirect to -- redirect_uri) by forcing a victim into executing arbitrary scripting methods of any page on the endpoint’s domain. The impact of a SOME attack is similar to the impact of Cross-Site Scripting, though there are some important and distinguishing exploitation restrictions. In spite of limitations, it is vital and valid to say that the attack is not limited to a specific web functionality/page nor confined in terms of UI or HTTP response headers. In fact, using a payload of only alphanumeric characters and a dot will allow attackers to hijack dangerous web functionality and even exfiltrate sensitive user data such as private photos and/or videos. 
Popular domains like Google, Yahoo, Microsoft (,, and so on) along with the very popular platforms - Wordpress and VideoJS (which turned numerous domains vulnerable to SOME) were affected by SOME. Many were recently fixed (responsible disclosure details are mentioned below).

Paper, Demo and Slides from BlackHat

If you wish to invest your time in exploring the fascinating technical details in-depth, you are encourage to read my white-paper (mirror), or look at the updated Black-Hat presentation. The slides include a demonstration video of a SOME exploit - you can see how I used SOME to hijack Google cloud’s private photo and video albums. 

By the way, you can also find more details about the breach I am talking about in my previous blog post: Stealing private photo albums from Google

Attack Scenario:

To understand the SOME attack we first need to cover some general aspects, so bear with me:
  • Web browsers allow execution of a variety of methods without considering the given arguments, for example: form1.submit(“ignored”,”ignored”); will evaluate exactly as the following natural version: form1.submit(); will. Therefore, an external control over the prefix/padding before the parenthesis (as often given by many callback implementations) would be enough for hijacking dangerous web functionality regardless of the arguments.
  • In an environment with multiple windows and their respective  documents, redirecting any of the documents will re-enforce Same Origin Policy to restrict cross-site window documents’ DOM access. However, web browsers would not delete memory references to other window objects post-redirection. For instance, whenever a document opens a popup window, the browser will add a memory reference pointing to this document and save it as the window.opener property of the new window. Regardless of any redirections this reference would continue to work unless it is explicitly deleted or destroyed.
  • Most callbacks endpoints are designed to only allow a limited set of characters as a callback parameter value. This is commonly done by the following regex [a-zA-Z0-9_\.], or in other words, a char-set consisting of alphanumeric, a dot and an underscore. Let me add that crafting a SOME exploit requires only alphanumeric and a dot charset. 
  • Interaction between different browsing contexts is often applied via callback execution. For instance, Flash applets and/or other callback endpoints (e.g. OAuth dialogs) commonly execute a callback function to notify events to a different browsing context. As a result, in cases where this callback can be controlled via a HTTP parameter, an attacker would be able to control and replace the execution browsing context (e.g. by redirecting the opener window document). Analogically, the function/method that the interpreter executes could also be controlled by the attacker.

Same Origin Method Execution abuses the nature of user agents by forging a setup of windows/frames, in turn redirecting their documents. Using references created by this setup within a callback parameter will allow replacing the execution context with a targeted document and hijacking an existing web functionality within it.

Manipulating a Surface for Method Execution

Initial steps:
  1. Firstly, the attacker has to detect a vulnerable instance - either a plugin or a vulnerable callback endpoint document. A vulnerable instance is the one that leads the browser’s interpreter towards active execution of a function name supplied by a (callback) parameter value.
    Note: Instances that respond with passive mime types like application/json are not vulnerable when accessed directly. 
  2. In the second preparatory step the attacker has to choose a target webpage hosted on the same domain ( Aiming at hijacking a web functionality (e.g. object method, javascript function) of this target webpage, the attacker shall assemble a reference using DOM navigation or a direct reference pointing to it, for example: document.body.privateAlbum.firstChild.nextElementSibling.submit
Setting up the Exploit:
  1. For setting up SOME and creating the appropriate window references, one has to create an exploitation surface/environment by opening a new browsing context (WIN1).

  2. Once the environment is ready, the initiating page (MAIN) shall redirect its document to any desired target page on the endpoint’s domain (
  3. Following the redirection, the new browsing context (WIN1) shall wait for the targeted document’s DOM loading completion.
  4. Once ready, for hijacking a method execution, the new browsing context (WIN1) would redirect its document to the vulnerable instance set with an arbitrary callback parameter, for example:

Demo of designating the execution context for executing an alert:

@Main Page:
function startSOME() {"step1.html");
document.body.addEventListener("click",startSOME); //Popup Blocker trick


function waitForDOM() {

Mitigation and Fix
  1. Static Callbacks - Exploiting Same Origin Method Execution relies on abusing a callback parameter. Many web applications can actually maintain their same existing functionality without having to dynamically set callbacks. Thus, when applicable, websites should use fixed callback values as opposed to externalizing the callback control.
  2. White-list approach – In cases where the web application is designed for supporting more than a single callback per endpoint, or, alternatively, where maintaining a high flexibility is highly important (common in Flash plugins), it is better to set a white-list and match the given callback parameter value against it. This would enforce and verify that only legitimate callback functions can execute.UPDATE: I am working on a JavaScript defense library aiming to serve as a generic and easy to deploy solution.
  3. Cross-Domain Messaging – Use postMessage for notifying events and interacting to and from cross-domains as an alternative to javascript callback execution (if applicable).

Responsible Disclosure:

Oct 30, 2014: Google fixed a vulnerable instance – Google Plus.
Nov 06, 2014: Microsoft fixed a vulnerable instance – Yammer.
April 21, 2015: Wordpress fixed a vulnerable instance – Plupload.

(Kudos to @zoczus for finding yammer and plupload instances)

The issue of callback exploitation is known to a certain level in the infosec community, although until recently the attack did not catch enough attention. For that reason website owners, including the leading players, still rely on developers’ habits and experience. More importantly, no ‘best practice’ or standard was published as of now. Thus I chose to shed some light on Same Origin Method Execution and callback endpoints during the BlackHat conference. Several aspects of Same Origin Method Execution have been discovered by top researchers namely Google's Aleksandr Dobkin and LinkedIn's Roman Shafigullin. They both certainly deserve credit here.

It is noteworthy that Google Bug Bounty deemed this attack’s impact similar to that of cross-site scripting. 

Microsoft Bug Bounty deemed this attack’s impact similar to that of cross-site scripting.

Wordpress classified this attack like "XSS" in their critical security release (Apr. 2015 - WordPress 3.9-4.1.1 - Same-Origin Method Execution).

The Same Origin Method Execution attack can lead to ugly and critically severe consequences for its targeted victims. Keep in mind that the attack’s risk is considered as high as the risk of Cross-site scripting, rated the "third most risky attack" in OWASP top 10 project - that is A3 Cross-site scripting (XSS). To conclude, it is really important to abandon the misconception that a narrow set of characters somehow guarantees safety and security, of your web applications. Further, we should strive to raise the developers’ awareness of SOME.

Monday, May 25, 2015

Stealing Private Photo Albums from Google - Same Origin Method Execution

It has been a long time since I updated this blog since I focused on company blogs and Black Hat presentations for the last couple of years. It is time to kick in with details about the vulnerable Google instance I was demonstrating during my Black Hat EU presentation – Same Origin Method Execution. Using that instance and a payload of only alphanumeric characters and a dot I was able to hijack web functionality and thereby delete or steal private photo albums from Google Plus. A white paper is currently in review stages and will be released next week in my next post! 

Same Origin Policy and OAuth overview:

From time to time and for numerous reasons web applications interact with external third-party services. Some of these reasons may be importing information (e.g. import contact list), notifying events, getting delegated access to resources such providing a "Login with" systems and etc. 

Since an external service often (if not always) means a different security context, interacting with it will require overcoming Same Origin Policy (SOP). One of the most common interfaces for such third-party interaction these days is using OAuthentication dialogs. OAuth dialogs are hosted on third-party resource providers and are designed to ask the resource owner (the user) to allow/deny access from the website to the user's (resource owner) private resources. Once an answer is given the dialog will redirect (call) the user back to a callback page hosted on the website which asked for access, this page is called the “callback endpoint”. The purpose of the callback endpoint is to receive a token from the third-party and notify the requesting website. Although, since no best practice was created for building callback endpoints, the technique web developers use to save the token and notify the initiating page (call it back) is based entirely on developers’ habit and experience. Therefore many times callback endpoints end up prone to “Same Origin Method Execution”.

The vulnerable instance:

How many times have you noticed a "Login with", import contacts or friend lists from third-party service? 

As in many other websites Google Plus provides an option to import external contacts information from third-party resource providers such as Yahoo and Microsoft, Prior to the responsible disclosure the authorization process occurred as follows:

  1. Google Plus opened a pop-up for the OAuth dialog asking secure delegated access to the user’s external contact-list on Yahoo/Microsoft, to avoid losing the currently open document content.  
  2. After the user allows/denies the access, the dialog window document is redirected to a Google Plus callback endpoint consisting a callback URL parameter.
  3. The endpoint page uses the value provided by the parameter to notify the opener and deliver the access token (JSONP style).
Callback endpoint URL:[...snip...]
Accessing the callback endpoint URL directly responded with the following markup:

<html><body><script type="text/javascript">
window.opener.callback_function_name({"status":0,"token":"ItHumYWI[...snip..]","oauthstate":"1234","tokenid":"ToKeN1234","tokenexp":"0","gid":"401223423..","siteid":6,"displayname":"Ben Hayak","profileurl":""});

Is that Cross-site scripting?

Of course the first thing to try here was Cross-site Scripting, although fortunately ;) in similarity to most callback endpoint implementations only a specific set of characters were allowed as a callback value specifically alphanumeric a dot and underscore [A-Za-z0-9_\.]. We can however use tricks like document.write, eval, etc, though as aforementioned in the markup above no user controlled input got inside the parenthesis so XSS is out of the question.

“NULL means no!?”

When accessing the callback endpoint directly the window.opener property is null, so it appears that the instance is not vulnerable. However there is a technique to control the opener window. The first idea that came to mind was to create a bug chain, by finding another page in google plus that will force opening a window with an arbitrary URL and combine that with the callback endpoint. Although finding such a page is a little too rare and will weaken the attack.

Window Objects in memory:

So let’s try different approach, I wanted to entirely control a window and set its document to whatever page in Google Plus and then tell the Google Plus callback endpoint “This is your opener window deal with it”. That’s exactly what you can acheive in “Same Origin Method Execution” all you need is a page that opens another window and a set of redirection and you can designated any window as the opener and start hijacking methods! The key element that makes this a successful approach is the nature of user agents. When a window document is being redirected its window object remains at the original allocated memory space, therefore any other window/s that holds a reference to it as “opener” can still use the reference to access the opener window even after the document changed/redirected.

If window A opens window B, the user agent will create a reference to window A as window.opener property of window B, when window A’s document would change (redirect) the reference won’t be cleared/deleted and window B can still use the opener property to reference it.

So the answer is pretty clear, all there’s left is to make a malicious html that will open another window via “‘/step1.html’)” , then redirect the first window to a designated document on Google Plus, and redirected the pop-up window to the callback endpoint. This way you can set any page as the opener of the callback endpoint.

Stealing Private Photo Albums with SOME:

I covered how to control an opener and abuse a vulnerable callback endpoint to execute any DOM/Javascript function at the context of the opener window. All there’s left is to choose a page containing an interesting web functionality and use only alphanumeric and a dot to assemble a payload that will hijack this web functionality (Similar to the impact of CSRF but we don’t mind CSRFTokens or other protective mechanisms).

The target document I used:

Google Plus can automatically backup private cell photos to Google servers in case G+ is installed as a mobile application on your phone. Fortunately Google created a service called “Google Picker” which allows users to share their photos, videos and documents stored in Google servers with third-party websites.

Now that I've designated a target document (Google Picker) I setup the attack page as follows:
  1. Set a page that opens two pop-up windows to control their opener.
  2. Redirect the page to Google Plus instance of Picker.
  3. Wait for the DOM to complete loading.
  4. Redirect the first pop-up to the vulnerable callback endpoint with a callback parameter set to:
  5. Redirect the second pop-up to the vulnerable callback endpoint with a callback parameter set to: pickerApp.V.Fa.PA which made the service send all the selected photos to my own domain.
  6. Send the malicious setup to a chosen victim (In my case Google Bug bounty responsible disclosure :)
The exploit resulted in hijacking the following JavaScript functions:
  2. window.opener.pickerApp.V.Fa.PA({JSONDATA});

This flow could make any user send every single photo from his/her private album to my server.

BlackHat EU Video:

Additional use cases: 
I exploited the same instance to delete Google Plus timeline posts. 

Note: The issue is now fixed as it has been reported to Google bug bounty program.

Hope you enjoyed reading!

Saturday, May 10, 2014

Deep Analysis of CVE-2014-0502 – A Double Free Story

The Adobe Flash Player zero-day that was part of a targeted attack that infected several nonprofit organizations’ websites.

The vulnerability is a double-free vulnerability caused by a bug in how shared objects are handled by Adobe Flash Player.

The full story:

A double free vulnerability occurs during the termination of adobe flash worker. when a worker is being terminated, all shared objects (also called as "flash cookies") are flushed an then freed from memory. while failing to flush an off limit "shared object" to disk (for being above 100KB data) a garbage collection occurs. the garbage collection decides to free the "shared object" from memory whilst the first free operation is still in process.

a screenshot presenting a "record" shared object while exploiting the vulnerable code and controlling EIP (0xcccccccc+8):

the screenshot blow presents the internal SharedObject destructor procedure, you can notice that there's a flag that checks whether flushing data to disk is required.
the "SharedObject" has data pending for flushing but fails to do so since the data exceeds the 100KB limit. then during the flushing attempt, garbage collection fires and frees the object without clearing this "pending flush" flag.

This specific flow will result in the “Pending Flush” flag being up when the object was already freed, and therefore Adobe Flash Player will try to execute a function from a dereferenced pointer otherwise known as remote code execution. 

I originally posted this post on spiderlabs blog. for more details read the full story.

Wednesday, March 19, 2014

The Kernel is calling a zero(day) pointer – CVE-2013-5065 – Ring Ring

Here's my analysis of a PDF file which contained two different vulnerabilities, a remote-code-execution vulnerability in Adobe Reader and a new escalation-of-privileges zero-day vulnerability in Windows Kernel.

The full story:

A flaw in NDProxy driver while processing Telephony Application Programming Interface (TAPI) operations, was used to cause the Kernel to dispatch out-of-boundaries function. Therefore, one could exploit this vulnerability and gain SYSTEM privileges and bypass different sandbox protections.

The vulnerability allows index control of the following static function table, which get executed in the kernel context:

Dispatching the invalid PxTapi function results access to address 0x0 in memory and crash:

Sunday, November 10, 2013

The Technical Aspects of Exploiting IE Zero-Day CVE-2013-3897

Just last month, during our work at spiderlabs research, the team and myself had the chance to analyze CVE-2013-3897 Use-after-free vulnerability.
This vulnerability was basically a result of an object type CDisplayPointer being freed and used again when a richtext tries to scroll the pointer into the current view.
A flow that includes a selection, that occurs under "onpropertychange" event, and a DOM that contains a textarea structure (detailed below) results a possible remote code execution.

Breaking it to down
1. Create a TEXTAREA and apply a different element as a child using applyElement. This will place theaddress element as the child of the textarea element.
2. Trigger a select event on the TEXTAREA element to create an instance of DisplayPointer.
3. Inside onselect event change the value property of the TEXTAREA element, which in turn will fire the eventonpropertychange. For example, usage of appendChild or swapNode will cause this behavior. 
Notice that id_2 (“address” element) is a child of the TEXTAREA element. By swapping that element we remove it from layout of “textarea” and insert a different element, therefore the value property changes.
4. The event onpropertychange is triggered
5. In the next stage we basically need to change the position of the display pointer within the TEXTAREA layout. In the original exploit document.execCommand(“UnSelect”) was used. However, selecting a different element, executing the SelectAll command or any operation that causes a DisplayPointer position change will also work. 
The attacker used "UnSelect" command
6.  The JavaScript selection causes a call to CDisplayPointer::ScrollIntoView, which tries to set a new position for the DisplayPointer. At this stage, the reference to CMarkupPointer is already released by the CDisplayPointer::Release function (as a result of the “UnSelect” command) and therefore points to an attacker-controlled heap area.
The flow eventually gets into QIClassID, which tries to execute “CMarkupPointer::QueryInterface” (located at offset 0x0 in CMarkupPointer’s virtual table).
QIClassID (use): 
Blog 2
QIClassID disassemble crash point

At the crash we end up with the following stack trace:

CMarkupPointer freed and then used by QIClassID:
Most of this post was originally generated here:

Monday, February 11, 2013

X-Framing them all! - Cross-Framing is "impossibe" - Apple’s iOS 5

Cross Framing Google, Facebook and whoever you wish. 

Jailbreak Your Device? or buy android?

This post is mostly for people who hold iPhone/iPad/iPod or any other iDevice.

As for today at least for most people, jailbreaking is a serious concern and as for my experience it can even determine whether or not to purchase IOS(Apple) or Android(Google) device.
 there are quite many differences that comes to mind, one bold example is that the exact same application (whatsapp for example) would be free if you hold an smart-device who runs android, and would cost money if you use iDevice unless it is jailbreaked.
Some people even say the reason there was no jailbreak for iPhone5 might affected the apple sales, New York Times post on “Apple Earnings”
“Once-euphoric investors, who pushed Apple’s stock to a record high of $702.10 last September, have become nervous, and in early trading on Thursday, the stock traded at $455.89, down more than 34 percent from its peak.” (

Are you, behind? IOS 5.1.1? 6.0.1?

Since the only reason to convince us to upgrade to IOS 6 are update you already have with your installed Cydia tweaks, people just “stay behind” and use IOS 5.1.1 or lower to still have a nice jailbreaked iPhone. 

So you use IOS 5 or lower? Are you Safe?
As for today we already know there are many web application vulnerabilities around, client side attacks and mostly cross site scripting have become one of the most common attacks in the past recent years.

Google, Facebook, Microsoft, Paypal, Mozilla, Apple and many other great companies have tried to fight against the security risks to give us - their product customers, the answer to keep our data safe.
But do they?
Many of the web application developers had to deal with many different client side attacks and design their security architecture to protect their users and avoid different hacking attempts targeting their customers, since some attacks such as frame-busting click-jacking, multiple stage attack, self-XSS exploitation etc, are not easy to deal with and require browser cooperation.
There are quite a few client side security solutions such as Anti-XSS filters; No-Script, XSS-Auditor, SoP different headers, Caching, and X-Frame-Options header which define how the interpreter handles a response from a webpage loaded insde frames.

Safari on your iPhone(or iDevice) – you CHOOSE to stay vulnerable:

So Google’s/Facebook’s/Paypal’s/Any_Other web developers(including myself) can rely on browser implemented security features and protect their webpages from Client side attacks mostly from Click-Jacking and staging attacks with X-Frame-Options, setting it so that the webpage content will only be displayed after a request coming from the Same-Origin or completely disable Framing and thinking everything is now secured, what we unfortunately forget it is basing the protection on browser's client security. 

What if the browser fail?
I reported to apple 2 months ago at 06/12/12, that I discovered that even though the web server (in this example “”) set HTTP response header, X-Frame-Options Header to Same Origin the response will still be displayed using my iDevice.

As you can see in the following PoC HTTP response while sending HTTP request to

HTTP/1.1 200 OK
Date: Thu, 06 Dec 2012 15:54:50 GMT
Expires: -1
Cache-Control: private, max-age=0
Content-Type: text/html; charset=UTF-8
Server: gws
X-XSS-Protection: 1; mode=block

X-Frame-Options: SAMEORIGIN
Content-Length: 99283 

Setting this header suppose to provide browser client side security that will allow the iframe element to be displayed only if the parent document is at the same origin/domain of the iframe src attribute.
It appears the Safari Browser does not enforce X-Frame-Options and therefore displays our frame element as it did not even have any protection.

Normal Behavior IE9 enforcing X-Frame-Options: 

Safari on IOS 5:

PoC Test Page:
<head><title>X-Frame-Options Bypass</title></head>
<h1>Apple PoC X-Frame-Options </h1>
<iframe id="X" src=""></iframe>
framex = document.getElementById("X");
framex.onload = function () { }


Btw, This also means ClickJacking Anywhere Over IOS 5 and lower victims.

So What Should I Do?

Well, Apple did good and fixed this issue in the New IOS (6.0.1)
Unless you want to stay vulnerable knowning you can be a victim to advanced client side attacks over your gmail/facebook make sure you use IOS 6.