Cross-Platform Browser Communication Between Page and IFRAME (Same Domain) - iframe

For a specialized purpose with Aweber regarding a newsletter subscription, I have a page loading a nested IFRAME inside, and both reside on the same domain. (Many other stackoverflow posts talk about different domains, but this question deals only with the same domain.) I need a cross-platform way (including browsers as old as the dawn of IE6) for the two to communicate.
For example, someone fills out name and email and clicks a checkbox, and the hidden IFRAME next to the checkbox sits in a setInterval() loop watching for that. When it receives notification, it grabs the name and email and does a form post.
I thought at first that I could just drop a cookie in the parent page, and then the IFRAME child could then sit in an interval watching for that cookie. But my tests show that this won't work. The cookie gets created -- but the IFRAME can't see it. So, I tried the meta-refresh technique in the IFRAME, and again it couldn't see that cookie for some reason.
The only solution I can come up with is that the parent page will take the checkbox click (we use jQuery) and do an AJAX data push to the server into a database. The IFRAME can then check on an interval back to the server via AJAX to see if the database value has changed, and react to it if so. But this seems like an over-engineered solution and I'm looking for an easier alternative that works cross-platform, even in earlier browsers from the timeframe of IE6 and forward.

It's much more simple: In the iframe, you can access the parent variable, which contains the parent window. So you can use parent.document to find the form, read the values, etc.

Related

WordPress pluggin not working with multiple instances of shortcode on the page (Social Discount Press)

The problem can be seen this page: http://ignitingthesixthsense.com/pre-launch-1
The issue is with the pluggin called Social Discount Press. The purpose of this pluggin is that it prompts the user to share your webpage via social media, and if they do so a link will then appear giving them access to restricted content.
There are actually 2 problems, but I am not sure if they stem from the same issue or not.
1) The first issue is that I have placed the social share buttons on the page twice using this shortcode:
[social_sharing_discount index="2"]
And the second instance of the share buttons (towards the bottom of the page) do not work properly. The Facebook and Twitter button activate the share box when clicked, but after sharing, the "instant access" button does not appear beneath the share button as it should. And the Google button does nothing at all when clicked. I have found that if I remove the 1st instance of the share buttons (at the top of the page), then the second instance of them starts working, so in other words it only seems to work properly if there is one instance on the page at a time.
2) The second and much much smaller issue, is that when the Google share button is clicked, the access button appears before the person actually shares.
And assistance with this would be greatly appreciated.
I have found that the main cause of the issue was due to the pluggin being built mainly on ID's which need to be unique across the page. And having multiple instances of the same ID was causing many errors.
The solution was to rewrite some of the php and js to use Classes instead of ID's. This allowed for two instances of the pluggin to work on the same page, thus solving problem number one.
The reason why the google one is so inaccurate is because the author simply opens up a popup to the google share page in a popup, this doesn't allow us to see the JS events such as when we share.
On the other hand because the twitter and facebook jssdk are loaded into the page, we know the exact moment when there has been either of those have been shared and thus accurately display the instant access button.
Due to this the author of the pluggin is just doing a best guess as to when the user is likely to have shared. It this case the author is guessing that when the javascript onunload event fires, that logically the user has shared on google. Now the onunload event can be fired in multiple ways, one is when the user closes the popup, i.e the best guess scenario as to if the user has shared. However the onunload event also fires when the form loses focus, a user naviagtes a way or a link is clicked.
Furthermore the onunload event is only properly supported in IE, FF and Safari, not Chrome and Opera. Which in the end gives it differeing behaviour in different browsers.
All of this can lead to unpredicatable behaviour, such as what you are noticing.
A better solution would be for google to have a jssdk for the the google plus share that let's us create a share box on the fly, however it's lacking that functionality as of now.

How much data can an iframe read from its parent window?

If I create a widget and embed it in an <iframe> on a site that is from a different domain, how much data about the parent page can the widget read?
Obviously there's no DOM access, but is there any access to other information, such as whether the parent page has a parent, or what the url of the parent page is?
Normally the content of an iframe served from a different domain cannot access the parent in any way. It's like loading the page in a different browser tab.
However, even if served from a different domain, there is a possible man-in-the-middle attack which wil allow access to the parent DOM. This is easier than it sounds -- anyone who has administrative control over a public WiFi access point could carry out this attack (think Starbucks, hotels, airports.)
It is possible to protect against this attack using the HTML5 iframe sandbox attribute -- see below.
The man-in-the-middle attack works as follows. Suppose your page loads off http://yoursite.com and the iframe goes to http://badsite.org
first http://badsite.org redirects to http://yoursite.com/badpage
This is the step that requires a man-in-the-middle attack. The attacker must either be able to get between the user and yoursite.com, or control the answers to your DNS lookup. The goal is to serve the content of http://yoursite.com/badpage from the attacker's site, not your actual site.
The attacker can then serve whatever malicious code they like from the (fake) http://yoursite.org/badpage. Because this is in the same domain as the main page, it will have access to the parent DOM.
The HTML5 iframe sandbox attribute seems to be the way to avoid this. You can read the spec, but the best description might be here.
This seems to be supported on Chrome, IE10, FireFox, Safari.
The spec says that if the "allow-same-origin" attribute is not set, "the content is treated as being from a unique origin." This should prevent your child iframe from accessing any part of the parent's DOM, no matter what the browser thinks the URL is.
Sandbox also lets you disable scripts, pop-ups, the ability to change the top level URL, and other things.
I did a little google search, and it turns out that normally you cannot access the internal guts of the Iframe if the the content is another domain (same origin policy), however there's an article here which can give you some ways around that.

How can I stop the Flash privacy popup from occurring twice on a page?

My web-app records users via webcam and microphone. I want to use HTML/JS for the controls and content, so I created two separate Flex modules:
* A "Webcam Setup" module that lets you choose your camera and mic input devices
* A "record" module that lets the user record and submit the recording
When I embed either of these on the page, since they access the user's Camera/Mic object, Flash shows the Privacy dialog that says "[mysite] is requesting access to your camera and microphone. If you click Allow, you may be recorded."
The problem is, if I answer Yes in the Setup module, and later add the Record module to the page using Javascript, it again shows the Privacy dialog.
Is there a way to avoid the second privacy popup?
I would think that saying "Yes" for [mysite] would store that permission for at least that session, but apparently not.
What I've tried
I tried combining them into one SWF, adding it to the page once and moving the DOM element with jQuery's append() function when needed. When I move it, however, it reloads and asks me again.
Imagine if [mysite] was, say, blogger.com or livejournal.com (or, if it were still around, geocities.com). Would you want a "yes" response on that site to be good for every page under that domain?
Rememeber, just because you promise (cross your heart & hope to die) not to abuse the security hole you request, doesn't mean they can allow you to have that security hole.
Eventually, I found a usable workaround, similar to what I originally tried (above).
I combined the setup and record modules into one SWF. I first show the setup screen. When the user hits the Continue button on my page, Javascript calls a function in the SWF to swap to the Record screen.
I then move the <div> containing the Flash object to another location on page using absolute positioning, and resize the object.
Previously, I was trying to use jQuery's append() function to move the div within the DOM, and that was causing the SWF to reload. Just changing position and size does actually work.
You could build the "record" component to simply send and receive signals using an API you've created for your "setup" component (which has already been authorized, meaning one auth & two swfs) by using the LocalConnection class:
http://livedocs.adobe.com/flex/3/langref/flash/net/LocalConnection.html
This seems far closer to best practice than the other implementations mentioned, which smell a bit hacky and would probably confuse anyone who may inherit the codebase in the future.

How to login without leaving RP by showing the OP login window in iframe?

How to login without leaving RP by showing the OP login window in iframe ?
I am using Openid Provider for the login in my Website.
how to implement the login window inside the iframe.
Using an iframe is hugely frowned upon, since the user will be entering their credentials on a page that looks like it is your RP but is supposedly their OP instead. It teaches users to be phished.
If you're going to use an iframe anyway, very little special work has to be done. There are a few approaches you can take though. If you're taking the OpenID Identifier from the user on the page and will display an iframe based on the user input, then the easiest way is probably to use JavaScript when the user clicks "Login" to create an iframe and direct it at http://yoursite.com/redirect.aspx?openid=userSuppliedIdentifier. That page will perform OpenID discovery on the identifier and do the standard redirect to the OP, which will be limited to the iframe since that is where the request came from. The openid.return_to that you send to the OP will have to be to a special page that knows how to "pop out" of the iframe back into your main window. It's really a very similar flow to the popup window approach which I point you to a demo to below, but instead of a popup, you do it in an iframe.
Rather than an iframe, the recommended way if you don't want to send the users away momentarily from your site, is to use a popup window. Just one such example of this is DotNetOpenAuth's ajax login sample, but there are other ways to do it. It's always complicated to get it working across browsers and working securely. We'd need to know what web platform you're using (ASP.NET, PHP, Perl, Python, etc.) before going much further.
(In response to Andrew Arnott's response) I'm bothered that popups are considered the norm for redirects. It's true that Facebook has adopted this approach, but I don't think it's the final solution. From a UI/UX pov in other applications, we've tried to move away from popup windows in favor of inline types of user experience. (popup ads, for instance are extremely annoying) Popups in general are just aggravating. Hence javascript library third-party widgets such as thickbox/lightbox/shadowbox. These solutions allow for iframe loaded content.
Plaxo and Google provided an experiment showing something like a 92% return rate for users who signed in with a two click OpenID process, so the question isn't about return rate, and yes popups can work in that scenario, however...
What I think hasn't been solved is adoption rate, and this comes down to basic usability and user experience, and what most engineers seem to be missing is the fact that users are completely driven off by popups.
It's true that phishing is a problem, but I think the onus and burden for better security lies with the developer on this one, and not the user. For this reason, I still think an inline experience is best, and, unfortunately, iframes are the only methodology currently employable. There are solutions, however, to prevent phishing.
I see that you are discussing usage of iframes for OP authentication. Have you considered the fact that clickjacking becomes possible when using iframes? In fact, many OPs do not allow their pages to be included in an iframe, e.g. VeriSign, Yahoo, myOpenID, etc. They break out of iframes using the HTTP header X-FRAME-OPTIONS, or JavaScript like this:
if (top.location != location) {
top.location = self.location;
}
Take a look at http://ajaxian.com/archives/busting-framebusters-clickjacking-is-still-a-big-issue for more information.

Loses session state in iframe, but not in pop-up window

We're developing a web shop, and process payments with a third party UI.
We have chosen to show the payment UI inside an iframe inside out check-out page, even though (we now realize), the payment solution provider recommend using a top-level window.
Now what happens is that in IE7/IE8, the payment UI loses session state on the first postback (inside the iframe), while in Firefox, it works just fine. We observe that the payment UI is developed using ASP.NET.
I was under the impression that as far as the server is concerned, there is no difference between being referenced from an iframe versus from a top-level window, but clearly there is.
Does anyone have a clue? What does an iframe do that could possibly make a difference to the payment server, causing it to lose session state?
Could it (it suddenly dawns on me) be differences in cookie handling? Stricter security perhaps?
Probably caused by this:
Internet Explorer 6 introduced support for the Platform for Privacy Preferences (P3P) Project. The P3P standard notes that if a FRAMESET or a parent window references another site inside a FRAME or inside a child window, the child site is considered third party content. Internet Explorer, which uses the default privacy setting of Medium, silently rejects cookies sent from third party sites.
http://support.microsoft.com/kb/323752/en-us
I once heard someone say that an IFrame is actually a new instance of IE, but apparently it's a bit more complicated.
You might find this article by Milan Negovan helpful to explain why framed pages get a separate Session ID. The article also talks about the P3P solution mentioned by Gerrie Schenck above.
so the structure of your code/site would be something like:
Site A has Page 1 has an iframe which displays Site B
the iframe updates and now displays Page 2 from Site A
and when you right-click on the contents of the iframe you can verify that the url is corresponding to Site A?
If you debug, does Page 2 fire off your breakpoints as expected?

Resources