<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="https://shkspr.mobi/blog/wp-content/themes/edent-wordpress-theme/rss-style.xsl" type="text/xsl"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	    xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	     xmlns:dc="http://purl.org/dc/elements/1.1/"
	   xmlns:atom="http://www.w3.org/2005/Atom"
	     xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	  xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>
<channel>
	<title>sri &#8211; Terence Eden’s Blog</title>
	<atom:link href="https://shkspr.mobi/blog/tag/sri/feed/" rel="self" type="application/rss+xml" />
	<link>https://shkspr.mobi/blog</link>
	<description>Regular nonsense about tech and its effects 🙃</description>
	<lastBuildDate>Fri, 29 Nov 2024 09:39:15 +0000</lastBuildDate>
	<language>en-GB</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>

<image>
	<url>https://shkspr.mobi/blog/wp-content/uploads/2023/07/cropped-avatar-32x32.jpeg</url>
	<title>sri &#8211; Terence Eden’s Blog</title>
	<link>https://shkspr.mobi/blog</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title><![CDATA[Major sites running unauthenticated JavaScript on their payment pages]]></title>
		<link>https://shkspr.mobi/blog/2018/11/major-sites-running-unauthenticated-javascript-on-their-payment-pages/</link>
					<comments>https://shkspr.mobi/blog/2018/11/major-sites-running-unauthenticated-javascript-on-their-payment-pages/#comments</comments>
				<dc:creator><![CDATA[@edent]]></dc:creator>
		<pubDate>Thu, 29 Nov 2018 12:39:41 +0000</pubDate>
				<category><![CDATA[/etc/]]></category>
		<category><![CDATA[hack]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[NaBloPoMo]]></category>
		<category><![CDATA[Responsible Disclosure]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[sri]]></category>
		<guid isPermaLink="false">https://shkspr.mobi/blog/?p=30747</guid>

					<description><![CDATA[A few months ago, British Airways&#039; 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 &#60;script src=&#34;https://example.com/whatever.js&#34;&#62;&#60;/script&#62; The 3rd party&#039;s site was hacked, and the JS was changed. BA&#039;s customers ran the script, which then harvested their credit card details as they were…]]></description>
										<content:encoded><![CDATA[<p>A few months ago, British Airways' customers had their credit card details stolen.  How was this possible?  The <a href="https://www.theregister.co.uk/2018/09/12/feedify_magecart_javascript_library_hacked/">best guess goes something like this</a>:</p>

<ol>
<li>BA had 3rd party JS on its payment page <br><code>&lt;script src="https://example.com/whatever.js"&gt;&lt;/script&gt;</code></li>
<li>The 3rd party's site was hacked, and the JS was changed.</li>
<li>BA's customers ran the script, which then harvested their credit card details as they were typed in.</li>
</ol>

<p>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.</p>

<p>If you absolutely have to load someone else's code, check to see if it has been altered.  This is done using <a href="https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity">SubResource Integrity</a> (SRI).</p>

<p>SRI tells the user's browser to check that the code hasn't been changed since the website was published. It looks like this:</p>

<pre><code class="language-html">&lt;script src="https://example.com/whatever.js"
        integrity="sha384-eP2mZH+CLyffr1fGYsgMUWJFzVwB9mkUplpx9Y2Y3egTeRlmzD9suNR+56UHKr7v" 
        crossorigin="anonymous"&gt;&lt;/script&gt;
</code></pre>

<p>If even a single bit of the code has changed since it was added to the page, the browser refuses to run it.</p>

<h2 id="who-isnt-using-this"><a href="https://shkspr.mobi/blog/2018/11/major-sites-running-unauthenticated-javascript-on-their-payment-pages/#who-isnt-using-this">Who isn't using this</a></h2>

<h3 id="deliveroo"><a href="https://shkspr.mobi/blog/2018/11/major-sites-running-unauthenticated-javascript-on-their-payment-pages/#deliveroo">Deliveroo</a></h3>

<p>Gig-economy food flingers add in code from <a href="https://cdnjs.com/">CDNJS</a>.
<img src="https://shkspr.mobi/blog/wp-content/uploads/2018/11/deliveroo2-fs8.png" alt="HTML source for Deliveroo's payment page." width="758" height="374" class="aligncenter size-full wp-image-30748"></p>

<p>What's especially annoying about this, is that the CDNJS website has a "one-click copy" for SRI.
<img src="https://shkspr.mobi/blog/wp-content/uploads/2018/11/cdnjs-fs8.png" alt="A drop-down menu with a highlight on &quot;Click to copy SRI&quot;." width="669" height="286" class="aligncenter size-full wp-image-30750"></p>

<h3 id="spotify"><a href="https://shkspr.mobi/blog/2018/11/major-sites-running-unauthenticated-javascript-on-their-payment-pages/#spotify">Spotify</a></h3>

<p>Their payment page loads code from <code>live.adyen.com</code>
<img src="https://shkspr.mobi/blog/wp-content/uploads/2018/11/Spotify-fs8.png" alt="HTML code from Spotify." width="769" height="162" class="aligncenter size-full wp-image-30751">
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?</p>

<h3 id="the-guardian"><a href="https://shkspr.mobi/blog/2018/11/major-sites-running-unauthenticated-javascript-on-their-payment-pages/#the-guardian">The Guardian</a></h3>

<p>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.
<img src="https://shkspr.mobi/blog/wp-content/uploads/2018/11/Guardian-fs8.png" alt="HTML source of the Guardian's website." width="649" height="127" class="aligncenter size-full wp-image-30756">
Bonus points for leaving a handy pointer to their internal Google docs...</p>

<h3 id="fanduel"><a href="https://shkspr.mobi/blog/2018/11/major-sites-running-unauthenticated-javascript-on-their-payment-pages/#fanduel">Fanduel</a></h3>

<p>Sports betting site running unverified scripts from external sources.
<img src="https://shkspr.mobi/blog/wp-content/uploads/2018/11/Fanduel-fs8.png" alt="HTML source for FanDuel." width="639" height="206" class="aligncenter size-full wp-image-30752">
They've also got external style-sheets</p>

<pre><code class="language-html">&lt;link rel="stylesheet" href="//d2avoc1xjbdrch.cloudfront.net/6.26.0/styles/desktop.css"&gt;
</code></pre>

<p>If an attacker can change the JS or CSS, they could compromise users of the site.</p>

<h3 id="easyjet"><a href="https://shkspr.mobi/blog/2018/11/major-sites-running-unauthenticated-javascript-on-their-payment-pages/#easyjet">EasyJet</a></h3>

<p>I feel a bit conflicted about this one.  You can <em>probably</em> trust Google not to get hacked. <a href="https://thehackernews.com/2018/10/google-plus-shutdown.html">Right</a>?
<img src="https://shkspr.mobi/blog/wp-content/uploads/2018/11/EasyJet-fs8.png" alt="HTML source of EasyJet's website." width="556" height="94" class="aligncenter size-full wp-image-30758"></p>

<p>Google supports SRI - but <a href="https://developers.google.com/speed/libraries/#jquery">doesn't mention it anywhere on their Hosted Libraries site</a>.</p>

<h3 id="british-airways"><a href="https://shkspr.mobi/blog/2018/11/major-sites-running-unauthenticated-javascript-on-their-payment-pages/#british-airways">British Airways!</a></h3>

<p>Yup! They've not learned their lesson. <strong>Three</strong> pieces of unverified code running on the payment page.
<img src="https://shkspr.mobi/blog/wp-content/uploads/2018/11/BA-fs8.png" alt="HTML code." width="824" height="204" class="aligncenter size-full wp-image-30800"></p>

<ul>
<li>Maxymiser is an A/B testing and analytics tool. Run by Oracle now. Most ad-blockers prevent it loading.</li>
<li>Google's reCAPTCHA. If that gets hacked, half the planet is compromised.</li>
<li><a href="https://www.globalsign.com/en/ssl/secure-site-seal/">SiteSeal</a> "proves" your site is secure by displaying a image. No, I don't understand that either.</li>
</ul>

<p></p><div style="width: 610px" class="wp-caption alignnone"><img src="https://shkspr.mobi/blog/wp-content/uploads/2018/11/seal_125-50_blue.png" alt="An SSL badge which proves nothing." width="125" height="50" class="aligncenter size-full wp-image-54278"><p class="wp-caption-text">This does not make the site magically secure.</p></div><p></p>

<p>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"?</p>

<h3 id="and-more"><a href="https://shkspr.mobi/blog/2018/11/major-sites-running-unauthenticated-javascript-on-their-payment-pages/#and-more">...and more?</a></h3>

<p>These are just a small sample of the sites I've found. <a href="https://www.w3.org/TR/SRI/">SRI has been available for two years</a> and it still isn't being used enough.</p>

<h2 id="responsible-disclosure"><a href="https://shkspr.mobi/blog/2018/11/major-sites-running-unauthenticated-javascript-on-their-payment-pages/#responsible-disclosure">Responsible Disclosure</a></h2>

<p>I've reported this issue to a few sites by using responsible-disclosure aggregator <a href="https://hackerone.com/edent">HackerOne</a>.</p>

<p>Typically, my warning goes unheeded with a response like:</p>

<blockquote><p>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.</p></blockquote>

<p>or</p>

<blockquote><p>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.</p></blockquote>

<p>That's fair enough. I'm not expecting a huge payout and it is <em>only</em> 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.</p>

<p>This needs to be taken seriously. If you're handling users' details, you need to take every possible step to keep them secure.</p>
<img src="https://shkspr.mobi/blog/wp-content/themes/edent-wordpress-theme/info/okgo.php?ID=30747&HTTP_REFERER=RSS" alt="" width="1" height="1" loading="eager">]]></content:encoded>
					
					<wfw:commentRss>https://shkspr.mobi/blog/2018/11/major-sites-running-unauthenticated-javascript-on-their-payment-pages/feed/</wfw:commentRss>
			<slash:comments>12</slash:comments>
		
		
			</item>
		<item>
		<title><![CDATA[Should you use SRI for self-hosted scripts?]]></title>
		<link>https://shkspr.mobi/blog/2018/11/should-you-use-sri-for-self-hosted-scripts/</link>
					<comments>https://shkspr.mobi/blog/2018/11/should-you-use-sri-for-self-hosted-scripts/#comments</comments>
				<dc:creator><![CDATA[@edent]]></dc:creator>
		<pubDate>Tue, 27 Nov 2018 11:57:31 +0000</pubDate>
				<category><![CDATA[/etc/]]></category>
		<category><![CDATA[NaBloPoMo]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[sri]]></category>
		<guid isPermaLink="false">https://shkspr.mobi/blog/?p=30762</guid>

					<description><![CDATA[Here&#039;s a curiosity which I found while stumbling through the Sony PlayStation store.    The website loads internally hosted scripts using SRI (SubResource Integrity).  Why?  Does your work require you to swipe an ID card to access the building?  That seems pretty normal.  Does your work also remind you to keep your badge visible, and to challenge people who aren&#039;t wearing theirs? That also seems…]]></description>
										<content:encoded><![CDATA[<p>Here's a curiosity which I found while stumbling through the Sony PlayStation store.</p>

<img src="https://shkspr.mobi/blog/wp-content/uploads/2018/11/Sony-SRI-fs8.png" alt="HTML source of Sony's PlayStation website." width="850" height="134" class="aligncenter size-full wp-image-30763">

<p>The website loads <em>internally</em> hosted scripts using SRI (<a href="https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity">SubResource Integrity</a>).  Why?</p>

<p>Does your work require you to swipe an ID card to access the building?  That seems pretty normal.</p>

<p>Does your work also remind you to keep your badge visible, and to challenge people who aren't wearing theirs? That also seems pretty normal. Sometimes security is breached, so we have multiple layers to keep us safe.</p>

<p>In Sony's case, they may know that many people have write access to the <code>/assets/</code> directory, but very few can write to the product templates.  So they add a further check even on code which they serve themselves.</p>

<p>This is <a href="https://en.wikipedia.org/wiki/Defense_in_depth_(computing)">defence in depth</a>.  But is it sensible?</p>

<p>If you're running a simple site, there's probably no benefit to this. If someone has the ability to maliciously alter a single JS file on your server, they probably have the ability to change the SRI hashes you're embedding.</p>

<p>But if you have a large and complicated infrastructure, it makes sense to double-check everything.</p>

<p>If you think I'm wrong - stick a comment in the box below.</p>
<img src="https://shkspr.mobi/blog/wp-content/themes/edent-wordpress-theme/info/okgo.php?ID=30762&HTTP_REFERER=RSS" alt="" width="1" height="1" loading="eager">]]></content:encoded>
					
					<wfw:commentRss>https://shkspr.mobi/blog/2018/11/should-you-use-sri-for-self-hosted-scripts/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title><![CDATA[Dynamic JavaScript and SRI]]></title>
		<link>https://shkspr.mobi/blog/2018/11/dynamic-javascript-and-sri/</link>
					<comments>https://shkspr.mobi/blog/2018/11/dynamic-javascript-and-sri/#comments</comments>
				<dc:creator><![CDATA[@edent]]></dc:creator>
		<pubDate>Sat, 24 Nov 2018 11:59:40 +0000</pubDate>
				<category><![CDATA[/etc/]]></category>
		<category><![CDATA[NaBloPoMo]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[sri]]></category>
		<guid isPermaLink="false">https://shkspr.mobi/blog/?p=30711</guid>

					<description><![CDATA[Some external JavaScript libraries are dynamic. That&#039;s a problem for the SRI model of security.  How can this be fixed?  Definitions  Suppose I want my website to have the latest version of the jQuery library.  I might use a Content Delivery Network (CDN) to serve the code for me.  &#60;script src=&#34;https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js&#34;&#62;&#60;/script&#62;   If an attacker were to…]]></description>
										<content:encoded><![CDATA[<p>Some external JavaScript libraries are dynamic. That's a problem for the SRI model of security.  How can this be fixed?</p>

<h2 id="definitions"><a href="https://shkspr.mobi/blog/2018/11/dynamic-javascript-and-sri/#definitions">Definitions</a></h2>

<p>Suppose I want my website to have the latest version of the jQuery library.  I might use a Content Delivery Network (CDN) to serve the code for me.</p>

<pre><code class="language-html5">&lt;script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"&gt;&lt;/script&gt;
</code></pre>

<p>If an attacker were to get access to that CDN, they could inject code into my site and compromise my users' privacy.</p>

<p>This is <strong>not</strong> a theoretical problem.  This is how <a href="https://web.archive.org/web/20181124205913/https://www.riskiq.com/blog/labs/magecart-british-airways-breach/">British Airways and others</a> were compromised. An attacker poisoned the external JS they were using and stole credit card details.</p>

<p>This is where SubResource Integrity (SRI) comes in.  Rather than just linking to an external script, I will also take a cryptographic snapshot of it (a hash). If the code changes, it will no longer match that hash, and the browser will refuse to run the external code.</p>

<p>This is what it looks like:</p>

<pre><code class="language-html5">&lt;script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js" 
   integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
   crossorigin="anonymous"&gt;&lt;/script&gt;
</code></pre>

<p>So far, so good.</p>

<h2 id="dynamic-resources"><a href="https://shkspr.mobi/blog/2018/11/dynamic-javascript-and-sri/#dynamic-resources">Dynamic Resources</a></h2>

<p>But not all external libraries are static.  Take <a href="">Polyfill.io</a> - a clever service which dynamically returns code based on what browser is requesting it.
<small>I've friends who work at the company which publishes Polyfill. These are my personal thoughts. I'm picking them because they're a popular service.</small></p>

<p>For example, if I include this script on my page:</p>

<pre><code class="language-html5"><br></code></pre>

<p>Firefox will get served the following JS:</p>

<pre><code class="language-js">(function(undefined) {}).call('object' === typeof window &amp;&amp; window || 'object' === typeof self &amp;&amp; self || 'object' === typeof global &amp;&amp; global || {});
</code></pre>

<p>But Opera will get served a completely different script:</p>

<pre><code class="language-js">(function(undefined) {Object.defineProperty(Array.prototype,"values",{value:Array.prototype[Symbol.iterator],enumerable:!1,writable:!1});var Iterator=function(){var e=function(){return this.length=0,this},t=function(e){if("function"!=typeof e)throw new TypeError(e+" is not a function");return e},_=function(e,n){if(!(this instanceof _))r...
</code></pre>

<p>Because the contents are different, the SRI hashes will be different.  That means we can't use the <code>integrity</code> attribute.</p>

<h2 id="solution"><a href="https://shkspr.mobi/blog/2018/11/dynamic-javascript-and-sri/#solution">Solution?</a></h2>

<p>As noted on <a href="https://github.com/Financial-Times/polyfill-service/issues/487">Polyfill's GitHub page</a>, the service...</p>

<blockquote><p>sends a different content per User-Agent (and that's the point of the service), so for Subresource Integrity, website developers don't need a hash per URL, but per (URL, User-Agent) pair and they need to change the integrity attribute on a per UA basis</p></blockquote>

<p>There's no sensible way to verify that the code being sent back hasn't been tampered with.</p>

<h2 id="conclusion"><a href="https://shkspr.mobi/blog/2018/11/dynamic-javascript-and-sri/#conclusion">Conclusion</a></h2>

<p>You should use SRI for <em>all</em> your external resources. If you can't, then you should either take a static copy and serve it yourself, or run your own dynamic service.</p>

<p>For example, The Guardian runs the Polyfill code on its own servers.</p>

<img src="https://shkspr.mobi/blog/wp-content/uploads/2018/11/Guardian-Polyfill-fs8.png" alt="HTML source of The Guardian website. Polyfill is being loaded from their own CDN." width="649" height="85" class="aligncenter size-full wp-image-30753">

<p>I trust the people at the Polyfill service not to act maliciously. And I trust them not to get hacked. But I shouldn't <em>have</em> to trust them.  The same goes for any external service.  Trust but verify.</p>

<p><ins datetime="2024-11-24T08:14:43+00:00">Update! In 2024, <a href="https://www.akamai.com/blog/security/2024-polyfill-supply-chain-attack-what-to-know">Pollyfill.io was taken over and became part of a massive supply-chain attack</a>.</ins></p>
<img src="https://shkspr.mobi/blog/wp-content/themes/edent-wordpress-theme/info/okgo.php?ID=30711&HTTP_REFERER=RSS" alt="" width="1" height="1" loading="eager">]]></content:encoded>
					
					<wfw:commentRss>https://shkspr.mobi/blog/2018/11/dynamic-javascript-and-sri/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
	</channel>
</rss>
