Iframes security tips and scripts - javascript

I am trying to launch a website for myself which people might be using in future. Currently I am allowing users to post iframes for YouTube and Google Maps etc. Copy entire 'iframe' from Google Maps or YouTube and paste it in post box just to keep it simple.
Later I am storing it in MySQL database. I am displaying this post on some page. I am little worried since though I have asked user to paste only YouTube or Maps iframes, a devil mind might put src of malicious code.
What are all the possible ways to prevent this?

I think there are multiple risks, some that come to mind are:
Cross-site scripting. There are too many ways to achieve this if you allow the full <iframe> tag to be displayed as entered. This is probably the main risk, and the showstopper. It would be really hard to prevent XSS if you just write the full iframe tag (as entered by an attacker) into subsequent pages. If you really want to do this, you should look into HTML sanitization like Google Caja or HTMLPurifier or similar, but it is a can of worms that you better avoid if possible.
Information leak to malicious website. This very much depends on the browser (and the exact version of such browser), but some information (like for example teh window size, etc.) does leak to the website in an iframe, even if it's from a different origin.
Information / control leak from malicious website. Even worse than the previous, the embedded website would have some control over the window, for example it can redirect it (again, I think it depends on the browser though, I'm not quite sure), or can change the url hash fragment. Also if postMessage is used, the iframe can send messages to your application, which can be exploited if your application is not properly secured (not necessarily right now, but at any time in the future, like 5 years from now, after much development).
Arbitrary text injection, possibly leading to social engineering. Say an adversary includes a frame that says something like "You are the winner of this month's super-prize! Call 1-800-ATTACKER to provide your details and get your reward!"... You get the idea. The message would look like a legitimate one from your website, when it's not.
So you'd better not allow people to enter full tags as copied from Google Maps or anywhere else. There appears to be a finite set of things you want to allow (like for example Youtube videos and Google Maps links are only two), for which you should have customized controls. The user would only enter the video id/slug (the part after ?v=...), or would paste the full link, from which you would take the id, and you would make the actual tag for your page on the server side. The same for Google Maps, if the user navigates to wherever he wants in a Maps window and pastes the url, you can make your own iframe I think, because everything is in the url in Google Maps.
So in short, you should not allow people entering tags. XSS can be mitigated by sanitizers, but other risks listed above cannot.

Related

What all threats imposed by an iframe? [duplicate]

Why are iframes considered dangerous and a security risk? Can someone describe an example of a case where it can be used maliciously?
The IFRAME element may be a security risk if your site is embedded inside an IFRAME on hostile site. Google "clickjacking" for more details. Note that it does not matter if you use <iframe> or not. The only real protection from this attack is to add HTTP header X-Frame-Options: DENY and hope that the browser knows its job.
If anybody claims that using an <iframe> element on your site is dangerous and causes a security risk, they do not understand what <iframe> element does, or they are speaking about possibility of <iframe> related vulnerabilities in browsers. Security of <iframe src="..."> tag is equal to <img src="..." or <a href="..."> as long there are no vulnerabilities in the browser. And if there's a suitable vulnerability, it might be possible to trigger it even without using <iframe>, <img> or <a> element, so it's not worth considering for this issue.
In addition, IFRAME element may be a security risk if any page on your site contains an XSS vulnerability which can be exploited. In that case the attacker can expand the XSS attack to any page within the same domain that can be persuaded to load within an <iframe> on the page with XSS vulnerability. This is because vulnerable content from the same origin (same domain) inside <iframe> is allowed to access the parent content DOM (practically execute JavaScript in the "host" document). The only real protection methods from this attack is to add HTTP header X-Frame-Options: DENY and/or always correctly encode all user submitted data (that is, never have an XSS vulnerability on your site - easier said than done).
However, be warned that content from <iframe> can initiate top level navigation by default. That is, content within the <iframe> is allowed to automatically open a link over current page location (the new location will be visible in the address bar). The only way to avoid that is to add sandbox attribute without value allow-top-navigation. For example, <iframe sandbox="allow-forms allow-scripts" ...>. Unfortunately, sandbox also disables all plugins, always. For example, historically Youtube couldn't be sandboxed because Flash player was still required to view all Youtube content. No browser supports using plugins and disallowing top level navigation at the same time. However, unless you have some very special reasons, you cannot trust any plugins to work at all for majority of your users in 2021, so you can just use sandbox always and guard your site against forced redirects from user generated content, too. Note that this will break poorly implemented content that tries to modify document.top.location. The content in sandboxed <iframe> can still open links in new tabs so well implemented content will work just fine. Also notice that if you use <iframe sandbox="... allow-scripts allow-same-origin ..." src="blog:..."> any XSS attack within the blob: content can be extended to host document because blob: URLs always inherit the origin of their parent document. You cannot wrap unfiltered user content in blob: and render it as an <iframe> any more than you can put that content directly on your own page.
Example attack goes like this: assume that users can insert user generated content with an iframe; an <iframe> without an attribute sandbox can be used to run JS code saying document.top.location.href = ... and force a redirect to another page. If that redirect goes to a well executed phishing site and your users do not pay attention to address bar, the attacker has a good change to get your users to leak their credentials. They cannot fake the address bar but they can force the redirect and control all content that users can see after that. Leaving allow-top-navigation out of sandbox attribute value avoids this problem. However, due historical reasons, <iframe> elements do not have this limitation by default, so you'll be more vulnerable to phishing if your users can add <iframe> element without attribute sandbox.
Note that X-Frame-Options: DENY also protects from rendering performance side-channel attack that can read content cross-origin (also known as "Pixel perfect Timing Attacks").
That's the technical side of the issue. In addition, there's the issue of user interface. If you teach your users to trust that URL bar is supposed to not change when they click links (e.g. your site uses a big iframe with all the actual content), then the users will not notice anything in the future either in case of actual security vulnerability. For example, you could have an XSS vulnerability within your site that allows the attacker to load content from hostile source within your iframe. Nobody could tell the difference because the URL bar still looks identical to previous behavior (never changes) and the content "looks" valid even though it's from hostile domain requesting user credentials.
As soon as you're displaying content from another domain, you're basically trusting that domain not to serve-up malware.
There's nothing wrong with iframes per se. If you control the content of the iframe, they're perfectly safe.
I'm assuming cross-domain iFrame since presumably the risk would be lower if you controlled it yourself.
Clickjacking is a problem if your site is included as an iframe
A compromised iFrame could display malicious content (imagine the iFrame displaying a login box instead of an ad)
An included iframe can make certain JS calls like alert and prompt which could annoy your user
An included iframe can redirect via location.href (yikes, imagine a 3p frame redirecting the customer from bankofamerica.com to bankofamerica.fake.com)
Malware inside the 3p frame (java/flash/activeX) could infect your user
IFRAMEs are okay; urban legends are not.
When you "use iframes", it doesn't just mean one thing. It's a lexical ambiguity. Depending on the use case, "using iframes" may mean one of the following situations:
Someone else displays your content in an iframe
You display domeone else's content in an iframe
You display your own content in an iframe
So which of these cases can put you in risk?
1. Someone else displays your content
This case is almost always referred to as clickjacking - mimicking your site's behaviour, trying to lure your users into using a fake UI instead of the real site. The misunderstanding here is that you using or not using iframes is irrelevant, it's simply not your call - it's someone else using iframes, which you can do nothing about. Btw, even they don't need them specifically: they can copy your site any other way, stealing your html, implementing a fake site from scratch, etc.
So, ditching iframes in attempt to prevent clickjacking - it makes exactly zero sense.
2. You display someone else's content
Of the three above, this is the only one that's somewhat risky, but most of the scary articles you read all the time come from a world before same-origin policy was introduced. Right now, it's still not recommended to include just any site into your own (who knows what it will contain tomorrow?), but if it's a trusted source (accuweather, yahoo stock info etc), you can safely do it. The big no-no here is letting users (therefore, malicious users) control the src of the iframe, telling it what to display. Don't let users load arbitrary content into your page, that's the root of all evil. But it's true with or without iframes. It has nothing to do with them; it could happen using a script or a style tag (good luck living without them) - the problem is you let them out. Any output on your site containing any user-given content is RISKY. Without sanitizing (de-HTMLifying) it, you're basically opening your site up for XSS attacks, anyone can insert a <script> tag into your content, and that is bad news. Like, baaaad news.
Never output any user input without making dead sure it's harmless.
So, while iframes are innocent again, the takeaway is: don't make them display 3rd-party content unless you trust the source. In other words, don't include untrusted content in your site. (Also, don't jump in front of fast-approaching freight trains. Duuh.)
3. You display your own content in an iframe
This one is obviously harmless. Your page is trusted, the inner content of the iframe is trusted, nothing can go wrong. Iframe is no magic trick; it's just an encapsulation technique, you absolutely have the right to show a piece of your content in a sandbox. It's much like putting it inside a div or anything else, only it will have its own document environment.
TL;DR
Case 1: doesn't matter if you use iframes or not,
Case 2: not an iframe problem,
Case 3: absolutely harmless case.
Please stop believing urban legends. The truth is, iframe-s are totally safe. You could as well blame script tags for being dangerous; anything can cause trouble when maliciously inserted in a site. But how did they insert it in the first place? There must be an existing backend vulnerability if someone was able to inject html content into a site. Blaming one piece of technology for a common attack (instead of finding the real cause) is just a synonym for keeping security holes open. Find the dragon behind the fire.
Unsanitized output is bad; iframes are not.
Stop the witch-hunt.
UPDATE:
There is an attribute called sandbox, worth checking out: https://www.w3schools.com/tags/att_sandbox.asp
UPDATE 2:
Before you comment against iframes - please think about hammers. Hammers are dangerous. They also don't look very nice, they're difficult to swim with, bad for teeth, and some guy in a movie once misused a hammer causing serious injuries. Also, just googled it and tons of literature says mortals can't even move them. If this looks like a good reason to never ever use a hammer again, iframes may not be your real enemy. Sorry for going offroad.
"Dangerous" and "Security risk" are not the first things that spring to mind when people mention iframes … but they can be used in clickjacking attacks.
iframe is also vulnerable to Cross Frame Scripting:
https://www.owasp.org/index.php/Cross_Frame_Scripting

GDPR: youtube-nocookie embedded URL's, need visitors' permission?

This is my first time posting on Stack Overflow and I have a question about the GDPR.
Hi there! (This is ment to be on top of the post, but for some reason it gets deleted when I save it)
Situation:
On my website I don't want to bother visitors with cookie notifications, so the goal is to only place necessary cookies. However, there will be embedded YouTube video's on the website, which usually places tracking cookies.
After some research I stumpled upon the youtube-nocookie.com domain, which I am using now. Without using that domain, an embedded video url will be:
https://www.youtube.com/embed/7cjVj1ZyzyE
With using it, it is:
https://www.youtube-nocookie.com/embed/7cjVj1ZyzyE
By using the latter, cookies will only be placed after playing the video, and no tracking cookies will be placed (according to Google: https://support.google.com/youtube/answer/171780?hl=en under 'Turn on privacy-enhanced mode'). However, there will still be placed some cookies, and it is not clear for me if visitors will need to give permission for those, and if so, under what category (and maybe they are still tracking?).
Image of the cookies:
Image of cookies youtube-nocookies.com places
This is in Chrome. The cookies from the gstatic domain are placed on page-load for some reason. That doesn't happen in Opera.
Another weird thing is that FireFox (with allowing all cookies and trackers) and Edge don't seem to place any of the 6 cookies from the image at all.
Many sites and blogs say that this is the way to embed YouTube video's, but I can't seem to find a clear answer to the question if you still need visitors' permission for these cookies. Also on many sites where I only accept necessary cookies, I still have the possibility to view YouTube video's and the corresponding cookies will be happily placed without my consent.
Has anybody delt with this before?
Thanks in advance!
After some more research I think I found a clear answer. From a report of Cookiebot:
“Privacy-Enhanced Mode” currently
stores an identifier named “yt-remote-device-id”
in the web browser’s “Local Storage”. This
allows tracking to continue regardless of
whether users click, watch, or in any other way
interact with a video – contrary to Google’s
claims. Rather than disabling tracking, “privacyenhanced mode” seems to cover it up.
Source: https://www.cookiebot.com/media/1136/cookiebot-report-2019-ad-tech-surveillance-2.pdf
The 'yt-remote-device-id' indentifier, along with some other ones, are, even with the use of the youtube-nocookie.com domain (or 'Privacy Enhanced Mode'), still being placed on page load (given that the iframe with the set source is already part of the DOM at this point of course).
So while no tracking 'cookies' cookies are placed, the tracking has moved to the browsers localStorage (I overlooked this before), which basically means visitors actually do need to give permission before embedded YouTube video's with Privacy Enhanced Mode enabled should be loaded on the page.
Update
Gave some nuance in response to Marc Hjorth's comment.
i can confirm that the localStorage entry effectively replaces the funktion of the cookie. it is persistent and makes you identifiable across browser sessions. i get the same "yt-remote-device-id" value each time after restarts. only erasing the local storage makes a difference.

URL tracking functionality

I want my webpage to have two parts. The top part has a textbox. When the user types a URL into the textbox, the bottom part browses to the content of that URL. When the user clicks a link within the bottom part, the bottom part navigates to the new URL, and the textbox in the top part changes to the new URL. How can I do it?
NOTE: This behavior is the same as in Google Translate (e.g. here), but without any translation.
first problem..
Same origin issue
The only way to achieve what you are asking is exactly the way google translate does what it does - which is to use a server-side powered script as a proxy request:
http://translate.google.com/translate_un?depth=1&hl=en&ie=UTF8&prev=_t&rurl=translate.google.com&sl=auto&tl=en&twu=1&u=http://de.wikipedia.org/wiki/USA&lang=de&usg=ALkJrhgoLkbUGvOPUCHoNZIkVcMQpXhxZg
The above is the URL taken from the iframe that Google translate uses to display the translated page. The main thing to note is that the domain part of the URL is the same as the parent page's URL http://translate.google.com -- if both your frame and your parent window do not share the same domain, then your parent window's JavaScript wont be able to access anything within the iframe. It will be blocked by your browser's in-built security.
Obviously the above wont be a problem if in your project you are only ever going to be navigating your own pages (on the same domain), but considering you are proffering Google Translate as an example I'm assuming not.
What would Google do?
What the above URL does is to ask the server-side to fetch the wikipedia page and return it so that the iframe can display it - but to the iframe this page appears to be hosted on translate.google.com rather than wikipedia. This means that the iframe stays within the same origin as the parent window, and means that JavaScript can be used to edit or modify the page within the iframe.
next problem....
Rewrite the proxied content
Basically what I'm saying is that this can't be achieved with just HTML and client-side JavaScript - you need to have something to help from the server-side i.e. PHP, Python, Ruby, Lisp, Node.. and so on. This script will be responsible for making sure the proxied page appears/renders correctly e.g. you will have to make sure relative links to content/images/css on the original server are not broken (you can use the base tag or physically rewrite relative links). There are also many sites that would see this as an illegal use of their site, as per their site's terms of use and so should be black listed from your service.
final problem..?
Prevent the user from breaking away from your proxy
Once you have your proxy script, you can then use an iframe (please avoid using old framesets), and a bit of JavaScript magic that onload or ondomready of the iframe rewrites all of the links, forms and buttons in the page. This is so that when clicked or submitted, they post to your proxy script rather than the original destination. This rewrite code would also have to send the original destination to your proxy script some how - like u in the Google translate URL. Once you've sorted this, it will mean your iframe will reload with the new destination content, but - all importantly - your iframe will stay on the same domain.
too many problems!
If it were me, personally, I'd rethink your strategy
Overall this is not a simple task, and it isn't 100% fullproof either because there are many things that will cause problems:
Certain sites are designed to break out of frames.
There are ways a user can navigate from a page that can not be easily rewritten i.e. any navigation powered by JavaScript.
Certain pages are designed to break when served up from the wrong host.
Sites that do this kind of 'proxying' of other websites can get into hot water with regards to copyright and usage.
The reason why Google can do it is because they have a lot of time, money and resources... oh and a great deal of what Google translate does is actually handled on the server-side - not in JavaScript.
suggestions
If you are looking for tracking users navigating through your own site:
Use Google Analytics.
Or implement a simple server-side tracking system using cookies.
If you are looking to track users coming to your site and then travelling on to the rest of the world wide web:
Give up, web technologies are designed to prevent things like this.
Or join an online marketing company, they do their best to get around the prevention of things like this.
add a javascript function to your second frame -
<frame id="dataframe" src="frame_a.htm" onload="load()">
let the text box have an id - say "test"
function load()
{
document.getElementById('test').value=document.getElementById('dataframe').src
}

How do you keep content from your previous web page after clicking a link?

I'm sorry if this is a newbie question but I don't really know what to search for either. How do you keep content from a previous page when navigating through a web site? For example, the right side Activity/Chat bar on facebook. It doesn't appear to refresh when going to different profiles; it's not an iframe and doesn't appear to be ajax (I could be wrong).
Thanks,
I believe what you're seeing in Facebook is not actual "page loads", but clever use of AJAX or AHAH.
So ... imagine you've got a web page. It contains links. Each of those links has a "hook" -- a chunk of JavaScript that gets executed when the link gets clicked.
If your browser doesn't support JavaScript, the link works as it normally would on an old-fashioned page, and loads another page.
But if JavaScript is turned on, then instead of navigating to an HREF, the code run by the hook causes a request to be placed to a different URL that spits out just the HTML that should be used to replace a DIV that's already showing somewhere on the page.
There's still a real link in the HTML just in case JS doesn't work, so the HTML you're seeing looks as it should. Try disabling JavaScript in your browser and see how Facebook works.
Live updates like this are all over the place in Web 2.0 applications, from Facebook to Google Docs to Workflowy to Basecamp, etc. The "better" tools provide the underlying HTML links where possible so that users without JavaScript can still get full use of the applications. (This is called Progressive Enhancement or Graceful degradation, depending on your perspective.) Of course, nobody would expect Google Docs to work without JavaScript.
In the case of a chat like Facebook, you must save the entire conversation on the server side (for example in a database). Then, when the user changes the page, you can restore the state of the conversation on the server side (with PHP) or by querying your server like you do for the chat (Javascript + AJAX).
This isn't done in Javascript. It needs to be done using your back-end scripting language.
In PHP, for example, you use Sessions. The variables set by server-side scripts can be maintained on the server and tied together (between multiple requests/hits) using a cookie.
One really helpful trick is to run HTTPFox in Firefox so you can actually monitor what's happening as you browse from one page to the next. You can check out the POST/Cookies/Response tabs and watch for which web methods are being called by the AJAX-like behaviors on the page. In doing this you can generally deduce how data is flowing to and from the pages, even though you don't have access to the server side code per se.
As for the answer to your specific question, there are too many approaches to list (cookies, server side persistence such as session or database writes, a simple form POST, VIEWSTATE in .net, etc..)
You can open your last closed web-page by pressing ctrl+shift+T . Now you can save content as you like. Example: if i closed a web-page related by document sharing and now i am on travel web page. Then i press ctrl+shift+T. Now automatic my last web-page will open. This function works on Mozilla, e explorer, opera and more. Hope this answer is helpful to you.

How to offer a webapp to other sites. (div with javascript, iframe or..?)

I am quite new to web application development and I need to know how would I make other sites use it.
My webapp basically gets a username and returns some data from my DB. This should be visible from other websites.
My options are:
iframe. The websites owners embed an iframe and they pass the userid in the querystring. I render a webpage with the data and is shown inside the iframe.
pros: easy to do, working already.
cons: the websites wont know the data returned, and they may like to know it.
javascript & div. They paste a div and some javascript code in their websites and the div content is updated with the data retrieved by the small javascript.
pros: the webside would be able to get the data.
cons: I could mess up with their website and I don't know wow would I run the javascript code appart from being triggered by a document ready, but I wouldn't like to add jquery libraries to their sites.
There must be better ways to integrate web applications than what I'm thinking. Could someone give me some advice?
Thanks
Iframes cannot communicate with pages that are on a different domain. If you want to inject content into someone else's page and still be able to interact with that page you need to include (or append) a JavaScript tag (that points to your code) to the hosting page, then use JavaScript to write your content into the hosting page.
Context Framework contains embedded mode support, where page components can be injected to other pages via Javascript. It does depend on jQuery but it can always be used in noConflict-mode. At current release the embedded pages must be on same domain so that same-origin-policy is not violated.
In the next release, embedded mode can be extended to use JSONP which enables embedding pages everywhere.
If what you really want is to expose the data, but not the visual content, then I'd consider exposing your data via JSONP. There are caveats to this approach, but it could work for you. There was an answer here a couple of days ago about using a Web Service, but this won't work directly from the client because of the browser's Same Origin policy. It's a shame that the poster of that answer deleted it rather than leave it here as he inadvertently highlighted some of the misconceptions about how browsers access remote content.

Categories