Wednesday, June 15, 2011

Question on 3rd party JS

Question: How do you best use external JavaScripts and comply with PCI-DSS (from @joffemannen)

(Great answer from @johnwilander)

I've had more than one consultation on this issue and we've always had to start by explaining the full access and full trust model of loading 3rd party code and content. To start with there's an important distinction between loading a 3rd party code library such as jQuery, and loading DOM content with or without JavaScript. If they want DOM content then traditional iframing works fine until they want to interact with the 3rd party content or vice versa. Since they will be loaded from different domains they will not be able to access each other.

If they want interaction they have four ways ahead:
  • Hosted + controlled releases. Establish a B2B release cycle with the vendor in which new versions of script files are released to them via file transfer and not directly into production. Then they do whatever auditing and analysis their process requires and deploy under their own domain. Note that this works for code-only cases too, i.e. no 3rd party content. This used to be an issue back when everyone was "hot linking" but nowadays you typically see requirements to download and host yourself since 3rd parties don't want to have to pay for the bandwidth or even have the tough SLAs in place.
  • Reverse proxy. Setup a reverse proxy to mimic that the 3rd party content is served by themselves. This makes it look like they're hosting everything themselves but really they're not. However, in this case they can potentially filter and detect code changes. If code changes happen daily it'll just become noise but detecting less frequent changes may prove useful for the cert team.
  • Normal loading + ajax proxy. Let the 3rd party have their own release cycle, load from 3rd party's domain and set up an ajax proxy if the code requires that. That means their own domain is still serving the client calls but they just reflect whatever source code the vendor serves up.
  • Point subdomain to 3rd party. If they point a subdomain of their own such as googlemaps.mybank.com pointing to Google Maps and host their own content on secure.mybank.com they can have both the iframe and the outer page set their docment.domain to a mybank.com and thus enable interaction.
In the three latter cases they're basically giving the 3rd party code the same privileges their own code has. So it has to be covered by the same processes (pentests and what not). This is typically when my customers have started considering the first option – "Hey, maybe we need to control what code runs on our page? And who writes that code. And how easy it is to hack into the hosting servers and replace that code. Damn!".

Regards, @johnwilander

2 comments:

Joffemannen said...

Thanks for a swift and excellent response! Would I embarrass myself completely if I asked you to expand a bit on a concrete example, such as the addthis button: Say your two different stores on your e-commerce site wants addthis buttons on the product pages, each store with it's own addthis pubid. And you have no prior business relation with addthis.

I take it that that simple piece of interaction requires the script to be called directly, and not from an iframe? In which case you have to ask addthis to adapt somehow?

Thanks again for all help in this neverending struggle between Web2.0 and security!

/Josef

Jim Manico said...

I would at least push untrusted JavaScript through JSReg or some other sandbox. Any more questions, email me at jim@owasp.org and I'll connect you with the right people and information.

Aloha,
Jim Manico
jim@owasp.org