JavaScript HTTPS to HTTP iFrame Security Question - javascript

I'm working on a user login system and I have come up with a solution that I wanted to run past you fine folks to make sure I wasn't about to create a giant security flaw.
Here is what we have.
You start on an HTTP page that when you click a link will open a modal window. The first link from an HTTP page when clicked will repopulate the modal with an iFrame that links to an HTTPS page. Since I can't have the HTTPS talk to the HTTP page I'm using a document.location setting on the HTTPS iframe page to make the success page HTTP. Then the HTTP page talks back to the parent window.
So:
HTTP (click) -> Opens iFrame in HTTPS -> Login over HTTPS secure on Success document.location -> HTTP success page -> window.parent.success_msg(deferred); calls to the parent window.
It's working great in all browsers so far...haven't tested IE yet, but I wanted to verify this wasn't a really terrible practice before I present it.
Thanks!

An iframe to an HTTPS URL within an HTTP page is really bad practice because it makes it hard for the user to get more detailed information (in particular security-related information) about that page. (Sure, you can probably right click and find a way to check the properties of the iframe, but even users who'd know how to do that probably wouldn't do it).
With an HTTPS iframe like this, you prevent the browser from displaying the usual security symbols: lock, green/blue bar and, more importantly, the address of the site (an attacker could just put their own link to their www.some-other-site.example instead of the indented site; www.some-other-site.example could have a legitimate certificate and the browser wouldn't give any alert message).
This practice is especially bad as an HTTPS iframe within a page served over HTTP, but it's not good either when the containing page is served over HTTPS. You can't easily verify the identity of the server serving the framed page either. (Sadly, this is (or at least was) what's recommended by 3-D Secure...)
If you want to do the authentication over HTTPS, switch the full page to HTTPS and then back, by giving a non-secure cookie. Of course, this isn't very secure (someone could intercept that security token, as popularised by FireSheep), but this is better in that at least, the user will be able to check that the page where they enter their credentials is the legitimate one. (This should be done carefully too, see this question.)
The best way is to stay over HTTPS without iframes after authentication if you can.

Related

How can I make redirects from my secure website sent with HTTP instead of HTTPS

I'm using an external service (IDXBroker) to embed elements like a search bar into my real estate website via their script tag widgets. Before my website was not SSL secure and did not use HTTPS, so the search bar widget redirect was sent with HTTP, and the redirected IDXBroker page looks normal. However, now that I have secured my website, the redirect somehow now becomes sent with HTTPS, and the styling is screwed up because IDXBroker wants the request to be HTTP.
I can't change anything about the actual IDXBroker widget because I can't change anything under the script tag. Is there a way I can tell my website to stop "upgrading" the http request to https and behave as it was when my website wasn't secure?
Thanks!
If your website is now secure with HTTPS, then you will want to enable HTTPS for your IDX Broker pages in your account under Account -> Details when logged in.
Support Article: https://support.idxbroker.com/support/s/article/enable-https-or-ssl-on-your-idx-site
This will make sure you do not run into mixed content issues as stated above. I would recommend forcing http -> https redirects just as your website would to ensure everything is secure.

Best way to make a request to external web service

So, I have this web application that shows network products for a specific network. The web server is not inside the network, so in order to show the visitor what network services he or she can order, I need to identify their computer inside the network.
So, I've been doing this with an iframe, which loads a specific in-network URL provided by my clients. This in-network URL will identify the visiting browser and then redirect it (inside the iframe) to a resource on my web service, with attached identification details.
For identification to occur, the in-network web server needs to receive a HTTP request from the visitor, but is this really the best way to handle this? Ajax cross domain is a bit of a mess as far as I'm aware, but I think iframe cross domain is equally shaky, or?
How would you solve this? The chain of events needs to be:
visitor visits my.web.com/services
visitor is sent to client.network.com/identify
Which redirects to my.web.com/identifier?id=XXYY
Now I can set a cookie for my.web.com on the user browser that their id is "XXYY" (or update member profile if logged in). Obviously this request needs to be asynchronous since the in-network web server may be slow to respond, so just a normal redirect is off the table.

How does pushState protect against potential content forgeries?

As seen in GitHub's blog, they've implemented HTML5's JavaScript pushState feature for tree browsing (for modern browsers), bringing AJAX navigation without Hash Bangs.
The code is simple:
$('#slider a').click(function() {
history.pushState({ path: this.path }, '', this.href)
$.get(this.href, function(data) {
$('#slider').slideTo(data)
})
return false
})
This quite elegantly allows them to:
Request the just the new content through AJAX instead of a full page
Animate the transition
And change the browsers URL (not just the #, as Twitter does — twitter.com/stackexchange → twitter.com/#!/stackexchange )
My question is, how does JavaScript prevent against the use of pushState by one website to imitate another, resulting in a convincing phishing attack?
At the very least it seems that the domain can't be changed, but what about multiple paths within a site, potentially by multiple unrelated and untrusting content providers? Could one path (I.E. /joe) essentially imitate another (pushState /jane) and provide imitative content, with possibly malicious purposes?
My understanding is that this is perfectly consistent with the Same Origin Policy that governs XMLHttpRequest, setting cookies, and various other browser functions. The assumption is that if it's on the same domain + protocol + port, it's a trusted resource. Usually, as a web developer, that's what you want (and need) in order for your AJAX scripts to work and your cookies to be readable throughout your site. If you are running a site where users can post content, it's your job, not the browser's, to make sure they can't phish or keylog each other's visitors.
Here's some more detail on what the FireFox folks are thinking about pushState - it doesn't seem like this is an issue for them. There's another discussion of a possible pushState security hole here, but it's a different concern, about being able to hide a malicious querystring on the end of someone else's URL.
As nrabinowitz has stated and in more layman's terms: it's limited to the same domain, just like ajax calls and cookies. So it's completely safe—though a little sneaky to the end user.
Us (developers) have been doing this forever with hash tags forever but it's better because:
It looks cleaner.
On revisit of a deep link you can actually surface real html data to support things like SEO and Facebook Open Graph (both send spiders to scape the html of your page).
Servers don't have access to hash tags data so you don't see it in your server logs so it helps some with analytics.
It helps fix hash tag issues. For example I had an Nginx rewrite to redirect users visiting my app to the same https url. It works in all browsers but Safari which will redirect you to just the domain without the hash (so annoying!)

Can one use Ajax on Google App Engine as a logged in user over https from a non-appspot.com domain?

Suppose:
You have a website http://www.example.com that redirects to a project on Google App Engine (i.e. example.appspot.com);
you want communications to pass between the user over SSL (i.e. https://example.appspot.com); and
You want the domain to be shown to the user to be *://www.example.com (i.e. not https://example.appspot.com).
Given that Google's Appspot HTTPS support only works for https://example.appspot.com (i.e. you cannot set up https://www.example.com with GAE), I'd like to have an Ajax solution, namely:
http://www.example.com serves HTML and Javascript over http
Ajax requests go over SSL to https://example.appspot.com
My question/concern is: How does one ensure that the users logged into http://www.example.com (by way of Google's users API) pass their authentication credentials over Ajax to https://example.appspot.com?
This seems to be a violation of the same origin policy (which may or may not be a concern for the Google Users API), so how would one know what user is logged in to example.com for the Ajax requests to example.appspot.com?
Thoughts, comments and input is quite appreciated.
Thank you.
Brian
There are ways to work around same-origin when both sites cooperate, e.g. see this post, but only trial-and-error will reveal which techniques do work for your specific requirements (it may depend on how strictly the user has set security safeguards in their browser, as well as on server-side implementations).
You can try using JSONP to get around the around that. However JSONP doesnt have very good error recovery like JSON does when doing XHR calls.
Wouldn't it be far simpler to use frames? Serve up a single full-size frameset from yourdomain.com containing content from https://yourapp.appspot.com/.
Note, though, that either solution has the problem that users see an unsecured site, not a secured one.
example.appspot.com does not share any cookies with example.com - it will be impossible for you to identify the user without making them sign-in on example.appspot.com as well.
you could, of course, completely ditch Google Authentication on example.appspot.com and implement your own scheme; you could append a signature and the username to the AJAX requests you create and verify that signature on your app-engine app. if the signature is valid, just accept the user that was passed in as the authenticated user and pretend he logged in.

Cross domain with an Iframe, pointing to SSO server

I have an application where I am displaying some stuff in javascript modals using jquery.
It requires the user to login for certain flows; but the user never leaves the modal.
So here is what we do currently.
During user flow if the user needs to be logged in, we hide the current div and show a login div
Keep a hidden iframe with Source link as that of our SSO server.
Once user submits the form, we submit the hidden iframe to the SSO server
If user gets logged in we proceed with the flow.
Problem is when there is error logging in. We need to get the error codes from the hidden iframe of the page; but because we don't control the content inside iframe, and it's returned by SSO server; we don't know how to read it since it's cross domain.
Any insights?
So long as there is not client side script being executed from the SSO party you do not need the iframe. The point of using an iframe for security is to prevent AJAX methods from ignoring single origin policy and circumventing SSL encryption. The answer is to remove the iframe. Request the SSO data from the server side and send it to the client from your server as the page is built.
You can't get around x-domain restrictions unless you use the jsonp protocol.
Could the user simply see the error response on page? Why do you have the iframe hidden atm?
Are you trying to silently log in the user to another system using the iframe technique?
Even though that might work on most browsers - some browsers won't pass cookies in i-frames - making this approach not a good broad audience solution.
Let me know if I can clarify.
Use JSONP to callback the function you prevented in your website, then in the iframe, you just need to invoke the javascript function: "parent.callback()".

Categories

Resources