Hacker News new | past | comments | ask | show | jobs | submit login
New Paypal gateway UI susceptible to spoofing (homakov.blogspot.com)
120 points by dsr12 on Dec 7, 2014 | hide | past | favorite | 51 comments

Doesn't this weakness potentially exist with any integrated payment page on any site using any payment platform, though?

There is always a level of trust involved with entering these kinds of credentials on-line. This is why some of the 3-D Secure systems make you (the customer) give them a greeting of your own choice to incorporate in the prompt for your confirmation code.

However, it seems that for many vendors the losses due to a higher rate of aborted checkouts make such systems undesirable. Apparently most customers don't share the author's concern here, presumably either unaware of the potential security issues or just trusting that if anything does go wrong then some protection or guarantee from their payment service/card issuer will get it fixed.

I suspect the author here would argue that it would be better for on-line payments to be push transactions rather than pull, so users always actively send money via a trusted party such as their bank without ever handing over their bank-issued credentials to anyone else. No doubt many of us would agree with that; pull-based payment models are fundamentally insecure and absurdly vulnerable to fraud. But again, that goes for a lot more than just PayPal.

If 3D is anything like the silly Verified by Visa, it's atrocious. Some strange domain that sounds like a generic phishing attempt. Random password with supposedly a secure phrase to indicate they know me... But anyone with my card details can look that up and show it for me. I see no value in such systems, and they must murder conversion rates.

3-D Secure is the umbrella term for schemes like Verified by Visa, and yes, there has been a lot of criticism of both the added security (or not) and the disruption to the payment process and consequent hit on conversion rates.

The major advantage for merchants of using these schemes is that liability for various types of card fraud is shifted elsewhere, instead of the merchant getting dumped with the cost of fraudulent transactions even if they did nothing wrong except trust the payment services to do their job.

Much of this is likely to change again early next year, because there are SEPA-wide rules coming in that require strong authentication for Internet payments. Even the giant payment services can't ignore them, because liability for fraud on their networks is (finally) going to land on them whether they like it or not after the new rules take effect.

In cases like this, asking users for information, especially for payment details, for a different site than the user is visiting (e.g. PayPal) should be done using separate windows or iframes. Period. Additionally, the specification for visible iframes should make it clear to the user the iframe’s document URL. The iframe itself should have its own non-editable URL address bar, including an interactable area to allow the user to request information about the security details of the framed page for pages requested over SSL/TLS.

Thinking that an iframe will work here is fundamentally flawed unless the verifying metadata resides wholly outside of the browser's content window.

Even if you require the iframe to have some specific styling and make it so the parent DOM cannot edit it, we're talking about spoofing.

With html, js, and css you can reproduce absolutely any iframe styling by simply not using an iframe and pretending you are.

If you were to put the iframe's true url in the location bar e.g. having url: https://github.com/fragement | selected: https://paypal.com/fragment then that could sovle the problem however.

Browsers cannot edit domains in the location bar so this could work, but your suggestion absolutely doesn't.

Furthermore, I don't think the idea I outline above is a good idea because it requires users to learn something more. I'd rather just have the "redirect to and redirect back when done" solution since people have already learned to check "am I on paypal, does my address bar say paypal, is my ssl cert thingy green" and relearning to check "is my selected url paypal even though I'm on github" is not something that would happen quick enough in my mind.

But it would be very easy to forge any secure iframe address bar using JS/CSS.

The bar would be part of the user agent's iframe element, not accessible via JS/CSS.

Sure, you could overlay an element on top of the bar with JS/CSS, and some thought would have to be put in to avoid that type of forgery.

The spoof element wouldn't need to be an iframe though. They could use any element and apply fake "secure iframe" styling.

The method PayPal is using right now, the one mentioned in the article, utilizes iframes.

> The iframe itself should have its own non-editable URL address bar

This would definitely be good for security, but I feel like it would probably be overkill for many other iframe use cases. Think about every YouTube embed having an address bar. And what about the "hidden" iframes that are only 1x1, do you still show an address bar? Do you set a minimum size for iframes?

Obviously there would need some additional thought put into this. It might be a net-positive for every YouTube embedded video to have an address bar (copy from the iframe url and paste the embed URL into the browser's address bar, YouTube could detect that it's not being loaded into a frame and take the user to the standard video page).

As far as the 1x1 and minimum frame size, I don't know. 1x1 iframes are usually hidden (is there any point to having them visible?). I don't think it's a specification's place to enforce minimum size limits for elements (frames or otherwise). Perhaps the user agent could display a button that the user could interact with if the iframe size were smaller than a certain size.

And would be trivial to spoof by just drawing your own address bar. Bonus points for detecting browser/OS and drawing the appropriate version.

The certificate verification UI in browsers only works because it's outside of the area that a website could display a fake one in. You'd need some kind of indicator tied to the iframe from outside the web view, otherwise they'll end up like the ads that looks like popup windows to trick you into clicking the close button.

But as long as the attacker can detect when the user opens devtools all your efforts are futile.

This sounds even scarier - the user should be in control and able to inspect the page without the page knowing, since as he mentions, the attacker could otherwise deploy countermeasures to evade.

Looking at the code it looks pretty easy to circumvent: don't use firebug, have the devtools open when loading the page or have them open undocked by default. The detection method for non-firebug devtools is pretty silly: it checks the window size.

Even so, I'd appreciate it if the browser vendors took additional steps to disable the detection of devtools, personally. I don't think they should be detectable under any circumstances, if that's possible to implement.

If you're going to trust a website with your credit card you probably trust them enough to not try and steal your paypal information.

There isn't a way to solve this issue without hurting the user experience. For some websites, that's a fair trade off.

Maybe a browser could put in a "Verify iframes" button that would show you the payment form is actually coming from PayPal.

Not having to trust a website with my credit card details is one of the main reasons I tend to use PayPal at all, and it's something they're actively advertising with [1]. I understand it's hard to find a solution that offers both good UX and security. Maybe they could have at least added a link to open the login in a new window on their domain for users who want to easily verify it's legit. Still, I think it's pretty irresponsible to teach users that entering login credentials on (essentially) a third-party website is okay.

[1]: https://www.paypal.com/us/webapps/mpp/paypal-safety-and-secu... @ Who you are is how you pay

There is a way to do this securely whilst improving the user experience. The merchant site can run PayPal's js, which would check whether the user is signed in to PayPal. If they are signed in, the js could just display a "confirm payment" button rather than requesting credentials from the user. If they're not signed in, it could just ask the user to sign in to PayPal in a new window, where the user can verify via the browser's address bar whether they are signing into the real PayPal.

Google Wallet for Digital Goods (which Google is retiring soon) does this, and I think it is the best payment user experience that has been made, so far.

> the js could just display a "confirm payment" button rather than requesting credentials from the user.


Ah, but part of the point of paying for something via paypal is that I _don't_ need to trust the website with my credit card information, I only need to trust paypal.

Huh, this seems very obvious in hindsight. I guess with Stripe things are a bit easier since you have none of this username/password stuff to be dealing with (you could get your cc number swiped, but if you're an American you're dealing with that issue everyday anyways).

Exactly, giving your CC details to some website is a routine, but your email+password are critical credentials.

Specifically because PayPal has incentives for people to link their bank accounts. If you have someone's login for PayPal, you may have access to their checking bank account.

This isn't a new thing, it's been possible for a number of years to integrate paypal using an iframe.

Hands-up - I'm guilty of doing this. I hadn't really considered the issue before, but I agree it is a security concern.

One of the reasons developers switch to using an iframe rather than a separate window is due to popup blocking. Retrieving the url for a payment system usually requires making a server side call, so it's impossible to then launch a popup directly from the user action. The solution would be to require a second user action after having retrieved the url.

A complete redirect isn't always the best case for single page web apps, either. Thankfully, we're a bit smarter about deep-linking these days, so that should no longer be an issue.

>This isn't a new thing, it's been possible for a number of years to integrate paypal using an iframe.

Yes, I know about classic integration options. But it's not about what was possible (any kind of phishing is always possible) it's about what Paypal suggests by default and what websites actually use.

> Retrieving the url for a payment system usually requires making a server side call


Or even just a regular link to site.com/get-url-for-paypal-then-redirect.

that's a good option - hadn't considered that approach.

Yeah, and it's very widely used in oauth. (Talking in separate threads is weird)

Don't most competent popup blockers actually allow popups which are implemented plainly as links with a different target? I mean, the popups you want to block are only the ones which don't result in a single window/tab opening directly based on a user input where you would expect a popup to result.

yes - as I mentioned above, it's impossible to do this in one step, though. It requires getting the url from a server-side call, and then rendering the link to that url. Since the pressure is on to reduce friction in the process, you can see why this has been reduced to using an iframe (which can launch seamlessly in a single button press).

If by "server-side" call you mean getting a token for Express Checkout, I don't see how it's different from any existing OAuth implementation where site.com/oauth/twitter redirects to twitter.com/?oauth_token=TOKEN. That's the best practice actually.

Shameless plug - i have an article on paypal's oauth which is similar to oauth1 but hasn't fixed it's token fixation bug yet: http://homakov.blogspot.com/2014/01/token-fixation-in-paypal...

This seems like something that's going to become more and more of a problem as services attempt to create ever more seamless integrations to create better user experiences.

Has anyone seen anything in a spec or recommendation that addresses a browser-UI solution to verifying the authenticity of iframes or other embedded objects?

Did Paypal just remove the issue reporting page or is the link in the article just wrong? https://www.paypal.com/webapps/mpp/security/report-problem

That link works, but this page is probably what was used - https://www.paypal.com/webapps/mpp/security/reporting-securi...

This is a big security problem with iframes. I have hoped for years that developers of the major browsers should understand this and automatically change the adress bar to the iframes url when the iframe is having focus. Problem solved!

Not really problem solved so long as browsers continue to have cross frame scripting (XFS) issues. There are also issues surrounding which iframe to enumerate in the address bar. Finally, additional attacks would surely arise. Because the host domain still owns the DOM it could overwrite the region where the iframe is presented, knowing that the address bar would change to a trusted domain. In short I see this sort of solution leading to major problems.

I do not agree with you! Cross frame scripting is not a problem today. If it was a problem PayPal would never use this UI. And for my solution: If I place the cursor for example in the password input, then the address bar of the browser would show the iframe url, so the enumeration is not a problem. And if the parent site places anything over the iframe, who cares, since it can not fake the address bar of the browser. The point of this solution is to give the user the possibility to verify what site the iframe belongs to.

Their is only solution today to verify if the iframe is legitimate or not and that is to include a link in the iframe that the user can click on (With the text: Is this a legitimate login form?). This links opens up a new browser tab and in that tab PayPal checks the referrer. If the referrer comes from PayPal (the iframe) we know that this iframe is not a fake one and can present that information to the user.

That problem burdens the user with constantly checking whether the address bar has changed on every interaction they have with the site. Currently, browsers are still trying to train users to check the address bar just once before putting their credentials into a site. Even for technically slanted users, checking the address bar on every interaction would be a bit too much to ask, I think.

There is a better way for technically aware users to check an iframe's authenticity. Chrome and Firefox, at least, let you right click anywhere in an iframe and get info about its URL and HTTPS cert.

I have implemented PayPal for Digital Goods a couple months ago. The Login page opens in a separate page. I wonder if it's a privilege they give to trustworthy websites?

untils websites become smart with these we need workarounds what I do on those occasions is one of two things, I would purposefully enter a random wrong username and password in to paypal which usually springs up a normal browser window with paypal url and then I retype my correct password. Or I would open a different blank browser window and log into paypal and then go to github and refresh which then automatically logs into paypal without reentering password..

> I would purposefully enter a random wrong username and password

It can be a smart proxy: while you type they type for you in another browser, and log it.

>which then automatically logs into paypal without reentering password..

Doesn't work with Paypal gateway, you always have to login.

PayPal probably has good enough fraud detection that easier-but-riskier integration is still a net win for PayPal. (Not so much for the rest of the internet, though...)

Similarly, Google's "No CAPTCHA" (https://news.ycombinator.com/item?id=8693767) lets Google offer a better experience than a traditional CAPTHCA. I'm somewhat surprised that better fraud detection leads to better UX, but it's pretty neat.

It's not just PayPal fraud per se. Leaking user's PayPal email address and password has a lot of other consequences. (Yeah yeah in theory you should use distinct passwords for different sites etc etc)

Yes, but if PayPal's security is good enough, that's everyone else's problem.

(Yes, that's pretty nasty - but is putting a poorly-secured "startup" online really any better?)

To log in paypal account password is enough, user-agent and IP/location can be faked. When you're in you get access to user's transaction history. Ouch.

I just spent 10 minutes navigating the Paypal website trying to activate 2-factor auth on my account. Apparently they don't even offer it, at least for Singapore accounts.


It doesn't make a difference. Just because a site is SSL-encrypted doesn't make it a site you should trust with your paypal credentials.

The only site you should trust with your paypal credentials is paypal. And the only way to be sure you're talking to paypal is to see paypal in the address bar with an SSL-encrypted session. (At least, that's what the whole web, browsers and CA's alike, have been striving to ensure is the case since the web has had encryption.)

You're not getting the core issue - the way real gateway works cannot be distinguished from phishing. "seamless" user experience confuses users and is going to create a whole new wave of phishing

The problem is that Github could open a popup with a form that looks the same, and you wouldn't be able to tell that you're not sending your credentials to Paypal only

Yeah but what to stop me from serving a fake popup over https://myfraudsite.com?

Nothing, but you can't hide that it is https://myfraudsite.com from the user since the browser always displays the URL (at least it does nowadays).

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact