Well people need to stop writing code specifically for IE and just stick to web standards. If Google/Facebook/PayPal/All Banks stopped coding hacks to get their sites to work in IE, the users that use IE would have no other choice but to switch to a standards compliant web browser.
IE users should get the standard-compliant pure-HTML version which is sure to work on every browser. Only developers who neglected to start there have a problem.
I dont buy it. Some features just aren't reasonable to do without js and the number of people without js is tending towards vanishingly small, and you can have a nondegraded experience for a very significant percentage of traffic by not just dismissing all versions of IE. Not that you should support all versions, but if you are sending a separate no-js version to IE10 then you are doing it wrong.
In my experience it is totally absurd to think that you can just write "standards compliant HTML" and expect it to be rendered correctly on IE6 or 7 in any meaningful way anyway, you will always need to change your HTML and CSS to specifically support those browsers and realistically any browser that you want to support, the standards just are not uniformly implemented.
Alternatively, we could stand on the shoulders of giants. I've used the easyXDM library to abstract away cross domain hassle in a couple of large projects and am surprised it doesn't seem to be more widely known of.
I'm curious about how this change handles cross-domain security. Is there never any sensitive data in Stripe.js' JSONP responses? Or do y'all have a mechanism for preventing a malicious 3rd party site from loading a script pointing at one of your JSONP urls?
It shouldn't be any different than the existing functionality. stripe.js is solely responsible for turning credit card information into one-use tokens, so that CC information never hits your servers. That token is then used to communicate with Stripe using a private shared key (kept serverside, never exposed on the client) to create a Customer record, which is then used to conduct the actual money parts of the transaction.
So, a malicious party could create tokens with CC information, but without the private key they'd have no way to use them.
Interesting they choose JSONP (which is GET only, and can't return proper error codes) for such a POST-heavy library. It doesn't really matter, since they abstract it away. However, it's interesting they're completely ignoring so many basic REST principles.
Edit: I don't disagree with their decision, I just imagine it wasn't an easy one.
I'd rather have a functioning solution that "ignores basic REST principles" and lets me accept money from IE users than a principled library that requires the latest greatest browser to process transactions with.
It's not interesting, if you read the post you would know that they did it because of IE lacking support for CORS.
> Unfortunately, that’s not quite enough for Stripe.js. IE6 and IE7 both lack CORS support, while IE8 and IE9 have broken implementations. IE10 is the only version with a non-buggy CORS implementation. Obviously, compatibility is paramount for Stripe.js — we want to support all major browsers, right down to IE6—and so we needed to look elsewhere.
I'm not sure how common this is, but our application totally has a middleware to allow simulating other methods via _method and _body querystring parameters in GET requests. I know I've seen many other companies do this. Some may scoff at this for probably naive reasons, but REST doesn't have to mean 'correct' HTTP. It's just an architectural style.
This seems like a step backward. The iframe-based communication, as hackish as it seems, allows cross-domain communication without resorting to completely unsandboxed script tags referencing a remote server. Meanwhile, JSONP uses a script tag, and nothing forces the response to actually conform to JSONP (JSON wrapped in a specific function call) rather than running arbitrary Javascript code.
The only new exploit I can think of is domain hijacking, so that an attacker replaces the real
Stripe response with their own. If they can do domain hijacking, though, whether or not they choose to insert the replaced content into a third party page via JSON is a less damaging hack than just swiping your credit card info sent to Stripe.
Domain hijacking doesn't seem like an issue here, given HTTPS; if someone can MITM that they can do the same to my own site.
However, just because I trust a service to process payments or do any other specific business-critical task doesn't mean I trust that service to run arbitrary Javascript code in the context of my site. Customers may have significantly more sensitive data than just payment information, and third-party Javascript represents a major issue. I need the ability to confidently say to customers that no third-party service has access to their private data.
Given this new approach, I'd have to sandbox payment code off on a separate domain that has no access to other user data.
> However, just because I trust a service to process payments or do any other specific business-critical task doesn't mean I trust that service to run arbitrary Javascript code in the context of my site.
You...include their Javascript on your site to even be able to make the JSONP calls in the first place. Their "arbitrary Javascript" is on your domain already.
You certainly could audit it, locally mirror it, and then do that every time they publish an update, but are you actually going to do that?
Even without auditing it or with just a cursory audit, mirroring third-party code makes a difference. If you copy the code then you have a complete history of code changes in your own source control, which should make shenanigans unlikely since it's easily proven. That's quite a bit different than using a live third-party URL, since the third party (or an attacker) could selectively replace it for some targets and you'd never know.
So yes, it's a good idea to always check any third-party code you use into your own source control system. I would hope everyone does that.
> You certainly could audit it, locally mirror it, and then do that every time they publish an update, but are you actually going to do that?
Yes, absolutely. For any third-party Javascript, I'd either mirror it locally and review it for safety, or sandbox it on a separate untrusted domain that has no access to customer data.
I think the separate domain is a great solution in that case, but my point is that if you're worried about the use of JSONP as the transport being the insecure link, you're too late.
(The Web Intent polyfill is implemented with the same postMessage hack they were originally using, so technically they could just use the web intent and nothing else. Though in practice, it probably doesn't handle cross-domain iFrame messaging for the old browsers that don't support postMessage.)
Are there any security concerns with this? Is the URL of a GET request over SSL encrypted as well as the payload? I assume it must be if they are sending credit card information that way?
SSL/TLS is at a lower level than HTTP. The whole connection is secure as all the encryption is set up before the HTTP request is even sent. This is why SSL used to always require a dedicated IP address - The server didn't even know what domain you were going to while the connection was being set up (as the host name is in the HTTP headers) so you could only have one SSL certificate per IP address.
Server Name Indication (http://en.wikipedia.org/wiki/Server_Name_Indication) works around this by sending the host name during the TLS handshake, so that multiple domains can use SSL on the same IP address. In this case, only the host name is sent in the clear. The whole HTTP request and response are still encrypted.
If only all browsers supported SNI. The Android 1.x/2.x browser annoyingly doesn't (it's actually the fault of the Java Apache HttpClient). And ~75% of Android users are stuck on it.
Almost right. The entire URL, including the hostname, is "encrypted," but you still have to have the IP address of the machine you're talking to, which means your machine will probably be doing (unencrypted) DNS lookups and will send encrypted packets to the target's IP address.
Attackers can see the hostname of the machine you're talking to, but not because it's an "unencrypted" part of the SSL packet somehow.
Sorry for the off-topic comment, but I couldn't help but notice (and comment on) the noticeably slow-loading picture of Alex at the top, only to realize it's a 378KB 500x500 image[1] resized at render-time to 68x68.
I'm just surprised that a tech company like Stripe w/ such a polished site and attention to UX would not find a way to optimize this.
Ewwww JSONP. Keep it RESTful with useful response codes. People accepting credit card payments online should have the ability to do things server-side instead of use JS.
IE6, as usual, doesn’t support postMessage.
IE6 and IE7 both lack CORS support, while IE8 and IE9 have broken implementations
Oh what mankind could have achieved by now if we weren't so occupied making our websites work in IEx.