Episode 119: Abusing Iframes from a client-side hacker

Episode 119: In this episode of Critical Thinking - Bug Bounty Podcast Justin does a mini deep dive into the world of iframes, starting with why they’re significant, their attributes, and how to attack them.
Follow us on twitter at: https://x.com/ctbbpodcast
Got any ideas and suggestions? Feel free to send us any feedback here: info@criticalthinkingpodcast.io
Shoutout to YTCracker for the awesome intro music!
====== Links ======
Follow your hosts Rhynorater and Rez0 on Twitter:
====== Ways to Support CTBBPodcast ======
Hop on the CTBB Discord at https://ctbb.show/discord!
We also do Discord subs at $25, $10, and $5 - premium subscribers get access to private masterclasses, exploits, tools, scripts, un-redacted bug reports, etc.
You can also find some hacker swag at https://ctbb.show/merch!
====== Resources ======
Episode with JR0ch17
Exacerbating Cross-Site Scripting: The Iframe Sandwich
https://coopergyoung.com/exacerbating-cross-site-scripting-the-iframe-sandwich/
====== Timestamps ======
(00:00:00) Introduction
(00:01:20) Why are Iframes useful
(00:05:11) Attributes of Iframes
(00:21:39) Iframe Attacks
(00:29:53) Iframe Fun Facts
Title: Transcript - Thu, 17 Apr 2025 15:40:37 GMT
Date: Thu, 17 Apr 2025 15:40:37 GMT, Duration: [00:33:54.09]
The most overpowered way of doing this, by the way, is just writing some very quick and easy code to just have the iframe follow your cursor, right? Whenever your cursor is not centered on the invisible iframe, then just move it so that it is. All right, so packers, today we are going to cover one of my favorite topics in hacking, that is iframes. This is going to be just a little quick and dirty episode on how I approach iframes, how I use them in my sort of methodology. Things you need to know about all the attributes that are on there and some common vulnerability types and uncommon vulnerability types. We've got a couple on here that I think will be really helpful. Okay, so let's jump into it. Iframes, of course, are the ability. In HTML, it's an iframe tag or a HTML tag that allows you to embed another page inside of your website. Okay, so why is that helpful? Well, there's a lot of reasons why that's helpful. First ones that comes to mind is, of course, clickjacking. Now, when I say clickjacking, I'm sure a lot of you guys are triggered and like, oh, this guy's a scrub. Hey, he's talking about clickjacking. Guys, I just want to, like, take a second to say clickjacking can be an incredibly impactful vulnerability, right? You think about one click xss. We report that all the time. You know, this clickjacking can have very, very similar impact. Consider this scenario. You are able to embed an authorization, an oauth auth flow, into your own website, right? With one click on your website in this invisible iframe, you are able to get the victim to approve full access to their account. That's full account takeover in one click, right? So clickjacking gets a bad. A bad rap. I have submitted plenty of impactful clickjacking reports that have gotten bounties. The reason it gets a bad rap is people will report it without pocking it at all, right? So they'll just be like extreme options header is missing critical clickjacking. That's not the case, right? You need to find a single point of failure click that can make your clickjacking report impactful for it to actually be a good report. I know I said clickjacking. Chill the heck out everybody, but I really do think they can be very impactful. Clickjacking is one of the things that you can do with iframes that's impactful to hacking. The other one is frame references. Frame references are extremely Important when it comes to exploiting lots of client side types of vulnerabilities. The reason for that is that if you have a reference to a frame, you can send a post message to it. If you're same origin, you can jump into that page and grab the DOM and manipulate it. And that sort of thing, especially in this era of same site, lacks default cookies. Having a frame reference to a top level page or something like that really allows you to manipulate that page a lot. But the most common use for having a frame reference is to send a post message. Okay, what is a post message? A post message is inter tab communication or interframe communication for the browser. And I really think that this is still after me talking about it for years and years and years a underserved attack surface. A lot of people just don't even look at post messages at, at all. And they're just completely missing an API that lives in the browser that is extremely important to the browser security. Okay, so definitely something to look into. I'll talk more about post messages maybe on a different like deep dive, technical deep dive episode like this. But for now what you need to know is that iframe is one of the. Okay, there's like a decent amount of ways to get a frame reference, but one of the few ways to get a frame reference is by iframe. Okay, so keep that in mind. All right. And then the other two things that I have in this, like why they're useful section for the iframe is window name hijacking, which is a vulnerability that I'll talk to you about a little bit later. And then the second one is, or the last one is hiding your attacks that take time. So sometimes there's like either a post message based attack or some client side based flow that will take a lot of time to exploit. And you kind of need to have your attack be hidden on your website and you need to be able to target the victim website. Now unfortunately this doesn't happen quite as much nowadays because if same site lacks default cookies, you can't really embed stuff quite as simply. But in certain scenarios, you can embed this target page in an iframe on your site, distract the user with a game of click this, click that, and then have enough time to fully exploit your vulnerability. So that is what I would say are some of the four top reasons why iframes are useful to hackers. Let's go into some of the attributes of iframes so we can understand how they can be manipulated, how they can be used. The first one is source and source doc. Obviously these are going to be the most impactful ones. These are the ones that control where the iframe is pointed at. Source simply allows you to point the source of the iframe at a URL. Could be a JavaScript URL. That's one of the common ways to get XSS is an iframe source JavaScript URL could be a absolute URL where you're pointing to a different website and embedding a victim page. Rarely do we see something where it's a relative URL that's just like not super helpful for attackers typically. And then what is source doc and why do I lump them together? Well, source doc is sort of the alternative to source and it is a attribute that allows you to define what should be inside of the iframe directly in the source doc attribute. And this is extremely helpful for several things. But the first one that pops to mind when I think about the source doc attribute is the fact that you can write a new domain inside of that iframe. And that is really, really helpful when you need to use a script tag in a post DOM rendering environment. Because a lot of you guys know that if you try to do an inner HTML sync in DOMXSS and you try to put a script tag in there, it will not fire because the DOM has already rendered. And that's when script tags trigger. So you can have an inner HTML sync put a script tag in there. It's not going to do anything, however, and typically you can get around that by using something like a onevent handler, like an svgonload or an image on error handler. However, sometimes you are limited or maybe you need to import a different origin, something like that, or import your script from a different origin and you want to use a script tag, well, you're stuck until iframe source doc comes in. What you can actually do is iframe source doc and then inside of that source doc you can define the script tag. And since that iframe is in a new DOM inside of the iframe, that script tag will trigger, resulting in xss. So it's a little bit of a roundabout way, but you can still accomplish the same goal. And it has saved my ass a couple times because sometimes there's just a really weird filter on there that doesn't allow for any sort of on event handlers, or maybe there's character limitation or something like that. This one does work. So very helpful. The other thing is that source doc will be same origin as the parent when it's defined. So that is helpful for just being able to embed content inside the page in an isolated DOM that is still the same origin as the parent. Okay, so that's source and source doc. I'm not sure that there's a lot of other things there that come to mind as far as tricks that a hacker needs to know. So let's move on to the next one. The next is the CSP attribute. Okay, now you guys have all heard of CSP content security policy. It is the way that modern browsers add additional limitations to what scripts can. Scripts can be run, styles can be run, what, what hosts we can connect to, that sort of thing. Let me get some water for a sec. Lovely. Okay, so CSP is often used and in this scenario as an attacker, oftentimes if you're coming up against the CSP attribute, then you're trying to get out of that CSP or get around that csp. Now, we could spend a whole episode on how we block, how we get around CSP's blocks, right? And probably we will at some point. But for what you need to know, right now, there's a CSP attribute that can be applied directly to the iframe. And this has a couple of cool uses. One is, okay, now we need to get around the csp. We're the attacker, we're stuck in the iframe. How do we escape? Fun stuff. The other thing that I was thinking is it's actually helpful for an attacker on a page with that they can load in an iframe, but, you know, it's cross origin. And you, you need to be able to define the CSP for that page because you can DOS specific scripts. Maybe there's a script that, you know, does something that puts the site in an insecure position, and then there's another script that comes over and like, makes it secure again. And you want to have that second script not load. Well, you can load that page inside of an iframe, set the CSP for that page, and then block that second script from loading if it's being dynamically loaded up from a specific URL or something like that. So very interesting, very interesting piece of functionality. Whenever you can define security controls for an origin that you don't own in this environment. Very, very interesting piece of functionality. So, audience, I challenge you, kind of let your brains spin a little bit on how we could use a CSP to attack a victim page that we can embed in an iframe, because we can set the Content security policy for that very interesting. Next attribute up is the allow attribute. Now the allow attribute defines what's called permission policy for that specific page. This gives access to resources such as camera, mic, geolocation, et cetera. All of those get passed to this specific frame. Now I learned something very, very interesting recently. I wish I could shout out who told me, but I can't. So you know who you are. If you're listening, shout out to you that the iframes will even cross origin iframes will inherit whatever permissions the top level page has. As far as permission policy goes, this is true especially if the allow attribute. This is necessary that the allow attribute, say pass through Mike, pass through camera, etc. That iframe is allowed to access them. Then it doesn't even matter that there's a cross origin relationship there. The top page can give their permissions to the lower level page. I think this creates a really interesting scenario where you have preview like functionality. I think that the top level origin that may be doing that previewing, maybe isolating your code in a sandbox or something like that, may be endowed with particular permissions that you may not want to give to the bottom iframe and then sometimes get passed through explicitly. Definitely keep an eye out for the allow attribute on these iframes if somebody is not aware of how they are impacted impacting the dom's security when they're using it. The next attribute that I had on the list was the name attribute. And guys, this is one of my favorite parts of freaking browser security. I don't know why I love the name attribute so much. I just think it's really helpful. The name attribute in an iframe context allows you to set the name for a window that is inside that iframe. The reason that's cool is because that name attribute is one of the only things that doesn't change when you move from origin to origin. You can open up an iframe, you can name it bob, and then you navigate that iframe to a completely different window and it's still called bob. I recently found where did I read this? Somebody told me this or I read it somewhere that this was how they used to do this is from an OG cross domain communication before the postmessage API came out is they would set a message in the window name and then they would redirect to that other domain and the domain would read the window and be like okay, here's the response message and they redirect back to the other domain. That was how they would do cross domain communication. Very interesting. The other cool thing about the name attribute is it can be used to specify what windows specific window open calls should be opened into or forms or a links can be pointed at. There are a couple really cool niche vulnerabilities that can happen where you have a specific window open on the page. The attacker controls the ability to open a window into a certain tab or frame via the name attribute and then you can force that iframe or whatever to contain the contents that you want as a malicious actor. Very cool vulnerability. I found it a couple times. Feels amazing when you pull it off. We'll talk more about that later under the window name hijacking vulnerability section. A couple more attributes to cover and then we'll get to some of the meat on different attack vectors you can use with an iframe. The next one is referrer policy. This is a pretty new one. I feel this hasn't been around for too long. Back in the good old days we used to be able to just leak data via the referrer anytime. If we could inject an image tag into a page and land an oauth code on that page and the image would load, then we would get that oauth code on our server every time because it was just yeeting the whole referrer out to whatever resource loaded up on the page. Which is totally crazy now in retrospect, but it was awesome back in the day. What prevents us from doing that now is the referrer policy. Now I've said this a couple times on the pod, but you should definitely go back and listen to the episode by jrock17. He drops an amazing zero day misconfiguration. Chrome and Dompurify fighting over stuff on that episode where essentially you can put a meta tag affecting the referrer policy of a specific page into dompurify and it will get sanitized, but somehow it still has effect on the page, which is just such a cool thing. If you ever have a dompurify based injection and you're trying to think what can I do with this? You can change the referrer policy. Very, very interesting thing. Very impactful. Especially in a scenario where a lot of times when you're going up against dompurify, you have user controlled HTML, right? That's what they're purifying, that's what they're sanitizing. So you embed an image tag in there, you set the refer policy to unsafe URL. You land an unused oauth code on that page via Dirty Dancing, right a la Franz Rosen. And then boom, you're good to go. So definitely, very interesting piece there and there for policy, a little bit less interesting referring to iframes, but I did have in my notes here, I forgot. There is a really interesting idea that I came up with when I was thinking and prepping for this episode about referrer policy and iframes. That was that I finally found a use for the client side post message based open redirect. Now, I talked about this a little bit on the gadgets episode that we did a while back. We were like, is this really a gadget? And the answer is no, because if you have a frame reference, most of the time you have the ability to redirect anyway. But what's interesting about this is that if you want to embed a victim page inside of your browser, inside of your attacker controlled page in an iframe, and set the refer policy for that unsafe URL and then use a post message to navigate the page inside of the iframe. The navigation comes from within the iframe. Then you can leak the top level URL of that page via the referer, which is a very valuable gadget. Much more valuable of a gadget than a client side post message based open redirect. Maybe you land an oauth code on there, maybe you get a piece of PII in the URI somehow. But that was something that I hadn't really put together in my brain before today that if you can set the referrer policy. Once again, we're in this sort of weird situation of like, how are we setting the referrer policy for a cross origin domain just because it's in our iframe? It's a little bit, it's a little bit funky, but you don't really see people set the referrer policy. It's mostly just screwing us because it's implicitly set to just the. The top level domain. So very, very interesting flow there. I'm definitely going to keep my eye out for that. I just thought of that like a couple minutes before the episode. All right, next up is the sandbox attribute. This one is where we kind of get into a little bit of meat. And I'm not going to spend too much time here because there's so many different attributes that, you know, components that can go into this attribute. But the sandbox attribute for an iframe allows you to isolate that iframe even more from your current domain and control it in very clear ways. Some of the most popular and useful attributes for an attacker to be aware of is Allow scripts and allow same origin. Those two are really impactful. One Allow scripts of course allows you to run JavaScript within this iframe. 2 allow same origin allows you to have the same origin as the parent frame and access also the cookies and local storage and some of those things that are tied to that domain. Very cool stuff. Allow forms Allow pop ups Allow pop ups to escape Sandbox and allow top level navigations are also second tier interesting to an attacker in my rating system. Inside of sandbox Allow forms obviously allows you to do form based navigation. That's a really cool way to get around CSP sometimes trigger some very impactful stuff. Allow popups that allows you to swing pop open another window, something like that. Allow popups to escape Sandbox is really cool. Allow popups without to escape Sandbox is also really interesting because the pop up window that you spawn inherits the same sandbox properties as the previous window. If you don't do allow same origin and iframe is origin null and you do a pop up on that, then the website is also going to be origin null. You can do some really weird stuff with window open inside of a Allow scripts iframe when it doesn't have same origin. Very fun stuff there. Definitely investigate that if you're into client side stuff. Okay, and the last one is Allow top level navigation. A lot of people don't know this, but you have a lot of power when it comes to iframes and openers. If you are the opener of a specific page, then you can redirect that page at will anytime. If you are an iframe within a page, you can also oftentimes redirect the top level page. So there's a lot of power that comes with that. And that can be really helpful for an attacker if they're able to inject an iframe somewhere into a page or hijack an iframe. There's a lot of capabilities that come there. Then the last one that I had as far as attributes go is the credential list attribute. We covered this recently on the pod a couple of weeks ago, so I won't talk about it too much, but essentially what it allows you to do is create a siloed browsing context inside of that iframe. That means that that iframe doesn't have access to your cookies, none of your local storage, none of that other stuff that you would normally have access to in a traditional iframe scenario. It's just isolated. This is really helpful. A buddy of mine recently had to do an XSS where you cannot send any samesite none cookies and the same site cookie none cookie that he needed to not be sent was set immediately Whenever you went to the page. It was really hard to exploit and this credential list was the solution. I'm going to get some water and then we'll jump into a couple of attacks that I love with iframes. All right, let's see what we got. All right, a couple of attacks that we're going to talk about with regards to iframes. Now, the first one is called window name hijacking. Okay. And this one is a little bit tricky to understand, but I'm going to do my best over the audio medium. Okay, Consider this. You have an attacker controlled page and you window open a victim page. The victim then clicks a button on that page which triggers another window open with a very specific name that you know the value of. What an attacker can then do is create an iframe on their own page before the button is clicked. Just to be clear, that has that same name. Now, the victim page and the attacker page are in a linked browsing context because of the opener relationship between those two pages. Because they share the same browsing context, they will also be able to reference each other's frames. What will happen then is if an attacker knows the origin that the victim will be opening the tab into so that they're going to do a window open on site.com or whatever, then they can embed their own attacker iframe inside of the attacker controlled page that points to site.com that is on site.com, right? Maybe you find a 404 page or something that doesn't have X frame options on it and you embed it in your page and you name that iframe, the same thing as the victim will be opening with window open. Okay. And what's going to happen in that scenario is when the user clicks the button and it opens the pop up, it is not going to pop up at all. It is going to open that attacker or that victim's new pop up window into your iframe that's on your attacker controlled page. Now the reason why that is interesting is that there's often a lot of implicit relationship stuff that occurs between opened windows and their opener. The opener will take that frame reference and be like, I'm just going to use this frame reference as the source of truth is whether I should trust this post message or not or. Or when I'm going to keep checking the origin of that window reference and when it comes back to my origin, then I'm going to trust the data that comes out of it. I'm going to grab from the hash or something like that. I've seen that a couple of times. What you can do by hijacking that frame, obviously you're the parent of that frame. It's in your own page. You control where that frame is pointed to. You simply redirect that frame to an attacker controlled page and send the post message back to its. Its opener saying, hey yo, I'm the frame you opened, here's the data and pass it through and exploit it that way. Or if it's looking to get a callback or something like that on that frame, then you get whatever data you want to call back, throw it in the hash, and then redirect it back to whatever callback page the opener was expecting and it will parse it just like it just coming back from the call that it did. So this is a very cool attack. I've exploited this several times. I think probably less than 10 times, but still very, very fun attack. When it works, it's a blast. And I just love that we can control where a pop up goes, right? Like, isn't that such a cool thing? The victim is expecting sort of a pop up to happen and instead it just opens into an attacker controlled iframe. And now you're focused on the attacker's page and your iframe now is populated with that victim's data that they were trying to open up. Very cool. All right, the next one is open faced iframe sandwich. Okay, this is the next attack that was on my list. Now I've talked about this a couple times on the pod and I wanted to bring it up again because a guy named Cooper Young, who I helped with an open faced iframe sandwich recently did a write up, I want to say like two or three days ago on the iframe sandwich. Okay. And the write up was great. It explains how everything happens. We were able to pop a bug with this, which was really fun. I wanted to go ahead and review it for the listeners of the pod because it is a little challenging, I have to say. I'm going to do my best to describe this with my two hands, but maybe, I don't know, maybe I'll put a graphic up on the screen. We'll see. This episode goes to production pretty quickly. I'm not sure we're going to have time to this, but I'll try to explain it. Anyway, we've got an attacker frame and a victim frame. What happens in this scenario is that the attacker gets an XSS on an origin that is iframed in a victim tab. Consider the scenario where you've got One of the real examples from my experiences was I was able to pop an XSS on the origin that controls the user's mail settings. Right? Like, do you want to subscribe to our newsletter or whatever? Right. It's like sometimes those things are super easy to pop and they're embedded in the iframe on www, right? So you're like, okay, what can I do with this? It isn't really in scope. I want to affect www. What do I do? Well, here's what you do. From the attacker's page, you open a frame that's the victim page. The victim page has that, I'm going to call it the mail domain, iframed into it. Now, as the attacker, you iframe on your page, your XSS into the mail domain, right? So now both pages have an iframe to the mail domain and they're open and they have an opener relationship with one another, right? I guess one of them has an opener relationship, one of them has an open E relationship. So what you then do is from the attacker's frame inside of the iframe, you go up to the attacker's top level page, over to the victim tab, and down into the victim's iframe. Now, these two iFramed pages have the same origin, which means they can access each other's dom. So the attacker with the malicious XSS then affects the dominant within that page or grabs whatever information is out of it on that page. In my scenario, there was a bunch of PII leaked into that from the parent. When it tells the mail domain, hey, this is the user I want you to control the mail for and you, you get impact that way. Let me grab some water. Okay. And now I'm back. I just had like a cough attack from that little tickle in my throat. But that's the open iframe sandwich. Open faced iframe sandwich. Really cool exploit, love to use it. Okay. And then last but not least is clickjacking. Of course, you can't really not mention clickjacking when you talk about iframe security in web security. Like I said before, clickjacking gets a bad rap all the time and I don't really know why. It can be very impactful when done correctly. And I just want to say, you know, I built A clickjacking POC recently and it was impactful, as I said. And the most overpowered way of doing this, by the way, is just writing some very quick and easy code to just have the iframe follow your cursor whenever your cursor is not centered on the invisible iframe, then just move it so that it is. That's really easy to code. I'm pretty sure I told cursor to do it and it just like one shot got it right and it was totally fine. You center the iframe where the user's cursor is over whatever button you want to click and it doesn't even matter. The user can be running their cursor around and it will still always click the right button, which is super overpowered in my opinion. So very cool stuff there. Had to mention clickjacking. Don't submit crappy clickjacking reports. Build out the full POC and you will very likely get paid for those if they're not explicitly out of scope because the impact is there. Or it should be there if you're reporting it. Okay, last but not least, couple fun facts about iframes that have just landed me a couple bugs recently. This is a fun one from the Critical Research Lab, actually. The content security policies Frame ancestor attribute will override X Frame Options header. Okay, so let me say that again. The X Frame Options header, of course you guys know what the X Frame Options header is? It controls whether a page can be iframed or not. What you'll often see is Extreme options deny this page cannot be framed at all. Gg, game over. Well, if there's a content security policy that has a frame ancestor attribute in it and that defines some pages that the page can be iframed from, then that will override extreme options and be given priority. Which is very interesting because a lot of times what happens in browser security is if there's a conflict between two, you know, security related entities, though the one that they go for is the one that is more safe. The one that is least permissive. Right, but in this scenario, we actually have it going with the one that is. That is. Sorry, yeah, the one that's least permissive. In this scenario, we have one going for the one that is more permissive. Kind of odd. Okay, let me see what else was on here. I know I had a couple more. I've already mentioned that iframes can redirect their parents and openers by default. That's pretty cool. The last one here that I have to mention is window frames is one of the very few attributes that can be accessed by a cross origin relationship window reference. Here, let's say I've got attacker.com, and I've got victim.com and they have like a relationship where they have a window frame. The attacker can see how many iframes the victim has in that page. Now this is really helpful for a lot of reasons from a cross site leak perspective. But one of the ones that I've always thought was really cool was like, wouldn't it be amazing if there was a, a page where you could like very easily update the hash and it would, you know, give you an iframe for every, like, result of a search or something like that. So you just put in, you know, the hash A and it like says, okay, there's like six, six of them and you say B and then there's like four of them and you say C and then there's just one of them and you say E and then it says nope. And then you say D and it says yes, there's one. You know, so you can do like, you can really sort of character by character brute force codes in sort of like a cross leak scenario if the number of iframes changes based off of what is controlled by the attacker. Very, very cool stuff. I've used this several times to land vulnerabilities. It's something I always check because I'm like, wouldn't it be sick if I could just leak this data across origin property on a window reference? Every time I think about that, my brain just keeps churning and churning and turning like, where can I use that? Where are there iframes that are relevant to data that an attacker can control? All right, y'all, that's about a wrap. I think that is a good, you know, basic overview of the iframes. I'm. I'm not sure that there's anything that's really essential that I missed there. So I hope you enjoyed it. Let me know what you guys think about these sort of like one off single, single person talking sort of technical deep dives on a topic you're comfortable with with. So let me know what you guys think. That's the pod for this week. Peace. And that's a wrap on this episode of Critical Thinking. Thanks so much for watching to the end, y'all. If you want more critical thinking content or if you want to support the show, head over to CTBB Show Discord. You can hop in the community. There's lots of great high level hacking discussion happening there? On top of the master classes, hack alongs, exclusive content and a full time Hunters guild. If you're a full time hunter, it's a great time. Trust me. I'll see you there.