Major sites running unauthenticated JavaScript on their payment pages
A few months ago, British Airways' customers had their credit card details stolen. How was this possible? The best guess goes something like this:
- BA had 3rd party JS on its payment page
<script src="https://example.com/whatever.js"></script>
- The 3rd party's site was hacked, and the JS was changed.
- BA's customers ran the script, which then harvested their credit card details as they were typed in.
This should have been a wake-up call to the industry. Don't load unauthenticated code on your website - and especially not on your payments page.
If you absolutely have to load someone else's code, check to see if it has been altered. This is done using SubResource Integrity (SRI).
SRI tells the user's browser to check that the code hasn't been changed since the website was published. It looks like this:
HTML
<script src="https://example.com/whatever.js"
integrity="sha384-eP2mZH+CLyffr1fGYsgMUWJFzVwB9mkUplpx9Y2Y3egTeRlmzD9suNR+56UHKr7v"
crossorigin="anonymous"></script>
If even a single bit of the code has changed since it was added to the page, the browser refuses to run it.
Who isn't using this
Deliveroo
Gig-economy food flingers add in code from CDNJS.
What's especially annoying about this, is that the CDNJS website has a "one-click copy" for SRI.
Spotify
Their payment page loads code from live.adyen.com
Adyen are their payment provider - so if they get hacked, credit card details are going to get compromised. But how much easier is it for an attacker to subtly change their JavaScript than to hack their entire mainframe?
The Guardian
Despite being a tofu-knitting member of the bourgeoisie, I am yet to subscribe to teh Gruan. If I did, I'd risk their affiliate tracker going rogue and stealing my organic credit card details.
Bonus points for leaving a handy pointer to their internal Google docs...
Fanduel
Sports betting site running unverified scripts from external sources.
They've also got external style-sheets
HTML
<link rel="stylesheet" href="//d2avoc1xjbdrch.cloudfront.net/6.26.0/styles/desktop.css">
If an attacker can change the JS or CSS, they could compromise users of the site.
EasyJet
I feel a bit conflicted about this one. You can probably trust Google not to get hacked. Right?
Google supports SRI - but doesn't mention it anywhere on their Hosted Libraries site.
British Airways!
Yup! They've not learned their lesson. Three pieces of unverified code running on the payment page.
- Maxymiser is an A/B testing and analytics tool. Run by Oracle now. Most ad-blockers prevent it loading.
- Google's reCAPTCHA. If that gets hacked, half the planet is compromised.
- SiteSeal "proves" your site is secure by displaying a image. No, I don't understand that either.

This does not make the site magically secure.
All three of them are highly trustworthy. But if you're BA and you've already been bitten by bad security practices, doesn't it make sense to go full "belt-and-braces"?
...and more?
These are just a small sample of the sites I've found. SRI has been available for two years and it still isn't being used enough.
Responsible Disclosure
I've reported this issue to a few sites by using responsible-disclosure aggregator HackerOne.
Typically, my warning goes unheeded with a response like:
Based on your initial description, there do not appear to be any security implications as a direct result of this behavior, this is an Informational issue at best, unless you can prove those third-party domains can be compromised in any way.
or
This appears to be more of a risk acceptance rather than a vulnerability. Although there is no PoC for this report, I will forward the information to the customer and see where to go from there.
That's fair enough. I'm not expecting a huge payout and it is only an informative report; I can't prove that the external sites are vulnerable. But there really ought to be a concerted effort to make payment sites as secure as possible.
This needs to be taken seriously. If you're handling users' details, you need to take every possible step to keep them secure.
No says:
@edent says:
Bob says:
I suppose some issues with using SRI is:
- how so the server admins get notified there is a newly updated JS? And how do they coordinate the switch-over so there is no downtime.
Thoughts?
@edent says:
Amy says:
So, if you use an outside service for payment processing (like spotify for example) are you suggesting they use SRI link for that script? Or to avoid using outside services at all?
I guess this line isn't clear to me:
@G2glvr says:
I liked the article and the one linked too:
https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity
SRI is good and it would work for included script code that is very static. If once it changes and the hash does not match then something goes bad on the payment page, especially if you are getting the whole payment script from a provider (like Spotify does in the example). Now payment page type companies should be really good at not changing their scripts lets hope. I guess if the SRI failed you could write code to fire off an email to some developer or write an entry in a well monitored log so that it could be fixed quickly, but the payment page may fail in some way. Having it fail if a hacker changes the script is awesome, having it fail because the provider company is just updating or improving code is more difficult. Hard to potentially notify all your potential link users and get them to change before the script changes…but possible.
An alternate would be to have two script places to go to in order to keep functionality going either until the hacked script is fixed or the updated script can be verified by the real provider. Maybe the payment page company provides an “always works but not so cool looking” backup script that they promise to never change the code you can switch to in an error or you could have an alternate company to go get a script (but now you are paying twice for services…depends on how much money you process I guess, may be worth it). Or, just throw up an error message saying “we can’t take your money today, try tomorrow”.
Another problem I see is that SRI is not supported by Edge (partial support) or Internet Explorer (as of Nov 6, 2018 at least) which I expect is still a pretty big portion of the browsing community. So a browser side solution as of now is not a very comprehensive control.
The developer could still check if the script loaded and fall back to an alternative provider, just as it would if the script server was offline.
Dave says:
Hector Eryx says:
I know it might not be possible for most cases, but for things that you now must be controlled it is better to have them under your control. If for whatever reason their JS code needs to change, it is the engineering team (development & infrastructure) who should be notified first.
Alex says:
CS253 - Web Security said on :
Reply to original comment on
|