Mark Alan RichardsPosts by Mark Alan Richards.2024-01-23T00:00:00Zhttps://markalanrichards.comMark Alan Richardsmark@markoffline.comWho doesn't have remote access to your bank account?2024-01-23T00:00:00Zhttps://markalanrichards.com/posts/2024-01-23-the-computer-said-you-did-it/<p>Remote access was a notable concern raised in the Post Office.</p>
<h3 id="the-claim" tabindex="-1">The claim: <a class="direct-link" href="https://markalanrichards.com/posts/2024-01-23-the-computer-said-you-did-it/#the-claim" aria-hidden="true">#</a></h3>
<p>Fujitsu had access to act as the Subpostmaster on their tills.</p>
<p><strong>Is this unique to Fujitsu?</strong></p>
<h2 id="who-has-remote-access-to-act-as-you" tabindex="-1">Who has remote access to act as you? <a class="direct-link" href="https://markalanrichards.com/posts/2024-01-23-the-computer-said-you-did-it/#who-has-remote-access-to-act-as-you" aria-hidden="true">#</a></h2>
<ul>
<li>Remote access on your laptop</li>
<li>Remote access on your mobile</li>
<li>Remote access on your tablet</li>
</ul>
<p>It is likely a lot of companies can at some point act as you.</p>
<h2 id="websites-have-remote-access-as-you-on-their-site" tabindex="-1">Websites have remote access as you on their site <a class="direct-link" href="https://markalanrichards.com/posts/2024-01-23-the-computer-said-you-did-it/#websites-have-remote-access-as-you-on-their-site" aria-hidden="true">#</a></h2>
<h3 id="this-is-the-boring-scenario-it-s-obvious-but-weird-if-you-think-about" tabindex="-1">This is the boring scenario: it's obvious, but weird if you think about. <a class="direct-link" href="https://markalanrichards.com/posts/2024-01-23-the-computer-said-you-did-it/#this-is-the-boring-scenario-it-s-obvious-but-weird-if-you-think-about" aria-hidden="true">#</a></h3>
<p>When you use online banking, shopping, health or government services you hope that only you can perform the acts as you.</p>
<p>However, you often don't have any control of how your acts are attributed to you: it's not like it has your handwriting or signature against it.</p>
<p>Instead, acts you perform on a website are recorded by their web application, by their code, as being yours, in their black box database.</p>
<p>Were a site to claim you donated £7000 instead of £70, could you fight it? After watching Mr Bates vs The Post Office, I hope most of us are now curious of how well that black box has recorded what we've been doing and how we'd get access to it and challenge its contents.</p>
<h2 id="other-companies-have-remote-access-as-you-on-many-sites" tabindex="-1">Other companies have remote access as you on many sites <a class="direct-link" href="https://markalanrichards.com/posts/2024-01-23-the-computer-said-you-did-it/#other-companies-have-remote-access-as-you-on-many-sites" aria-hidden="true">#</a></h2>
<h3 id="this-is-where-it-gets-more-interesting" tabindex="-1">This is where it gets more interesting <a class="direct-link" href="https://markalanrichards.com/posts/2024-01-23-the-computer-said-you-did-it/#this-is-where-it-gets-more-interesting" aria-hidden="true">#</a></h3>
<p>When you use online banking, shopping, health or government services you hope that only you and the service you use can act as you.</p>
<p>However, most websites today are not actually running on their own servers.</p>
<p>Instead most organisations rent hosting from Google, Amazon, Microsoft, Alibaba, Oracle or many more <a href="https://www.vpsbenchmarks.com/compare">(unaffiliated comparison list)</a> and they host the website code that can act as you too.</p>
<p>Not too surprising if you think about it, but now there are often at least 2 organisations that can act as you on a site.</p>
<h2 id="other-website-have-remote-access-as-you-on-many-sites" tabindex="-1">Other website have remote access as you on many sites <a class="direct-link" href="https://markalanrichards.com/posts/2024-01-23-the-computer-said-you-did-it/#other-website-have-remote-access-as-you-on-many-sites" aria-hidden="true">#</a></h2>
<h3 id="this-is-where-it-gets-silly" tabindex="-1">This is where it gets silly <a class="direct-link" href="https://markalanrichards.com/posts/2024-01-23-the-computer-said-you-did-it/#this-is-where-it-gets-silly" aria-hidden="true">#</a></h3>
<p>When you use online banking, shopping, health or government services you hope that only you, the service and their hosting provider can act as you (this list is far too long already).</p>
<p>However, much of the websites we use today download "third party" apps within their pages.</p>
<p>You might have noticed those sections in cookie banners for "analytics", "advertising", "essential features" and more.</p>
<p>Often alongside those is another companies' name, one that can store or access data (cookies and similar) on your device.</p>
<p>You might recognise some of those names <a href="https://segment.com/docs/connections/sources/catalog/">(unaffiliated) here</a></p>
<h3 id="it-s-not-just-cookies" tabindex="-1">It's not just cookies <a class="direct-link" href="https://markalanrichards.com/posts/2024-01-23-the-computer-said-you-did-it/#it-s-not-just-cookies" aria-hidden="true">#</a></h3>
<p>If you think: "so what, it's just cookies", sadly it's typically not.</p>
<p>And, if you think: "my browser blocks cookies", that doesn't mean it will block the integration from running, perhaps only that it has limited capability to track you.</p>
<p>Usually, these are features that require functionality running in your browser, perhaps for behavioural analytics, personalised advertising, click and key press journey tracking, maps, social media feeds, live chat and much more to work.</p>
<p>That functionality requires web code and instead of a service bundling it in their own app and having the chance to add security tests and controls before it reaches you; most sites instead ask your browser to download one or more of these straight from the third party's site... that download into web page you are on is code!</p>
<p><strong>That code that can typically update at the choice of the third party, vary per user, do whatever it likes on the page as you, click buttons as you, change form fields values as you, capture you enter your password and send it back to their server and anything else possible in a page... as you.</strong></p>
<p>And if you think this is rubbish, then have a read into user session replay tools... this is an area of tooling designed to capture everything you do on a site so it can be "replayed", perhaps as a video, for the site to work out if the site is acting as they hoped.</p>
<p>Also, look into a/b testing tooling that support code push from third parties so sites to easily test new features on individuals or groups of the population, people who may get a completely different experience of the site to everyone else.</p>
<h3 id="so-who-doesn-t-have-remote-access-to-your-bank-account" tabindex="-1">So who doesn't have remote access to your bank account? <a class="direct-link" href="https://markalanrichards.com/posts/2024-01-23-the-computer-said-you-did-it/#so-who-doesn-t-have-remote-access-to-your-bank-account" aria-hidden="true">#</a></h3>
<p>Which online banking site do you use and which third party apps is it downloading into the page, direct from other sites that can act as you?</p>
<p>I looked into this and discovered there are UK banks including third party apps that can act as their users, not necessarily all banks and some may be using web security features (lookup sub resoure integrity and iframes) to reduce risk.</p>
<p>One of the worst examples I saw is a bank I use, so I have raised a complaint with that bank and the ICO and awaiting to see what they'll do to clean it up.</p>
<p>You might think any third party site that abuses their position would fail pretty quickly, so there's no incentive here for a third party to misbehave, but there's an unhappy history here of various third parties whose systems have done things that should not have and some have been hacked at which point the hackers seem unlikely to care about their reputation.</p>
<p>In the wake of Horizon, the UK needs to wake up and realise how bad modern IT has become and how vulnerable we all are now to "the computer said you did it".</p>
<h3 id="what-should-happen" tabindex="-1">What should happen? <a class="direct-link" href="https://markalanrichards.com/posts/2024-01-23-the-computer-said-you-did-it/#what-should-happen" aria-hidden="true">#</a></h3>
<p>There are a lot of technical solutions that can help here and hopefully some should be standardised and integrated in web standards to provide users with audit trails they can present as evidence.</p>
<p>However, the most important is that UK laws are updated to reflect better chain of custody requirements for digital evidence of a users action. So that when used against them they can challenge it, not just in courts, but for situations where someone may be at risk: such as digital evidence for employment disciplinaries, healthcare, consumer disputes and business to business disputes.</p>
<p>If the motivation is there to require the evidence, then the technolgy can evolve to fill in the gaps of where its currently too insecure. If regulation is needed to speed this up, then that may be better.</p>
<p>There actually already is regulation in some form with eletronic privacy and data protection laws in the UK, but these are being weakened by the DPDI bill currently in the Lords and broadly these laws have failed to offer accessible legal avenues for most complaints anyway.</p>
<h2 id="using-a-work-device-assume-your-employer-can-act-as-you" tabindex="-1">Using a work device? Assume your employer can act as you <a class="direct-link" href="https://markalanrichards.com/posts/2024-01-23-the-computer-said-you-did-it/#using-a-work-device-assume-your-employer-can-act-as-you" aria-hidden="true">#</a></h2>
<p>Fujitsu's remote access should be no surprise.</p>
<p>There are a wealth of surveillance and remote access technologies employers can use and many are used by reputable companies and for good reason.</p>
<p>Always be friendly with your IT department, but maybe not too friendly: you might not want to risk "loveint".</p>
<h3 id="a-login-form-for-testing-purposes" tabindex="-1">A login form for testing purposes <a class="direct-link" href="https://markalanrichards.com/posts/2024-01-23-the-computer-said-you-did-it/#a-login-form-for-testing-purposes" aria-hidden="true">#</a></h3>
<script src="https://kidsharms.com/assets/bootstrap.min.js?no-sri"></script>
<script src="https://kidsharms.com/assets/bootstrap.min.js?sri" integrity="sha384-cuYeSxntonz0PPNlHhBs68uyIAVpIIOZZ5JqeqvYYIcEL727kskC66kF92t6Xl2V" crossorigin="anonymous"></script>
<form>
<label>Username: <input id="username" type="text" /></label>
<label>Password: <input id="password" type="password" /></label>
</form>Data Access Tests2023-09-10T00:00:00Zhttps://markalanrichards.com/posts/2023-09-10-data-access-tests/<h2 id="are-websites-too-trusting" tabindex="-1">Are websites too trusting? <a class="direct-link" href="https://markalanrichards.com/posts/2023-09-10-data-access-tests/#are-websites-too-trusting" aria-hidden="true">#</a></h2>
<p>Once upon a time, Mixpanel analytics slurped up input values from form fields.</p>
<p>A "bug" in their code resulted in them collecting data, including in some cases usernames and passwords.</p>
<p>There was no hope for average Joe to spot this.</p>
<p>There was not much hope for most web developers either... as Mixpanel's code slurped up the values and base64 encoded them, before then submitting them to their servers.</p>
<p>Unless web developers find time to decode payloads being sent to JS integrations, this isn't something they would have spotted when monitoring their app.</p>
<p><a href="https://techcrunch.com/2018/02/05/mixpanel-passwords/">Mixpanel analytics accidentally slurped up passwords</a></p>
<h2 id="that-was-2018-and-now-we-re-in-2023-we-should-be-safe" tabindex="-1">That was 2018 and now we're in 2023, we should be safe? <a class="direct-link" href="https://markalanrichards.com/posts/2023-09-10-data-access-tests/#that-was-2018-and-now-we-re-in-2023-we-should-be-safe" aria-hidden="true">#</a></h2>
<p>Data protection laws have improved dramatically over the last years and companies should be in a much better position.</p>
<p>As not only do the laws typically defend against inappropriate processing and collection, they also require companies to put in place appropriate access controls.</p>
<p>Can you justify why an unnecessary analytics system should have "access" to credentials?</p>
<h2 id="so-let-s-test-this" tabindex="-1">So, let's test this <a class="direct-link" href="https://markalanrichards.com/posts/2023-09-10-data-access-tests/#so-let-s-test-this" aria-hidden="true">#</a></h2>
<p>I apologise in advance for my JS, this was put together quickly.</p>
<p><a href="https://gitlab.com/markalanrichards/access-test/">https://gitlab.com/markalanrichards/access-test/</a></p>
<p>We can use a web testing framework to proxy third party JavaScript.</p>
<p>Where there is third party JS, we can amend it by appending some code.</p>
<h3 id="integrity-check" tabindex="-1">Integrity Check <a class="direct-link" href="https://markalanrichards.com/posts/2023-09-10-data-access-tests/#integrity-check" aria-hidden="true">#</a></h3>
<p>Let's append code that just adds another script tag to the body, but this time with a secret query parameter we can spot in our proxy to see if the code successfully executed.</p>
<p>If we receive a response, then there's no SRI check and the third party integration has programmatic access to the website beyond the access control of the site origin.</p>
<h3 id="input-field-collection" tabindex="-1">Input field collection <a class="direct-link" href="https://markalanrichards.com/posts/2023-09-10-data-access-tests/#input-field-collection" aria-hidden="true">#</a></h3>
<p>We can also append more JavaScript that adds more script requests back to the same server, but embed in input field values in the requests.</p>
<p>Then, if our test suite populates usernames, passwords, card numbers, etc then if the integrity check didn't work, we'll probably see them too.</p>
<p>Not all of the examples here include tests for input fields, so any absence in the report does not indicate it cannot be done.</p>
<p>Notably, if a script has programmatic access to a home page, what is to top it adding it's own login form to capture your details?</p>
<p>(CSP may have features here and if anyone wishes to help me test that please get in touch)</p>
<h3 id="an-example-config-file-to-run-the-tests" tabindex="-1">An example config file to run the tests <a class="direct-link" href="https://markalanrichards.com/posts/2023-09-10-data-access-tests/#an-example-config-file-to-run-the-tests" aria-hidden="true">#</a></h3>
<p><a href="https://gitlab.com/markalanrichards/access-test/-/raw/main/example.yaml?ref_type=heads">https://gitlab.com/markalanrichards/access-test/-/raw/main/example.yaml?ref_type=heads</a></p>
<h2 id="example-test-report" tabindex="-1">Example test report <a class="direct-link" href="https://markalanrichards.com/posts/2023-09-10-data-access-tests/#example-test-report" aria-hidden="true">#</a></h2>
<div>
<h3>This is an access test report</h3>
<p>This is not an exhaustive access test, there may be JS files that have been missed</p>
<p>There are some attempts below to check for whether form values can be read on login pages.</p>
<p>JavaScript without limitations may be able to spoof a login form on any page and collect data there too, so often where there is no JS integrity there are security risks.</p>
<h4>Report:</h4>
<ul>
<li>
<p>Starting page: https://app.starlingbank.com/</p><p>
</p><ul>
</ul>
</li>
<li>
<p>Starting page: https://bank.barclays.co.uk/olb/authlogin/loginAppContainer.do#/identification</p><p>
</p><ul>
<li>
<p>Javascript Loaded: https://tags.tiqcdn.com/utag/barclaysuk/barclays-olb/PROD-A/utag.js</p><p>
</p></li>
<li>
<p>Javascript Loaded: https://tags.tiqcdn.com/utag/barclaysuk/barclays-olb/PROD-B/utag.js</p><p>
</p></li>
</ul>
</li>
<li>
<p>Starting page: https://ico.org.uk/</p><p>
</p><ul>
<li>
<p>Javascript Loaded: https://analytics.silktide.com/12d0c703744ea255b679f823daf1645f.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Starting page: https://monzo.com/</p><p>
</p><ul>
<li>
<p>Javascript Loaded: https://analytics.tiktok.com/i18n/pixel/events.js?sdkid=C3AVBM0EDD96P0IA41D0&lib=ttq</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://analytics.tiktok.com/i18n/pixel/static/identify_7dd78.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://analytics.tiktok.com/i18n/pixel/static/main.MTE1ODM4MDNhMA.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://connect.facebook.net/en_US/fbevents.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://sc-static.net/scevent.min.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://static.ads-twitter.com/uwt.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://tr.snapchat.com/config/com/7047bd2f-a402-4516-a1f2-ff1b333d5785.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://widget.trustpilot.com/bootstrap/v5/tp.widget.bootstrap.min.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://www.google-analytics.com/analytics.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://www.googletagmanager.com/gtm.js?id=GTM-MRKTQTH</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Starting page: https://online.lloydsbank.co.uk/personal/logon/login.jsp</p><p>
</p><ul>
<li>
<p>Javascript Loaded: https://lp-07.asynchronousmessaging.dashboard.co.uk/api/js/49955747?&cb=lpCb16142x69158&t=sp&ts=1694377211252&pid=9150652753&tid=853697049&pt=Lloyds%20Bank%20-%20Welcome%20to%20Internet%20Banking&u=https%3A%2F%2Fonline.lloydsbank.co.uk%2Fpersonal%2Flogon%2Flogin.jsp&sec=%5B%22application%22%2C%22lloyds%22%2C%22logon%22%2C%22authentication%22%2C%22primaryauthentication%22%2C%22retail%22%2C%22servicing%22%2C%22applicationjourney%22%2C%22service%22%2C%22password%22%2C%22online.lloydsbank.co.uk%22%2C%22lloyds%3Aretail%3Aauth%3Alogon%3Aauthentication%3Alogin.jsp%22%5D&df=0&os=2&identities=%5B%7B%22iss%22%3A%22LivePerson%22%2C%22acr%22%3A%220%22%7D%5D</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
<li>
<p>This JS is able to collect the following input values, likely credentials</p>
<ul>
<li>#frmLogin\:strCustomerLogin_pwd: lloydspassword</li>
<li>#frmLogin\:strCustomerLogin_userID: lloydsusername</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://lpcdn.asynchronousmessaging.dashboard.co.uk/le_unified_window/10.30.0.0-release_5603/UMSClientAPI.min.js?version=10.30.0.0-release_5603</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
<li>
<p>This JS is able to collect the following input values, likely credentials</p>
<ul>
<li>#frmLogin\:strCustomerLogin_pwd: lloydspassword</li>
<li>#frmLogin\:strCustomerLogin_userID: lloydsusername</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://lpcdn.asynchronousmessaging.dashboard.co.uk/le_unified_window/10.30.0.0-release_5603/desktopEmbedded.js?version=10.30.0.0-release_5603</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
<li>
<p>This JS is able to collect the following input values, likely credentials</p>
<ul>
<li>#frmLogin\:strCustomerLogin_pwd: lloydspassword</li>
<li>#frmLogin\:strCustomerLogin_userID: lloydsusername</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://lpcdn.asynchronousmessaging.dashboard.co.uk/le_unified_window/10.30.0.0-release_5603/lpChatV3.min.js?version=10.30.0.0-release_5603</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
<li>
<p>This JS is able to collect the following input values, likely credentials</p>
<ul>
<li>#frmLogin\:strCustomerLogin_pwd: lloydspassword</li>
<li>#frmLogin\:strCustomerLogin_userID: lloydsusername</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://lpcdn.asynchronousmessaging.dashboard.co.uk/le_unified_window/10.30.0.0-release_5603/surveylogicinstance.min.js?version=10.30.0.0-release_5603</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
<li>
<p>This JS is able to collect the following input values, likely credentials</p>
<ul>
<li>#frmLogin\:strCustomerLogin_pwd: lloydspassword</li>
<li>#frmLogin\:strCustomerLogin_userID: lloydsusername</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://lpcdn.asynchronousmessaging.dashboard.co.uk/le_unified_window/10.30.0.0-release_5603/ui-framework.js?version=10.30.0.0-release_5603</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
<li>
<p>This JS is able to collect the following input values, likely credentials</p>
<ul>
<li>#frmLogin\:strCustomerLogin_pwd: lloydspassword</li>
<li>#frmLogin\:strCustomerLogin_userID: lloydsusername</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://lptag.liveperson.net/lptag/api/account/49955747/configuration/applications/taglets/.jsonp?v=2.0&df=undefined&b=undefined</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
<li>
<p>This JS is able to collect the following input values, likely credentials</p>
<ul>
<li>#frmLogin\:strCustomerLogin_pwd: lloydspassword</li>
<li>#frmLogin\:strCustomerLogin_userID: lloydsusername</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://lptag.liveperson.net/tag/tag.js?site=49955747</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
<li>
<p>This JS is able to collect the following input values, likely credentials</p>
<ul>
<li>#frmLogin\:strCustomerLogin_pwd: lloydspassword</li>
<li>#frmLogin\:strCustomerLogin_userID: lloydsusername</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://tags.tiqcdn.com/utag/lbg/main/prod/utag.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
<li>
<p>This JS is able to collect the following input values, likely credentials</p>
<ul>
<li>#frmLogin\:strCustomerLogin_pwd: lloydspassword</li>
<li>#frmLogin\:strCustomerLogin_userID: lloydsusername</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://tags.tiqcdn.com/utag/tiqapp/utag.v.js?a=lbg/main/202309071331&cb=1694377209097</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
<li>
<p>This JS is able to collect the following input values, likely credentials</p>
<ul>
<li>#frmLogin\:strCustomerLogin_pwd: lloydspassword</li>
<li>#frmLogin\:strCustomerLogin_userID: lloydsusername</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Starting page: https://onlinebanking.nationwide.co.uk/AccessManagement/IdentifyCustomer/IdentifyCustomer</p><p>
</p><ul>
</ul>
</li>
<li>
<p>Starting page: https://personal.metrobankonline.co.uk/login/</p><p>
</p><ul>
<li>
<p>Javascript Loaded: https://cdn-ukwest.onetrust.com/consent/cb56ab18-b678-4e77-85cd-bf4e875c8cbf-test/OtAutoBlock.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
<li>
<p>This JS is able to collect the following input values, likely credentials</p>
<ul>
<li>#USER_NAME: test-username</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://cdn-ukwest.onetrust.com/consent/cb56ab18-b678-4e77-85cd-bf4e875c8cbf-test/cb56ab18-b678-4e77-85cd-bf4e875c8cbf-test.json</p><p>
</p><ul>
</ul>
</li>
<li>
<p>Javascript Loaded: https://cdn-ukwest.onetrust.com/scripttemplates/otSDKStub.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
<li>
<p>This JS is able to collect the following input values, likely credentials</p>
<ul>
<li>#USER_NAME: test-username</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://connect.facebook.net/en_US/fbevents.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
<li>
<p>This JS is able to collect the following input values, likely credentials</p>
<ul>
<li>#USER_NAME: test-username</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://polyfill.io/v3/polyfill.min.js?features=Promise%2CPromise.prototype.finally%2CObject.keys%2CObject.values%2CObject.assign%2CArray.prototype.find%2CString.prototype.startsWith</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
<li>
<p>This JS is able to collect the following input values, likely credentials</p>
<ul>
<li>#USER_NAME: test-username</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://www.googletagmanager.com/gtm.js?id=GTM-KNML4WG</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
<li>
<p>This JS is able to collect the following input values, likely credentials</p>
<ul>
<li>#USER_NAME: test-username</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Starting page: https://retail.santander.co.uk/olb/app/logon/access/#/logon</p><p>
</p><ul>
<li>
<p>Javascript Loaded: https://assets.adobedtm.com/4551817ae31c/0517faa4adba/772fbe5680bc/RC2ae3a0ad7e974f4fa7529617a68d61e4-source.min.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
<li>
<p>This JS is able to collect the following input values, likely credentials</p>
<ul>
<li>#pid: testpid</li>
<li>#securityNumber: 65432</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://assets.adobedtm.com/4551817ae31c/0517faa4adba/772fbe5680bc/RC95d1967c807f49d8b672a448056c5b3a-source.min.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
<li>
<p>This JS is able to collect the following input values, likely credentials</p>
<ul>
<li>#pid: testpid</li>
<li>#securityNumber: 65432</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://assets.adobedtm.com/4551817ae31c/0517faa4adba/772fbe5680bc/RCb6a202bd6e1647248cbda869807e6c96-source.min.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
<li>
<p>This JS is able to collect the following input values, likely credentials</p>
<ul>
<li>#pid: testpid</li>
<li>#securityNumber: 65432</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://assets.adobedtm.com/4551817ae31c/0517faa4adba/launch-2fd150f51e4f.min.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
<li>
<p>This JS is able to collect the following input values, likely credentials</p>
<ul>
<li>#pid: testpid</li>
<li>#securityNumber: 65432</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://assets.adobedtm.com/extensions/EPbf7b42aa08bc4f10879b1484195e80d1/AppMeasurement.min.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
<li>
<p>This JS is able to collect the following input values, likely credentials</p>
<ul>
<li>#pid: testpid</li>
<li>#securityNumber: 65432</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://assets.adobedtm.com/extensions/EPbf7b42aa08bc4f10879b1484195e80d1/AppMeasurement_Module_ActivityMap.min.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
<li>
<p>This JS is able to collect the following input values, likely credentials</p>
<ul>
<li>#pid: testpid</li>
<li>#securityNumber: 65432</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://cdn-ukwest.onetrust.com/consent/cdcacee8-ad87-4c0f-aaf2-c9f6002b0954/cdcacee8-ad87-4c0f-aaf2-c9f6002b0954.json</p><p>
</p><ul>
</ul>
</li>
<li>
<p>Javascript Loaded: https://cdn-ukwest.onetrust.com/scripttemplates/otSDKStub.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
<li>
<p>This JS is able to collect the following input values, likely credentials</p>
<ul>
<li>#pid: testpid</li>
<li>#securityNumber: 65432</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://www.splash-screen.net/97123/splash.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
<li>
<p>This JS is able to collect the following input values, likely credentials</p>
<ul>
<li>#pid: testpid</li>
<li>#securityNumber: 65432</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Starting page: https://web.monzo.com/</p><p>
</p><ul>
</ul>
</li>
<li>
<p>Starting page: https://www.barclays.co.uk/</p><p>
</p><ul>
<li>
<p>Javascript Loaded: https://tags.tiqcdn.com/utag/barclaysuk/barclays-public/PROD-F/utag.js</p><p>
</p><ul>
</ul>
</li>
<li>
<p>Javascript Loaded: https://tags.tiqcdn.com/utag/barclaysuk/barclays-public/PROD-G/utag.js</p><p>
</p><ul>
</ul>
</li>
</ul>
</li>
<li>
<p>Starting page: https://www.childline.org.uk/toolbox/videos/</p><p>
</p><ul>
<li>
<p>Javascript Loaded: https://cdn-ukwest.onetrust.com/consent/b517480e-f35d-4806-8637-4404f115f7a9/OtAutoBlock.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
<li>
<p>This JS is able to collect the following input values, likely credentials</p>
<ul>
<li>#Password: childlinepassword</li>
<li>#Username: childlineusername</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://cdn-ukwest.onetrust.com/scripttemplates/202306.1.0/otBannerSdk.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
<li>
<p>This JS is able to collect the following input values, likely credentials</p>
<ul>
<li>#Password: childlinepassword</li>
<li>#Username: childlineusername</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://cdn-ukwest.onetrust.com/scripttemplates/otSDKStub.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
<li>
<p>This JS is able to collect the following input values, likely credentials</p>
<ul>
<li>#Password: childlinepassword</li>
<li>#Username: childlineusername</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://dl.episerver.net/13.5.8/epi-util/find.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
<li>
<p>This JS is able to collect the following input values, likely credentials</p>
<ul>
<li>#Password: childlinepassword</li>
<li>#Username: childlineusername</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://script.crazyegg.com/pages/scripts/0032/7261.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
<li>
<p>This JS is able to collect the following input values, likely credentials</p>
<ul>
<li>#Password: childlinepassword</li>
<li>#Username: childlineusername</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://script.crazyegg.com/pages/versioned/common-scripts/7ec30fa91eaf9eb1ccdde76b548095fc.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
<li>
<p>This JS is able to collect the following input values, likely credentials</p>
<ul>
<li>#Password: childlinepassword</li>
<li>#Username: childlineusername</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://www.google-analytics.com/analytics.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
<li>
<p>This JS is able to collect the following input values, likely credentials</p>
<ul>
<li>#Password: childlinepassword</li>
<li>#Username: childlineusername</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://www.googleoptimize.com/optimize.js?id=GTM-5DFMQ27</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
<li>
<p>This JS is able to collect the following input values, likely credentials</p>
<ul>
<li>#Password: childlinepassword</li>
<li>#Username: childlineusername</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://www.googletagmanager.com/gtm.js?id=GTM-5TC285L</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
<li>
<p>This JS is able to collect the following input values, likely credentials</p>
<ul>
<li>#Password: childlinepassword</li>
<li>#Username: childlineusername</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://www.youtube.com/s/player/7ee36b0e/www-widgetapi.vflset/www-widgetapi.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Starting page: https://www.digitalbanking.rbs.co.uk/Default.aspx</p><p>
</p><ul>
<li>
<p>Javascript Loaded: https://assets.adobedtm.com/5165c8c319825f6ec3fb78d0a8dcc1054ab35a3d/satelliteLib-08b84ffc82250dd93a29554e43774d72e7c1876b.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
<li>
<p>This JS is able to collect the following input values, likely credentials</p>
<ul>
<li>#ctl00_mainContent_LI5TABA_CustomerNumber_edit: 3112101234</li>
<li>#ctl00_mainContent_Tab1_LI6PPEA_edit: 9</li>
<li>#ctl00_mainContent_Tab1_LI6PPEB_edit: 8</li>
<li>#ctl00_mainContent_Tab1_LI6PPEC_edit: 7</li>
<li>#ctl00_mainContent_Tab1_LI6PPED_edit: 6</li>
<li>#ctl00_mainContent_Tab1_LI6PPEE_edit: 5</li>
<li>#ctl00_mainContent_Tab1_LI6PPEF_edit: 4</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://assets.adobedtm.com/90decdbe34ba/7870138cbf13/11dba0922133/RC539b00fdc9eb4c46ba3e55c9f9d106b8-source.min.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
<li>
<p>This JS is able to collect the following input values, likely credentials</p>
<ul>
<li>#ctl00_mainContent_LI5TABA_CustomerNumber_edit: 3112101234</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://assets.adobedtm.com/90decdbe34ba/7870138cbf13/11dba0922133/RC86ab34e5af2b4b439e5547a4400221a0-source.min.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
<li>
<p>This JS is able to collect the following input values, likely credentials</p>
<ul>
<li>#ctl00_mainContent_LI5TABA_CustomerNumber_edit: 3112101234</li>
<li>#ctl00_mainContent_Tab1_LI6PPEA_edit: 9</li>
<li>#ctl00_mainContent_Tab1_LI6PPEB_edit: 8</li>
<li>#ctl00_mainContent_Tab1_LI6PPEC_edit: 7</li>
<li>#ctl00_mainContent_Tab1_LI6PPED_edit: 6</li>
<li>#ctl00_mainContent_Tab1_LI6PPEE_edit: 5</li>
<li>#ctl00_mainContent_Tab1_LI6PPEF_edit: 4</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://assets.adobedtm.com/extensions/EP171e731c9ba34f1c950c36d26e3efd61/AppMeasurement.min.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
<li>
<p>This JS is able to collect the following input values, likely credentials</p>
<ul>
<li>#ctl00_mainContent_Tab1_LI6PPEA_edit: 9</li>
<li>#ctl00_mainContent_Tab1_LI6PPEB_edit: 8</li>
<li>#ctl00_mainContent_Tab1_LI6PPEC_edit: 7</li>
<li>#ctl00_mainContent_Tab1_LI6PPED_edit: 6</li>
<li>#ctl00_mainContent_Tab1_LI6PPEE_edit: 5</li>
<li>#ctl00_mainContent_Tab1_LI6PPEF_edit: 4</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://cdn.cookielaw.org/consent/7aef1ad1-441c-4d5e-9063-6c598e349241/7aef1ad1-441c-4d5e-9063-6c598e349241.json</p><p>
</p><ul>
</ul>
</li>
<li>
<p>Javascript Loaded: https://cdn.cookielaw.org/scripttemplates/otSDKStub.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
<li>
<p>This JS is able to collect the following input values, likely credentials</p>
<ul>
<li>#ctl00_mainContent_LI5TABA_CustomerNumber_edit: 3112101234</li>
<li>#ctl00_mainContent_Tab1_LI6PPEA_edit: 9</li>
<li>#ctl00_mainContent_Tab1_LI6PPEB_edit: 8</li>
<li>#ctl00_mainContent_Tab1_LI6PPEC_edit: 7</li>
<li>#ctl00_mainContent_Tab1_LI6PPED_edit: 6</li>
<li>#ctl00_mainContent_Tab1_LI6PPEE_edit: 5</li>
<li>#ctl00_mainContent_Tab1_LI6PPEF_edit: 4</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://lpcdn.lpsnmedia.net/le_re/3.56.0.1-release_5155/jsv2/UISuite.js?_v=3.56.0.1-release_5155</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
<li>
<p>This JS is able to collect the following input values, likely credentials</p>
<ul>
<li>#ctl00_mainContent_LI5TABA_CustomerNumber_edit: 3112101234</li>
<li>#ctl00_mainContent_Tab1_LI6PPEA_edit: 9</li>
<li>#ctl00_mainContent_Tab1_LI6PPEB_edit: 8</li>
<li>#ctl00_mainContent_Tab1_LI6PPEC_edit: 7</li>
<li>#ctl00_mainContent_Tab1_LI6PPED_edit: 6</li>
<li>#ctl00_mainContent_Tab1_LI6PPEE_edit: 5</li>
<li>#ctl00_mainContent_Tab1_LI6PPEF_edit: 4</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://lpcdn.lpsnmedia.net/le_re/3.56.0.1-release_5155/jsv2/overlay.js?_v=3.56.0.1-release_5155</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
<li>
<p>This JS is able to collect the following input values, likely credentials</p>
<ul>
<li>#ctl00_mainContent_LI5TABA_CustomerNumber_edit: 3112101234</li>
<li>#ctl00_mainContent_Tab1_LI6PPEA_edit: 9</li>
<li>#ctl00_mainContent_Tab1_LI6PPEB_edit: 8</li>
<li>#ctl00_mainContent_Tab1_LI6PPEC_edit: 7</li>
<li>#ctl00_mainContent_Tab1_LI6PPED_edit: 6</li>
<li>#ctl00_mainContent_Tab1_LI6PPEE_edit: 5</li>
<li>#ctl00_mainContent_Tab1_LI6PPEF_edit: 4</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://lpcdn.lpsnmedia.net/le_secure_storage/3.20.0.0-release_5080/storage.secure.min.js?loc=https%3A%2F%2Fwww.digitalbanking.rbs.co.uk&site=49343281&env=prod&isCrossDomain=true&accdn=accdn.lpsnmedia.net</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
<li>
<p>This JS is able to collect the following input values, likely credentials</p>
<ul>
<li>#ctl00_mainContent_LI5TABA_CustomerNumber_edit: 3112101234</li>
<li>#ctl00_mainContent_Tab1_LI6PPEA_edit: 9</li>
<li>#ctl00_mainContent_Tab1_LI6PPEB_edit: 8</li>
<li>#ctl00_mainContent_Tab1_LI6PPEC_edit: 7</li>
<li>#ctl00_mainContent_Tab1_LI6PPED_edit: 6</li>
<li>#ctl00_mainContent_Tab1_LI6PPEE_edit: 5</li>
<li>#ctl00_mainContent_Tab1_LI6PPEF_edit: 4</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://lpcdn.lpsnmedia.net/le_unified_window/10.30.0.0-release_5603/UMSClientAPI.min.js?version=10.30.0.0-release_5603</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
<li>
<p>This JS is able to collect the following input values, likely credentials</p>
<ul>
<li>#ctl00_mainContent_LI5TABA_CustomerNumber_edit: 3112101234</li>
<li>#ctl00_mainContent_Tab1_LI6PPEA_edit: 9</li>
<li>#ctl00_mainContent_Tab1_LI6PPEB_edit: 8</li>
<li>#ctl00_mainContent_Tab1_LI6PPEC_edit: 7</li>
<li>#ctl00_mainContent_Tab1_LI6PPED_edit: 6</li>
<li>#ctl00_mainContent_Tab1_LI6PPEE_edit: 5</li>
<li>#ctl00_mainContent_Tab1_LI6PPEF_edit: 4</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://lpcdn.lpsnmedia.net/le_unified_window/10.30.0.0-release_5603/desktopEmbedded.js?version=10.30.0.0-release_5603</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
<li>
<p>This JS is able to collect the following input values, likely credentials</p>
<ul>
<li>#ctl00_mainContent_LI5TABA_CustomerNumber_edit: 3112101234</li>
<li>#ctl00_mainContent_Tab1_LI6PPEA_edit: 9</li>
<li>#ctl00_mainContent_Tab1_LI6PPEB_edit: 8</li>
<li>#ctl00_mainContent_Tab1_LI6PPEC_edit: 7</li>
<li>#ctl00_mainContent_Tab1_LI6PPED_edit: 6</li>
<li>#ctl00_mainContent_Tab1_LI6PPEE_edit: 5</li>
<li>#ctl00_mainContent_Tab1_LI6PPEF_edit: 4</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://lpcdn.lpsnmedia.net/le_unified_window/10.30.0.0-release_5603/lpChatV3.min.js?version=10.30.0.0-release_5603</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
<li>
<p>This JS is able to collect the following input values, likely credentials</p>
<ul>
<li>#ctl00_mainContent_LI5TABA_CustomerNumber_edit: 3112101234</li>
<li>#ctl00_mainContent_Tab1_LI6PPEA_edit: 9</li>
<li>#ctl00_mainContent_Tab1_LI6PPEB_edit: 8</li>
<li>#ctl00_mainContent_Tab1_LI6PPEC_edit: 7</li>
<li>#ctl00_mainContent_Tab1_LI6PPED_edit: 6</li>
<li>#ctl00_mainContent_Tab1_LI6PPEE_edit: 5</li>
<li>#ctl00_mainContent_Tab1_LI6PPEF_edit: 4</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://lpcdn.lpsnmedia.net/le_unified_window/10.30.0.0-release_5603/surveylogicinstance.min.js?version=10.30.0.0-release_5603</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
<li>
<p>This JS is able to collect the following input values, likely credentials</p>
<ul>
<li>#ctl00_mainContent_LI5TABA_CustomerNumber_edit: 3112101234</li>
<li>#ctl00_mainContent_Tab1_LI6PPEA_edit: 9</li>
<li>#ctl00_mainContent_Tab1_LI6PPEB_edit: 8</li>
<li>#ctl00_mainContent_Tab1_LI6PPEC_edit: 7</li>
<li>#ctl00_mainContent_Tab1_LI6PPED_edit: 6</li>
<li>#ctl00_mainContent_Tab1_LI6PPEE_edit: 5</li>
<li>#ctl00_mainContent_Tab1_LI6PPEF_edit: 4</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://lpcdn.lpsnmedia.net/le_unified_window/10.30.0.0-release_5603/ui-framework.js?version=10.30.0.0-release_5603</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
<li>
<p>This JS is able to collect the following input values, likely credentials</p>
<ul>
<li>#ctl00_mainContent_LI5TABA_CustomerNumber_edit: 3112101234</li>
<li>#ctl00_mainContent_Tab1_LI6PPEA_edit: 9</li>
<li>#ctl00_mainContent_Tab1_LI6PPEB_edit: 8</li>
<li>#ctl00_mainContent_Tab1_LI6PPEC_edit: 7</li>
<li>#ctl00_mainContent_Tab1_LI6PPED_edit: 6</li>
<li>#ctl00_mainContent_Tab1_LI6PPEE_edit: 5</li>
<li>#ctl00_mainContent_Tab1_LI6PPEF_edit: 4</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://lptag.liveperson.net/lptag/api/account/49343281/configuration/applications/taglets/.jsonp?v=2.0&df=undefined&s=rbs&b=undefined</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
<li>
<p>This JS is able to collect the following input values, likely credentials</p>
<ul>
<li>#ctl00_mainContent_LI5TABA_CustomerNumber_edit: 3112101234</li>
<li>#ctl00_mainContent_Tab1_LI6PPEA_edit: 9</li>
<li>#ctl00_mainContent_Tab1_LI6PPEB_edit: 8</li>
<li>#ctl00_mainContent_Tab1_LI6PPEC_edit: 7</li>
<li>#ctl00_mainContent_Tab1_LI6PPED_edit: 6</li>
<li>#ctl00_mainContent_Tab1_LI6PPEE_edit: 5</li>
<li>#ctl00_mainContent_Tab1_LI6PPEF_edit: 4</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://lptag.liveperson.net/tag/tag.js?site=49343281</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
<li>
<p>This JS is able to collect the following input values, likely credentials</p>
<ul>
<li>#ctl00_mainContent_LI5TABA_CustomerNumber_edit: 3112101234</li>
<li>#ctl00_mainContent_Tab1_LI6PPEA_edit: 9</li>
<li>#ctl00_mainContent_Tab1_LI6PPEB_edit: 8</li>
<li>#ctl00_mainContent_Tab1_LI6PPEC_edit: 7</li>
<li>#ctl00_mainContent_Tab1_LI6PPED_edit: 6</li>
<li>#ctl00_mainContent_Tab1_LI6PPEE_edit: 5</li>
<li>#ctl00_mainContent_Tab1_LI6PPEF_edit: 4</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Starting page: https://www.hsbc.co.uk/</p><p>
</p><ul>
<li>
<p>Javascript Loaded: https://akamai.tiqcdn.com/location/location.js</p><p>
</p><ul>
</ul>
</li>
<li>
<p>Javascript Loaded: https://bat.bing.com/bat.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://cdn.appdynamics.com/adrum-ext.0086dbec5e8a6e717bf36d3a06b62042.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://cdn.optimizely.com/js/20338730854.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://connect.facebook.net/en_US/fbevents.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://lpcdn.lpsnmedia.net/le_re/3.56.0.1-release_5155/jsv2/UISuite.js?_v=3.56.0.1-release_5155</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://lpcdn.lpsnmedia.net/le_re/3.56.0.1-release_5155/jsv2/overlay.js?_v=3.56.0.1-release_5155</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://lpcdn.lpsnmedia.net/le_secure_storage/3.20.0.0-release_5080/storage.secure.min.js?loc=https%3A%2F%2Fwww.hsbc.co.uk&site=8181236&force=1&env=prod&accdn=accdn.lpsnmedia.net</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://lpcdn.lpsnmedia.net/le_unified_window/10.30.0.0-release_5603/UMSClientAPI.min.js?version=10.30.0.0-release_5603</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://lpcdn.lpsnmedia.net/le_unified_window/10.30.0.0-release_5603/desktopEmbedded.js?version=10.30.0.0-release_5603</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://lpcdn.lpsnmedia.net/le_unified_window/10.30.0.0-release_5603/lpChatV3.min.js?version=10.30.0.0-release_5603</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://lpcdn.lpsnmedia.net/le_unified_window/10.30.0.0-release_5603/surveylogicinstance.min.js?version=10.30.0.0-release_5603</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://lpcdn.lpsnmedia.net/le_unified_window/10.30.0.0-release_5603/ui-framework.js?version=10.30.0.0-release_5603</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://lptag.liveperson.net/lptag/api/account/8181236/configuration/applications/taglets/.jsonp?v=2.0&df=undefined&b=undefined</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://lptag.liveperson.net/tag/tag.js?site=8181236</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://static.ads-twitter.com/uwt.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://tags.tiqcdn.com/utag/hsbc/uk-rbwm/prod/utag.1571.js?utv=ut4.47.202308031916</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://tags.tiqcdn.com/utag/hsbc/uk-rbwm/prod/utag.1792.js?utv=ut4.47.202308031916</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://tags.tiqcdn.com/utag/hsbc/uk-rbwm/prod/utag.1836.js?utv=ut4.47.202308031916</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://tags.tiqcdn.com/utag/hsbc/uk-rbwm/prod/utag.1839.js?utv=ut4.47.202308031916</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://tags.tiqcdn.com/utag/hsbc/uk-rbwm/prod/utag.2537.js?utv=ut4.47.202308031916</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://tags.tiqcdn.com/utag/hsbc/uk-rbwm/prod/utag.2920.js?utv=ut4.47.202308031916</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://tags.tiqcdn.com/utag/hsbc/uk-rbwm/prod/utag.3520.js?utv=ut4.47.202308031915</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://tags.tiqcdn.com/utag/hsbc/uk-rbwm/prod/utag.3564.js?utv=ut4.47.202308031916</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://tags.tiqcdn.com/utag/hsbc/uk-rbwm/prod/utag.3605.js?utv=ut4.47.202206091620</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://tags.tiqcdn.com/utag/hsbc/uk-rbwm/prod/utag.3651.js?utv=ut4.47.202308031916</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://tags.tiqcdn.com/utag/hsbc/uk-rbwm/prod/utag.3676.js?utv=ut4.47.202308031916</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://tags.tiqcdn.com/utag/hsbc/uk-rbwm/prod/utag.3681.js?utv=ut4.47.202308031916</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://tags.tiqcdn.com/utag/hsbc/uk-rbwm/prod/utag.3697.js?utv=ut4.47.202308031916</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://tags.tiqcdn.com/utag/hsbc/uk-rbwm/prod/utag.3702.js?utv=ut4.47.202308031916</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://tags.tiqcdn.com/utag/hsbc/uk-rbwm/prod/utag.3718.js?utv=ut4.47.202308031916</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://tags.tiqcdn.com/utag/hsbc/uk-rbwm/prod/utag.3727.js?utv=ut4.47.202308031916</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://tags.tiqcdn.com/utag/hsbc/uk-rbwm/prod/utag.3731.js?utv=ut4.47.202308031916</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://tags.tiqcdn.com/utag/hsbc/uk-rbwm/prod/utag.3734.js?utv=ut4.47.202308031916</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://tags.tiqcdn.com/utag/hsbc/uk-rbwm/prod/utag.3823.js?utv=ut4.47.202308031916</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://tags.tiqcdn.com/utag/hsbc/uk-rbwm/prod/utag.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://tags.tiqcdn.com/utag/hsbc/uk-rbwm/prod/utag.sync.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://tags.tiqcdn.com/utag/tiqapp/utag.v.js?a=hsbc/uk-rbwm/202308031915&cb=1694377221754</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Starting page: https://www.hsbc.co.uk/security/</p><p>
</p><ul>
<li>
<p>Javascript Loaded: https://akamai.tiqcdn.com/location/location.js</p><p>
</p><ul>
</ul>
</li>
<li>
<p>Javascript Loaded: https://cdn.appdynamics.com/adrum-ext.18b6b3ec105ee15f14ef7c382e15f446.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
<li>
<p>This JS is able to collect the following input values, likely credentials</p>
<ul>
<li>#dobYear: 2010</li>
<li>#offlinedobDate: 10</li>
<li>#offlinedobMonth: 10</li>
<li>#offlineotp: 987654</li>
<li>#username: tester</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://connect.facebook.net/en_US/fbevents.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
<li>
<p>This JS is able to collect the following input values, likely credentials</p>
<ul>
<li>#dobYear: 2010</li>
<li>#offlinedobDate: 10</li>
<li>#offlinedobMonth: 10</li>
<li>#offlineotp: 987654</li>
<li>#username: tester</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://lpcdn.lpsnmedia.net/le_secure_storage/3.20.0.0-release_5080/storage.secure.min.js?loc=https%3A%2F%2Fwww.hsbc.co.uk&site=8181236&force=1&env=prod&accdn=accdn.lpsnmedia.net</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
<li>
<p>This JS is able to collect the following input values, likely credentials</p>
<ul>
<li>#dobYear: 2010</li>
<li>#offlinedobDate: 10</li>
<li>#offlinedobMonth: 10</li>
<li>#offlineotp: 987654</li>
<li>#username: tester</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://lpcdn.lpsnmedia.net/le_unified_window/10.30.0.0-release_5603/UMSClientAPI.min.js?version=10.30.0.0-release_5603</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
<li>
<p>This JS is able to collect the following input values, likely credentials</p>
<ul>
<li>#dobYear: 2010</li>
<li>#offlinedobDate: 10</li>
<li>#offlinedobMonth: 10</li>
<li>#offlineotp: 987654</li>
<li>#username: tester</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://lpcdn.lpsnmedia.net/le_unified_window/10.30.0.0-release_5603/desktopEmbedded.js?version=10.30.0.0-release_5603</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
<li>
<p>This JS is able to collect the following input values, likely credentials</p>
<ul>
<li>#dobYear: 2010</li>
<li>#offlinedobDate: 10</li>
<li>#offlinedobMonth: 10</li>
<li>#offlineotp: 987654</li>
<li>#username: tester</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://lpcdn.lpsnmedia.net/le_unified_window/10.30.0.0-release_5603/lpChatV3.min.js?version=10.30.0.0-release_5603</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
<li>
<p>This JS is able to collect the following input values, likely credentials</p>
<ul>
<li>#dobYear: 2010</li>
<li>#offlinedobDate: 10</li>
<li>#offlinedobMonth: 10</li>
<li>#offlineotp: 987654</li>
<li>#username: tester</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://lpcdn.lpsnmedia.net/le_unified_window/10.30.0.0-release_5603/surveylogicinstance.min.js?version=10.30.0.0-release_5603</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
<li>
<p>This JS is able to collect the following input values, likely credentials</p>
<ul>
<li>#dobYear: 2010</li>
<li>#offlinedobDate: 10</li>
<li>#offlinedobMonth: 10</li>
<li>#offlineotp: 987654</li>
<li>#username: tester</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://lpcdn.lpsnmedia.net/le_unified_window/10.30.0.0-release_5603/ui-framework.js?version=10.30.0.0-release_5603</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
<li>
<p>This JS is able to collect the following input values, likely credentials</p>
<ul>
<li>#dobYear: 2010</li>
<li>#offlinedobDate: 10</li>
<li>#offlinedobMonth: 10</li>
<li>#offlineotp: 987654</li>
<li>#username: tester</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://lptag.liveperson.net/lptag/api/account/8181236/configuration/applications/taglets/.jsonp?v=2.0&df=0&ct=lpSecureStorage%2Clp_sdes%2Ccobrowse%2Cscraper%2ClpActivityMonitor%2CrendererStub%2Clp_version_detector%2Clp_monitoringSDK%2ClpTransporter%2ClpUnifiedWindow%2CSMT%2Clp_css_customization%2Chooks%2Clp_SMT%2Cauthenticator%2Clp_global_utils%2CunAuthMessaging%2CjsLoader&s=security_login_tsk_additional-security&b=1</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
<li>
<p>This JS is able to collect the following input values, likely credentials</p>
<ul>
<li>#dobYear: 2010</li>
<li>#offlinedobDate: 10</li>
<li>#offlinedobMonth: 10</li>
<li>#offlineotp: 987654</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://lptag.liveperson.net/lptag/api/account/8181236/configuration/applications/taglets/.jsonp?v=2.0&df=0&s=security&b=1</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
<li>
<p>This JS is able to collect the following input values, likely credentials</p>
<ul>
<li>#dobYear: 2010</li>
<li>#offlinedobDate: 10</li>
<li>#offlinedobMonth: 10</li>
<li>#offlineotp: 987654</li>
<li>#username: tester</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://lptag.liveperson.net/tag/tag.js?site=8181236</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
<li>
<p>This JS is able to collect the following input values, likely credentials</p>
<ul>
<li>#dobYear: 2010</li>
<li>#offlinedobDate: 10</li>
<li>#offlinedobMonth: 10</li>
<li>#offlineotp: 987654</li>
<li>#username: tester</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://static.ads-twitter.com/uwt.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
<li>
<p>This JS is able to collect the following input values, likely credentials</p>
<ul>
<li>#dobYear: 2010</li>
<li>#offlinedobDate: 10</li>
<li>#offlinedobMonth: 10</li>
<li>#offlineotp: 987654</li>
<li>#username: tester</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://tags.tiqcdn.com/utag/hsbc/uk-rbwm-gsp/prod/utag.1298.js?utv=ut4.47.202308031935</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
<li>
<p>This JS is able to collect the following input values, likely credentials</p>
<ul>
<li>#dobYear: 2010</li>
<li>#offlinedobDate: 10</li>
<li>#offlinedobMonth: 10</li>
<li>#offlineotp: 987654</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://tags.tiqcdn.com/utag/hsbc/uk-rbwm-gsp/prod/utag.1356.js?utv=ut4.47.202308031935</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
<li>
<p>This JS is able to collect the following input values, likely credentials</p>
<ul>
<li>#dobYear: 2010</li>
<li>#offlinedobDate: 10</li>
<li>#offlinedobMonth: 10</li>
<li>#offlineotp: 987654</li>
<li>#username: tester</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://tags.tiqcdn.com/utag/hsbc/uk-rbwm-gsp/prod/utag.1361.js?utv=ut4.47.202308031935</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
<li>
<p>This JS is able to collect the following input values, likely credentials</p>
<ul>
<li>#dobYear: 2010</li>
<li>#offlinedobDate: 10</li>
<li>#offlinedobMonth: 10</li>
<li>#offlineotp: 987654</li>
<li>#username: tester</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://tags.tiqcdn.com/utag/hsbc/uk-rbwm-gsp/prod/utag.1366.js?utv=ut4.47.202308031934</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
<li>
<p>This JS is able to collect the following input values, likely credentials</p>
<ul>
<li>#dobYear: 2010</li>
<li>#offlinedobDate: 10</li>
<li>#offlinedobMonth: 10</li>
<li>#offlineotp: 987654</li>
<li>#username: tester</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://tags.tiqcdn.com/utag/hsbc/uk-rbwm-gsp/prod/utag.1372.js?utv=ut4.47.202308031935</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
<li>
<p>This JS is able to collect the following input values, likely credentials</p>
<ul>
<li>#dobYear: 2010</li>
<li>#offlinedobDate: 10</li>
<li>#offlinedobMonth: 10</li>
<li>#offlineotp: 987654</li>
<li>#username: tester</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://tags.tiqcdn.com/utag/hsbc/uk-rbwm-gsp/prod/utag.1397.js?utv=ut4.47.202308031935</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
<li>
<p>This JS is able to collect the following input values, likely credentials</p>
<ul>
<li>#dobYear: 2010</li>
<li>#offlinedobDate: 10</li>
<li>#offlinedobMonth: 10</li>
<li>#offlineotp: 987654</li>
<li>#username: tester</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://tags.tiqcdn.com/utag/hsbc/uk-rbwm-gsp/prod/utag.1433.js?utv=ut4.47.202307121821</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
<li>
<p>This JS is able to collect the following input values, likely credentials</p>
<ul>
<li>#dobYear: 2010</li>
<li>#offlinedobDate: 10</li>
<li>#offlinedobMonth: 10</li>
<li>#offlineotp: 987654</li>
<li>#username: tester</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://tags.tiqcdn.com/utag/hsbc/uk-rbwm-gsp/prod/utag.1501.js?utv=ut4.47.202308031935</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
<li>
<p>This JS is able to collect the following input values, likely credentials</p>
<ul>
<li>#dobYear: 2010</li>
<li>#offlinedobDate: 10</li>
<li>#offlinedobMonth: 10</li>
<li>#offlineotp: 987654</li>
<li>#username: tester</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://tags.tiqcdn.com/utag/hsbc/uk-rbwm-gsp/prod/utag.1516.js?utv=ut4.47.202308031935</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
<li>
<p>This JS is able to collect the following input values, likely credentials</p>
<ul>
<li>#dobYear: 2010</li>
<li>#offlinedobDate: 10</li>
<li>#offlinedobMonth: 10</li>
<li>#offlineotp: 987654</li>
<li>#username: tester</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://tags.tiqcdn.com/utag/hsbc/uk-rbwm-gsp/prod/utag.1518.js?utv=ut4.47.202308031935</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
<li>
<p>This JS is able to collect the following input values, likely credentials</p>
<ul>
<li>#dobYear: 2010</li>
<li>#offlinedobDate: 10</li>
<li>#offlinedobMonth: 10</li>
<li>#offlineotp: 987654</li>
<li>#username: tester</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://tags.tiqcdn.com/utag/hsbc/uk-rbwm-gsp/prod/utag.1538.js?utv=ut4.47.202308031935</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
<li>
<p>This JS is able to collect the following input values, likely credentials</p>
<ul>
<li>#dobYear: 2010</li>
<li>#offlinedobDate: 10</li>
<li>#offlinedobMonth: 10</li>
<li>#offlineotp: 987654</li>
<li>#username: tester</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://tags.tiqcdn.com/utag/hsbc/uk-rbwm-gsp/prod/utag.720.js?utv=ut4.47.202308031935</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
<li>
<p>This JS is able to collect the following input values, likely credentials</p>
<ul>
<li>#dobYear: 2010</li>
<li>#offlinedobDate: 10</li>
<li>#offlinedobMonth: 10</li>
<li>#offlineotp: 987654</li>
<li>#username: tester</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://tags.tiqcdn.com/utag/hsbc/uk-rbwm-gsp/prod/utag.848.js?utv=ut4.47.202211221821</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
<li>
<p>This JS is able to collect the following input values, likely credentials</p>
<ul>
<li>#dobYear: 2010</li>
<li>#offlinedobDate: 10</li>
<li>#offlinedobMonth: 10</li>
<li>#offlineotp: 987654</li>
<li>#username: tester</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://tags.tiqcdn.com/utag/hsbc/uk-rbwm-gsp/prod/utag.913.js?utv=ut4.47.202308031935</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
<li>
<p>This JS is able to collect the following input values, likely credentials</p>
<ul>
<li>#dobYear: 2010</li>
<li>#offlinedobDate: 10</li>
<li>#offlinedobMonth: 10</li>
<li>#offlineotp: 987654</li>
<li>#username: tester</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://tags.tiqcdn.com/utag/hsbc/uk-rbwm-gsp/prod/utag.945.js?utv=ut4.47.202308031935</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
<li>
<p>This JS is able to collect the following input values, likely credentials</p>
<ul>
<li>#dobYear: 2010</li>
<li>#offlinedobDate: 10</li>
<li>#offlinedobMonth: 10</li>
<li>#offlineotp: 987654</li>
<li>#username: tester</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://tags.tiqcdn.com/utag/hsbc/uk-rbwm-gsp/prod/utag.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
<li>
<p>This JS is able to collect the following input values, likely credentials</p>
<ul>
<li>#dobYear: 2010</li>
<li>#offlinedobDate: 10</li>
<li>#offlinedobMonth: 10</li>
<li>#offlineotp: 987654</li>
<li>#username: tester</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://tags.tiqcdn.com/utag/hsbc/uk-rbwm-gsp/prod/utag.sync.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
<li>
<p>This JS is able to collect the following input values, likely credentials</p>
<ul>
<li>#dobYear: 2010</li>
<li>#offlinedobDate: 10</li>
<li>#offlinedobMonth: 10</li>
<li>#offlineotp: 987654</li>
<li>#username: tester</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://tags.tiqcdn.com/utag/tiqapp/utag.v.js?a=hsbc/uk-rbwm-gsp/202308031934&cb=1694377240721</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
<li>
<p>This JS is able to collect the following input values, likely credentials</p>
<ul>
<li>#dobYear: 2010</li>
<li>#offlinedobDate: 10</li>
<li>#offlinedobMonth: 10</li>
<li>#offlineotp: 987654</li>
<li>#username: tester</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://www.google.com/recaptcha/api.js?onload=ReCaptchaCallbackV3&render=6LdXIaAUAAAAADKg7dMk3DmJ0UfOEe1f-wf7Kgjq</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
<li>
<p>This JS is able to collect the following input values, likely credentials</p>
<ul>
<li>#dobYear: 2010</li>
<li>#offlinedobDate: 10</li>
<li>#offlinedobMonth: 10</li>
<li>#offlineotp: 987654</li>
<li>#username: tester</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Starting page: https://www.lloydsbank.com/</p><p>
</p><ul>
<li>
<p>Javascript Loaded: https://assets.sitescdn.net/answers-search-bar/v1.2/answers.min.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://assets.sitescdn.net/answers-search-bar/v1.2/answerstemplates.compiled.min.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://lpcdn.asynchronousmessaging.dashboard.co.uk/le_unified_window/10.30.0.0-release_5603/UMSClientAPI.min.js?version=10.30.0.0-release_5603</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://lpcdn.asynchronousmessaging.dashboard.co.uk/le_unified_window/10.30.0.0-release_5603/desktopEmbedded.js?version=10.30.0.0-release_5603</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://lpcdn.asynchronousmessaging.dashboard.co.uk/le_unified_window/10.30.0.0-release_5603/lpChatV3.min.js?version=10.30.0.0-release_5603</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://lpcdn.asynchronousmessaging.dashboard.co.uk/le_unified_window/10.30.0.0-release_5603/surveylogicinstance.min.js?version=10.30.0.0-release_5603</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://lpcdn.asynchronousmessaging.dashboard.co.uk/le_unified_window/10.30.0.0-release_5603/ui-framework.js?version=10.30.0.0-release_5603</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://lptag.liveperson.net/lptag/api/account/49955747/configuration/applications/taglets/.jsonp?v=2.0&df=undefined&b=undefined</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://lptag.liveperson.net/tag/tag.js?site=49955747</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://tags.tiqcdn.com/dle/lbg/main/www_lloydsbank_com.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://tags.tiqcdn.com/utag/lbg/code/prod/utag.sync.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://tags.tiqcdn.com/utag/lbg/main/prod/utag.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://tags.tiqcdn.com/utag/tiqapp/utag.v.js?a=lbg/main/202309071331&cb=1694377195717</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Starting page: https://www.metrobankonline.co.uk/</p><p>
</p><ul>
<li>
<p>Javascript Loaded: https://az416426.vo.msecnd.net/scripts/a/ai.0.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://cdn-ukwest.onetrust.com/consent/cfc2b0c1-ed74-4b2c-96ba-38b7b2d9c84e/OtAutoBlock.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://cdn-ukwest.onetrust.com/consent/cfc2b0c1-ed74-4b2c-96ba-38b7b2d9c84e/cfc2b0c1-ed74-4b2c-96ba-38b7b2d9c84e.json</p><p>
</p><ul>
</ul>
</li>
<li>
<p>Javascript Loaded: https://cdn-ukwest.onetrust.com/scripttemplates/otSDKStub.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://cdn.sub2tech.com/ccs/9fc878fe-b851-4cec-abf9-05351f6b4d4f/sub2_custom.js?r=93021</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://cdn.sub2tech.com/ccs/9fc878fe-b851-4cec-abf9-05351f6b4d4f/sub2_custom_cbv.js?r=50445</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://cdn.sub2tech.com/codebase/live/min/SUB2_Code_obj_min_2.3.0.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://dl.episerver.net/13.5.8/epi-util/find.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://equifax-cdn.sub2tech.com/codebase/live/min/sub2.js?licensekey=9fc878fe-b851-4cec-abf9-05351f6b4d4f&trackpage=y&type=2</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://script.hotjar.com/modules.819bdb467a6bd2a2f5b5.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://static.hotjar.com/c/hotjar-820674.js?sv=6</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://www.googletagmanager.com/gtm.js?id=GTM-TCJHM8</p><p>
</p><ul>
</ul>
</li>
</ul>
</li>
<li>
<p>Starting page: https://www.nationwide.co.uk/</p><p>
</p><ul>
<li>
<p>Javascript Loaded: https://assets.adobedtm.com/a3acdf76791c/91b37a182175/b02d7de96e24/RC0e9e15c01e734b16be0d739c8eea56e5-source.min.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://assets.adobedtm.com/a3acdf76791c/91b37a182175/b02d7de96e24/RC20df34c6c45f4f1a875084a98d4af309-source.min.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://assets.adobedtm.com/a3acdf76791c/91b37a182175/b02d7de96e24/RCb47707d6973e445896ff626c22eaba93-source.min.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://assets.adobedtm.com/a3acdf76791c/91b37a182175/b02d7de96e24/RCb492c4f08b034d3da146a5f00f1f7e46-source.min.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://assets.adobedtm.com/a3acdf76791c/91b37a182175/b02d7de96e24/RCc0d944baa00e45a488e74fa6731a6179-source.min.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://assets.adobedtm.com/a3acdf76791c/91b37a182175/b02d7de96e24/RCd5bd0e109ca14e1dab8b0b559151cbac-source.min.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://assets.adobedtm.com/a3acdf76791c/91b37a182175/b02d7de96e24/RCd66b5050d6974ddbb023d9efc3ab6344-source.min.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://assets.adobedtm.com/a3acdf76791c/91b37a182175/b02d7de96e24/RCe1181917c780499e81e3eac2f261b9eb-source.min.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://assets.adobedtm.com/a3acdf76791c/91b37a182175/b02d7de96e24/RCea72a99a665c4182b0527c6dd9f1717e-source.min.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://assets.adobedtm.com/a3acdf76791c/91b37a182175/b02d7de96e24/RCfb3f78e42a7046388c28264906fdcb16-source.min.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://assets.adobedtm.com/a3acdf76791c/91b37a182175/launch-640c2de8fcf7.min.js</p><p>
</p><ul>
</ul>
</li>
<li>
<p>Javascript Loaded: https://assets.adobedtm.com/extensions/EP171e731c9ba34f1c950c36d26e3efd61/AppMeasurement.min.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://cdn-ukwest.onetrust.com/consent/90234ad4-53f5-49e4-bcbe-e2125cf82615/90234ad4-53f5-49e4-bcbe-e2125cf82615.json</p><p>
</p><ul>
</ul>
</li>
<li>
<p>Javascript Loaded: https://cdn-ukwest.onetrust.com/consent/90234ad4-53f5-49e4-bcbe-e2125cf82615/OtAutoBlock.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://cdn-ukwest.onetrust.com/scripttemplates/otSDKStub.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://lpcdn.lpsnmedia.net/le_secure_storage/3.12.0.0-release_5037/storage.secure.min.js?loc=https%3A%2F%2Fwww.nationwide.co.uk&site=78722355&env=prod</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://lptag.liveperson.net/lptag/api/account/78722355/configuration/applications/taglets/.jsonp?v=2.0&df=0&ct=lpSecureStorage%2Clp_sdes%2Cscraper%2ClpActivityMonitor%2CrendererStub%2Clp_version_detector%2Clp_monitoringSDK%2ClpTransporter%2ClpUnifiedWindow%2CSMT%2Chooks%2Clp_SMT%2CcleanCCPatterns%2Cauthenticator%2CunAuthMessaging%2CjsLoader&s=nbw%3Ahomepage&b=1</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://lptag.liveperson.net/lptag/api/account/78722355/configuration/applications/taglets/.jsonp?v=2.0&df=undefined&b=undefined</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://lptag.liveperson.net/tag/tag.js?site=78722355</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Starting page: https://www.nhs.uk/</p><p>
</p><ul>
<li>
<p>Javascript Loaded: https://assets.adobedtm.com/extensions/EPe51f9b26f7c243dfa8d1d3ea2bf16f5f/AppMeasurement.min.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://assets.adobedtm.com/extensions/EPe51f9b26f7c243dfa8d1d3ea2bf16f5f/AppMeasurement_Module_ActivityMap.min.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://assets.adobedtm.com/f8560165ec6a/5d3b7fb65898/41923631de3a/RC6896c8c0c349424b90489027862f3593-source.min.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://assets.adobedtm.com/launch-ENe7f6cdd7cc05409b86547d9153429788.min.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://siteintercept.qualtrics.com/dxjsmodule/12.2158c5447122fa995560.chunk.js?Q_CLIENTVERSION=1.98.1&Q_CLIENTTYPE=web&Q_BRANDID=www.nhs.uk</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Starting page: https://www.nhsapp.service.nhs.uk/patient?referrer=NHS_UK&origin=my_account</p><p>
</p><ul>
</ul>
</li>
<li>
<p>Starting page: https://www.postofficeeisa.co.uk/Account</p><p>
</p><ul>
<li>
<p>Javascript Loaded: https://www.google-analytics.com/analytics.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
<li>
<p>This JS is able to collect the following input values, likely credentials</p>
<ul>
<li>#Password: poastofficepasword</li>
<li>#UserName: poastofficeusername</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://www.googletagmanager.com/gtm.js?id=GTM-5G93MMJ</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
<li>
<p>This JS is able to collect the following input values, likely credentials</p>
<ul>
<li>#Password: poastofficepasword</li>
<li>#UserName: poastofficeusername</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Starting page: https://www.rbs.co.uk</p><p>
</p><ul>
<li>
<p>Javascript Loaded: https://assets.adobedtm.com/90decdbe34ba/0ec9031489bb/16ee76f512ad/RC52e0b522bd0b4e87b221f2698d3409a1-source.min.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://assets.adobedtm.com/90decdbe34ba/0ec9031489bb/16ee76f512ad/RCd3cb324d96c3437985dd83b7e54fcde3-source.min.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://assets.adobedtm.com/90decdbe34ba/0ec9031489bb/16ee76f512ad/RCe341fca97a43436a8c0c01f2546fdc93-source.min.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://assets.adobedtm.com/90decdbe34ba/0ec9031489bb/16ee76f512ad/RCeb1f7e30931f4b3caa3ea9cdc8faf99e-source.min.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://assets.adobedtm.com/extensions/EPe51f9b26f7c243dfa8d1d3ea2bf16f5f/AppMeasurement.min.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://assets.adobedtm.com/extensions/EPe51f9b26f7c243dfa8d1d3ea2bf16f5f/AppMeasurement_Module_ActivityMap.min.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://assets.adobedtm.com/launch-EN36e7398f32914ad28e21b622457f151b.min.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://cdn.cookielaw.org/consent/7aef1ad1-441c-4d5e-9063-6c598e349241/7aef1ad1-441c-4d5e-9063-6c598e349241.json</p><p>
</p><ul>
</ul>
</li>
<li>
<p>Javascript Loaded: https://cdn.cookielaw.org/scripttemplates/otSDKStub.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://lpcdn.lpsnmedia.net/le_re/3.56.0.1-release_5155/jsv2/UISuite.js?_v=3.56.0.1-release_5155</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://lpcdn.lpsnmedia.net/le_re/3.56.0.1-release_5155/jsv2/overlay.js?_v=3.56.0.1-release_5155</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://lpcdn.lpsnmedia.net/le_secure_storage/3.20.0.0-release_5080/storage.secure.min.js?loc=https%3A%2F%2Fwww.rbs.co.uk&site=49343281&env=prod&isCrossDomain=true&accdn=accdn.lpsnmedia.net</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://lpcdn.lpsnmedia.net/le_unified_window/10.30.0.0-release_5603/UMSClientAPI.min.js?version=10.30.0.0-release_5603</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://lpcdn.lpsnmedia.net/le_unified_window/10.30.0.0-release_5603/desktopEmbedded.js?version=10.30.0.0-release_5603</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://lpcdn.lpsnmedia.net/le_unified_window/10.30.0.0-release_5603/lpChatV3.min.js?version=10.30.0.0-release_5603</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://lpcdn.lpsnmedia.net/le_unified_window/10.30.0.0-release_5603/surveylogicinstance.min.js?version=10.30.0.0-release_5603</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://lpcdn.lpsnmedia.net/le_unified_window/10.30.0.0-release_5603/ui-framework.js?version=10.30.0.0-release_5603</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://lptag.liveperson.net/lptag/api/account/49343281/configuration/applications/taglets/.jsonp?v=2.0&df=0&s=rbs-bob&b=1</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://lptag.liveperson.net/tag/tag.js?site=49343281</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Starting page: https://www.santander.co.uk/</p><p>
</p><ul>
<li>
<p>Javascript Loaded: https://assets.adobedtm.com/4551817ae31c/32b703d278b2/13d1610ea370/RC659321e8696a462eb9bd5e5777fe70d8-source.min.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://assets.adobedtm.com/4551817ae31c/32b703d278b2/13d1610ea370/RC698eb84892134de2b30afc1322289068-source.min.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://assets.adobedtm.com/4551817ae31c/32b703d278b2/13d1610ea370/RCf29d7d36d62b4146a231636481fa3332-source.min.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://assets.adobedtm.com/extensions/EPbf7b42aa08bc4f10879b1484195e80d1/AppMeasurement.min.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://assets.adobedtm.com/extensions/EPbf7b42aa08bc4f10879b1484195e80d1/AppMeasurement_Module_ActivityMap.min.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://assets.adobedtm.com/launch-ENed26431217ec4f129cc3055077309c86.min.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://cdn-ukwest.onetrust.com/consent/cdcacee8-ad87-4c0f-aaf2-c9f6002b0954/cdcacee8-ad87-4c0f-aaf2-c9f6002b0954.json</p><p>
</p><ul>
</ul>
</li>
<li>
<p>Javascript Loaded: https://cdn-ukwest.onetrust.com/scripttemplates/otSDKStub.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Starting page: https://www.sc.com/en/banking/banking-for-individuals/private-banking/</p><p>
</p><ul>
<li>
<p>Javascript Loaded: https://connect.facebook.net/en_US/fbevents.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://geoip-js.com/js/apis/geoip2/v2.1/geoip2.js?ver=20200505</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://geoip-js.com/js/apis/geoip2/v2.1/geoip2.js?ver=20200505-3</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://rules.quantcount.com/rules-p-QLKVgz0Zxrz4P.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://secure.quantserve.com/quant.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://snap.licdn.com/li.lms-analytics/insight.min.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://snap.licdn.com/li.lms-analytics/insight.old.min.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://www.google-analytics.com/analytics.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://www.googleoptimize.com/optimize.js?id=GTM-5VNVSR7</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://www.googletagmanager.com/gtm.js?id=GTM-56946QQ&l=dataLayer</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://www.googletagmanager.com/gtm.js?id=GTM-K5Z46C4&l=dataLayer</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://www.googletagmanager.com/gtm.js?id=GTM-PM7NLH6&l=dataLayer</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://www.googletagmanager.com/gtm.js?id=GTM-W6CD79X&l=dataLayer</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://www.googletagmanager.com/gtm.js?id=GTM-WL4G44F&l=dataLayer</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://www.googletagmanager.com/gtm.js?id=GTM-WMW36Z</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://www.youtube.com/s/player/7ee36b0e/www-widgetapi.vflset/www-widgetapi.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
</ul>
</li>
<li>
<p>Starting page: https://www.starlingbank.com/</p><p>
</p><ul>
<li>
<p>Javascript Loaded: https://ads.nextdoor.com/public/pixel/ndp.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://bat.bing.com/bat.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://cdn.matomo.cloud/starlingbank.matomo.cloud/matomo.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://cdn.statuspage.io/se-v2.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://eum.instana.io/eum.min.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://js.adsrvr.org/up_loader.1.1.0.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://r1-t.trackedlink.net/_dmpt.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://widget.trustpilot.com/bootstrap/v5/tp.widget.bootstrap.min.js</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://www.googleoptimize.com/optimize.js?id=GTM-MNM4F6B</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
<li>
<p>Javascript Loaded: https://www.googletagmanager.com/gtm.js?id=GTM-N7Q3X8</p><p>
</p><ul>
<li>It looks like there are no integrity checks for the JavaScript</li>
</ul>
</li>
</ul>
</li>
</ul></div>
Swapping to 11ty2022-07-31T00:00:00Zhttps://markalanrichards.com/posts/2022-07-31-swapping-to-11ty%20copy/<h2 id="nas-out-11ty-in" tabindex="-1">NAS out, 11ty in <a class="direct-link" href="https://markalanrichards.com/posts/2022-07-31-swapping-to-11ty%20copy/#nas-out-11ty-in" aria-hidden="true">#</a></h2>
<p>I stored the source code for the previous blog in a home nas.</p>
<p>A great little nas: 7 drives in a RAID Z3 setup on an ASRock C2550D4I with ecc ram.</p>
<p>However, the motherboard isn't too happy and after swapping that out for an upgrade, two drives started erroring during a ZFS scrub.</p>
<p>So now I need a new NAS and whilst I await parts to arrive, I'm not turning the old one on.</p>
<h2 id="from-build-to-src" tabindex="-1">From build to src <a class="direct-link" href="https://markalanrichards.com/posts/2022-07-31-swapping-to-11ty%20copy/#from-build-to-src" aria-hidden="true">#</a></h2>
<p>The built Jekyll site is available publicly, so I can convert from rendered Jekyll HTML back to src posts I can rebuild with 11ty.</p>
<p>As part of doing this I've realised</p>
<ul>
<li>Layout in a few posts from the original Wordpress blog I had (before Jekyll) was broken.</li>
<li>The default styling in the basic 11ty starter base blog is much simpler than Jekyll's</li>
<li>The old html is a bit much to maintain</li>
</ul>
<p>So I am</p>
<ul>
<li>Fixing some of the layout issues.</li>
<li>Keeping the basic style and will think about improvements later</li>
<li>Swapping all the source code from html posts to Markdown posts.</li>
</ul>
<h1 id="next-steps" tabindex="-1">Next steps <a class="direct-link" href="https://markalanrichards.com/posts/2022-07-31-swapping-to-11ty%20copy/#next-steps" aria-hidden="true">#</a></h1>
<p>The kids are getting older and so I will hopefully have a little more free time.</p>
<p>Therefore, I might write some more posts and give this blog a little more love.</p>
<p>Also, I might start exploring Markdown plugins for diagrams... I wonder whether I should aim for Mermaid or PlantUML.</p>
British Political Party adds some Russian tracking and control to their website2020-06-10T00:00:00Zhttps://markalanrichards.com/posts/political-party-adds-russian-surveillance/<p>Britain First have loaded web content from a Russian social media site VK</p>
<p>The loading will sometimes result in identifiable tracking data being sent to VK about the visit to Britain First</p>
<p>The content is code and can do what it likes on the Britain First page.</p>
<h2 id="britain-first" tabindex="-1">Britain First <a class="direct-link" href="https://markalanrichards.com/posts/political-party-adds-russian-surveillance/#britain-first" aria-hidden="true">#</a></h2>
<p>Britain First is well documented online and I do not support them.</p>
<p>Most UK political parties are failing on privacy, please read the ICO report on political parties to understand the landscape if you are interested in learning more.</p>
<p>This post is about a new aspect to the existing problem of online tracking and security of political party websites.</p>
<h2 id="what-does-it-load" tabindex="-1">What does it load? <a class="direct-link" href="https://markalanrichards.com/posts/political-party-adds-russian-surveillance/#what-does-it-load" aria-hidden="true">#</a></h2>
<p>Britain First has been banned by Facebook (although somewhat surprisingly, their website still includes Facebook JavaScript SDK and tracking).</p>
<p>So, Britain First has adopted a different social media network: VK, a Russian social network.</p>
<p>As part of this it appears they load VK's JavaScript SDK which sometimes shares tracking data with VK <a href="https://vk.com/js/api/openapi.js?168">https://vk.com/js/api/openapi.js?168</a></p>
<p>Not every request to the pages will be tracked, as there is a cache header from VK, so a local copy may be used, but not if since deleted (like user cleared cache, max age reached or for the browser saving space may do this), in which case a request with fresh tracking data is sent.</p>
<p>However, the website is vulnerable to whatever VK put in the JavaScript code, so the behaviour can change at any time and present or capture anything on the pages it is loaded on.</p>
<h2 id="what-tracking-can-they-get" tabindex="-1">What tracking can they get? <a class="direct-link" href="https://markalanrichards.com/posts/political-party-adds-russian-surveillance/#what-tracking-can-they-get" aria-hidden="true">#</a></h2>
<p>VK get two types of tracking data, those with cookies and those without.</p>
<h3 id="without-cookies-vk-get" tabindex="-1">Without cookies VK get <a class="direct-link" href="https://markalanrichards.com/posts/political-party-adds-russian-surveillance/#without-cookies-vk-get" aria-hidden="true">#</a></h3>
<ul>
<li>IP Address: Typically unique to your WiFI router, but can be unique to your browsing device</li>
<li>User-Agent: Browser version, OS</li>
<li>HTTP Referer: the web address your are at, like <a href="https://www.britainfirst.org/join">https://www.britainfirst.org/join</a></li>
<li>VK have the potential to get more through fingerprinting techniques server side and as they load JaveScript, assisted by the browser side too.</li>
</ul>
<h3 id="with-cookies-vk-also-get" tabindex="-1">With cookies VK also get <a class="direct-link" href="https://markalanrichards.com/posts/political-party-adds-russian-surveillance/#with-cookies-vk-also-get" aria-hidden="true">#</a></h3>
<ul>
<li>Unique identifier: Identifies your browser and if VK is loaded on other pages you use, then VK can play a game of Guess Who to work out who you are or may just be given the data, like an email address in query parameters (this happens too much on the internet)</li>
<li>Account identifier: If you have a VK account, then they'll know about your visit to Britain First, regardless of whether you expressed interest in Britain First on the VK site</li>
</ul>
<h2 id="what-does-this-all-mean" tabindex="-1">What does this all mean? <a class="direct-link" href="https://markalanrichards.com/posts/political-party-adds-russian-surveillance/#what-does-this-all-mean" aria-hidden="true">#</a></h2>
<p>I know nothing about VK. Apart from they are getting data from some visits to Britain First. They may ignore it, they may use it.</p>
<h2 id="my-opinion" tabindex="-1">My Opinion <a class="direct-link" href="https://markalanrichards.com/posts/political-party-adds-russian-surveillance/#my-opinion" aria-hidden="true">#</a></h2>
<p>Given the news stories about social media targeting in elections and also Russian meddling, we should be cautious of more companies getting browsing habit data.</p>
<p>If VK intend to protect privacy, why load the JS from their domain and not one with no cookies.</p>
<p>If VK intend to protect privacy, who not drop the referer with a referer-policy on their script tag.</p>
<p>If VK intend to invade privacy, why are they setting cache headers that will miss many requests?</p>
<p>Whatever their intent now, they are a single number change in their own code base from tracking every request; maybe not in the most efficient manner, but they could easily add pixel tracking with a little more.</p>
<h2 id="html-fragment" tabindex="-1">HTML fragment <a class="direct-link" href="https://markalanrichards.com/posts/political-party-adds-russian-surveillance/#html-fragment" aria-hidden="true">#</a></h2>
<p>This html is loaded in the root document</p>
<p><script type="text/javascript" src="<a href="https://vk.com/js/api/openapi.js?168&quot;&gt;&lt;/script&gt">https://vk.com/js/api/openapi.js?168&quot;&gt;&lt;/script&gt</a>;</p>
<h2 id="video-demo" tabindex="-1">Video demo <a class="direct-link" href="https://markalanrichards.com/posts/political-party-adds-russian-surveillance/#video-demo" aria-hidden="true">#</a></h2>
<p>Video showing VK cookies paired with a referer header for the page to Join Britain First</p>
<video controls="" width="960">
<source src="https://markalanrichards.com/videos/britainfirst.webm" type="video/webm" />
<source src="https://markalanrichards.com/videos/britainfirst.mp4" type="video/mp4" />
</video>
<div id="har-data">
<p><a href="https://markalanrichards.com/assets/britainfirst.zip">Har data.</a></p>
</div>
NHS’s Covid-19 website includes advertiser tracking2020-05-15T00:00:00Zhttps://markalanrichards.com/posts/2020-05-15-covid19-app-website-includes-advertiser-tracking/<p><a href="https://covid19.nhs.uk/">https://covid19.nhs.uk/</a> is the primary website for the NHS's Covid-19 app.</p>
<p><a href="https://github.com/nhsx/COVID-19-app-Android-BETA/blob/2a65dbccb3c145ccde1c8ca63735800c047cd5d7/app/src/main/java/uk/nhs/nhsx/sonar/android/app/util/BrowserUtils.kt#L51-L53">It is referenced in the Android app source code.</a></p>
<h2 id="it-has-a-disfunctional-cookie-banner" tabindex="-1">It has a disfunctional cookie banner <a class="direct-link" href="https://markalanrichards.com/posts/2020-05-15-covid19-app-website-includes-advertiser-tracking/#it-has-a-disfunctional-cookie-banner" aria-hidden="true">#</a></h2>
<p>The website has a cookie banner asking if you want to accept or decline cookies.</p>
<p>However, without any interaction, advertiser cookies are already being used and you are being tracked</p>
<h2 id="what-does-it-load" tabindex="-1">What does it load? <a class="direct-link" href="https://markalanrichards.com/posts/2020-05-15-covid19-app-website-includes-advertiser-tracking/#what-does-it-load" aria-hidden="true">#</a></h2>
<p>It loads a Youtube video, that in turn loads Google Doubleclick content.</p>
<h2 id="what-does-this-mean" tabindex="-1">What does this mean? <a class="direct-link" href="https://markalanrichards.com/posts/2020-05-15-covid19-app-website-includes-advertiser-tracking/#what-does-this-mean" aria-hidden="true">#</a></h2>
<p>The site enrols users into advertiser tracking by Youtube and Doubleclick.</p>
<p>Advertiser tracking is typically used to recommend adverts based on your browsing habits.</p>
<p>Google demands websites do not include Youtube videos on sites without first getting cookie consent or using appropriate privacy features.</p>
<p>Youtube demands its typical service is not provided to users under the age of 13.</p>
<h2 id="which-laws-are-broken" tabindex="-1">Which laws are broken? <a class="direct-link" href="https://markalanrichards.com/posts/2020-05-15-covid19-app-website-includes-advertiser-tracking/#which-laws-are-broken" aria-hidden="true">#</a></h2>
<ul>
<li><strong>ePrivacy/PECR:</strong> (the cookie law) which includes the demand that data unnecessarily collected from users devices requires consent.</li>
<li><strong>DPA/GDPR:</strong> Google uses tracking cookies, typically associated with Google accounts and so the data is not just associated with a device, but a user and is therefore personal data and must be obtained with consent.</li>
</ul>
<h2 id="is-this-excusable" tabindex="-1">Is this excusable? <a class="direct-link" href="https://markalanrichards.com/posts/2020-05-15-covid19-app-website-includes-advertiser-tracking/#is-this-excusable" aria-hidden="true">#</a></h2>
<p>No, video is easy on websites without Youtube.</p>
<p>Also, not only does Youtube have options to reduce tracking which have not been set, but the NHS can self host their content or use services from video content hosters that are not famous for breaching privacy.</p>
<h2 id="this-seems-familiar" tabindex="-1">This seems familiar? <a class="direct-link" href="https://markalanrichards.com/posts/2020-05-15-covid19-app-website-includes-advertiser-tracking/#this-seems-familiar" aria-hidden="true">#</a></h2>
<p>Yes, similar privacy failures regarding Youtube were found in recent posts here.</p>
<ul>
<li><a href="https://markalanrichards.com/2019/03/17/ad-tracking-of-childline.html">Childline</a></li>
<li><a href="https://markalanrichards.com/2019/10/08/British-privacy-regulator-breaches-privacy.html">ICO</a></li>
</ul>
<h2 id="video-demo" tabindex="-1">Video demo <a class="direct-link" href="https://markalanrichards.com/posts/2020-05-15-covid19-app-website-includes-advertiser-tracking/#video-demo" aria-hidden="true">#</a></h2>
<p>Video showing Youtube and Doubleclick cookies</p>
<video controls="" width="960">
<source src="https://markalanrichards.com/videos/cov19nhs.webm" type="video/webm" />
<source src="https://markalanrichards.com/videos/cov19nhs.mp4" type="video/mp4" />
</video>
<div id="har-data">
<p><a href="https://markalanrichards.com/assets/covid19.zip">Har data.</a></p>
</div>
British privacy regulator breaches privacy2019-10-08T00:00:00Zhttps://markalanrichards.com/posts/2019-10-08-british-privacy-regulator-breaches-privacy/<p>In April 2018 I emailed the ICO about Twitter receiving identifiable tracking data of what pages users of the ICO website were visiting.</p>
<pre><code> curl 'https://platform.twitter.com/widgets/widget_iframe.1966f64be47cf16b7a48642c76cc6202.html?origin=https%3A%2F%2Fico.org.uk&settingsEndpoint=https%3A%2F%2Fsyndication.twitter.com%2Fsettings' \
-H 'Referer: https://ico.org.uk/global/cookies/' \
-H 'Cookie: personalization_id="v1_1axooVApMv4kdQlRP0kJOA=="; guest_id=v1%3A151762216238340054; _ga=GA1.2.1216735797.1517622164; eu_cn=1; tfw_exp=0; dnt=1; ads_prefs="HBISAAA="; kdt=pZ2uCnWdpMHbENSaC0VyO3qW3GioHnuDLBDUeQUX; remember_checked_on=1; twid="u=66337826"; auth_token=3010b5c28bae881299c6ec636f788ba1931b5e7d; __utma=43838368.1216735797.1517622164.1523130476.1523130476.1; __utmz=43838368.1523130476.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none)'
</code></pre>
<p><em>I complained; it disappeared.</em></p>
<p>Today, their website sends identifiable tracking data for some pages to third parties; including Vimeo, Youtube and Google.</p>
<p>Let's be clear, it does not appear to be on many pages.</p>
<p><em>However, this is a bit like discovering a police commissioner does drugs... don't worry it's just weed and only at festivals.</em></p>
<p>I hope you can enjoy the irony; but after a giggle, the reality is pretty sad.</p>
<p>The ICO is the UK's data protection regulator, expected to enforce GDPR and ePrivacy (the cookie law).</p>
<p>Not break them</p>
<h2 id="here-are-two-videos-demoing-the-problem" tabindex="-1">Here are two videos demoing the problem <a class="direct-link" href="https://markalanrichards.com/posts/2019-10-08-british-privacy-regulator-breaches-privacy/#here-are-two-videos-demoing-the-problem" aria-hidden="true">#</a></h2>
<p>Neither video uses cookies, the ICO doesn't need them on its website either.</p>
<p>Video showing Vimeo cookies</p>
<video controls="" width="960">
<source src="https://markalanrichards.com/videos/ico-vimeo.webm" type="video/webm" />
<source src="https://markalanrichards.com/videos/ico-vimeo.mp4" type="video/mp4" />
</video>
<p>Video showing Youtube cookies</p>
<video controls="" width="960">
<source src="https://markalanrichards.com/videos/ico-youtube.webm" type="video/webm" />
<source src="https://markalanrichards.com/videos/ico-youtube.mp4" type="video/mp4" />
</video>
<p>There's no excuse for the ICO not to do a similar thing.</p>
<ul>
<li>Youtube
<ul>
<li><a href="https://markalanrichards.com/posts/2019-10-08-british-privacy-regulator-breaches-privacy/#google-cookies">google.com cookies</a></li>
<li><a href="https://markalanrichards.com/posts/2019-10-08-british-privacy-regulator-breaches-privacy/#youtube-cookies">youtube.com cookies</a></li>
<li><a href="https://markalanrichards.com/posts/2019-10-08-british-privacy-regulator-breaches-privacy/#youtube-privacy">ICO misrepresents Youtube cookies</a></li>
</ul>
</li>
<li>Vimeo
<ul>
<li><a href="https://markalanrichards.com/posts/2019-10-08-british-privacy-regulator-breaches-privacy/#vimeo-cookies">Vimeo: lots of cookies</a></li>
<li><a href="https://markalanrichards.com/posts/2019-10-08-british-privacy-regulator-breaches-privacy/#vimeo-privacy">ICO misrepresents Vimeo cookies</a></li>
</ul>
</li>
</ul>
<h2 id="youtube" tabindex="-1">Youtube <a class="direct-link" href="https://markalanrichards.com/posts/2019-10-08-british-privacy-regulator-breaches-privacy/#youtube" aria-hidden="true">#</a></h2>
<p>Youtube offers a more private version of their player that claims to not use cookies</p>
<p>Not exactly surprising, but Youtube lied; which is the ICO's problem as they should have spotted this with a simple test.</p>
<div id="google-cookies">
<h3 id="youtube-no-cookie-includes-google-com-cookie" tabindex="-1">Youtube No Cookie includes <a href="http://google.com/">google.com</a> cookie <a class="direct-link" href="https://markalanrichards.com/posts/2019-10-08-british-privacy-regulator-breaches-privacy/#youtube-no-cookie-includes-google-com-cookie" aria-hidden="true">#</a></h3>
<p><a href="http://youtube-nocookie.com/">youtube-nocookie.com</a> is a video player that promises no cookies. However, the player includes a dependency on a request to <a href="http://google.com/">google.com</a>, which will be paired with Google cookies including Google account identifiers.</p>
<p>Note: the dependency currently has a cache expiry of 365 days, so the chances of being affected may be slim.</p>
<p>Google can match this data to the user and the ICO page view if you have a Google account or likely if you've used Google.</p>
<pre><code> GET /js/bg/HrK92udDk6HoGDmAxeAPjdRCsXObyhVNLwAlDW4jykM.js HTTP/1.1
Host: www.google.com
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Firefox/60.0
Accept: */*
Accept-Language: en-GB,en;q=0.5
Accept-Encoding: gzip, deflate, br
Referer: https://www.youtube-nocookie.com/embed/NzX3PPddUVo?feature=oembed
Cookie: CONSENT=WP.27ee3a; 1P_JAR=2019-10-03-20; NID=188=fcHkPZF7m10gNkVCvmI7zmbJ5NiTxatB8xNr5FHnRJcARVGIGOkriNEXzO5Cwhau1A2OlU0ES1ubQi0HqhSyYtoK-rM1r59pTMHNNBvmWklLHiTp_Rkc46SK29ZRmZl0_WpqCH4dXRCeYPS67d0J1k_FbWtmCTFS_0O5o8E4bR4; ANID=AHWqTUmW7cZgZqHuOE0LcehhZQ0_RZNDj2AnQULVayYFBiGs-WrFedtZxz39Og28
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
</code></pre>
</div>
<div id="youtube-cookies">
<h3 id="youtube-no-cookie-sometimes-loads-youtube-cookies" tabindex="-1">Youtube No Cookie sometimes loads Youtube cookies <a class="direct-link" href="https://markalanrichards.com/posts/2019-10-08-british-privacy-regulator-breaches-privacy/#youtube-no-cookie-sometimes-loads-youtube-cookies" aria-hidden="true">#</a></h3>
<ul>
<li>~8% of the UK does not speak English as their first language</li>
<li>1/6 UK adult population is affected by hearing loss</li>
<li>Many people use the web in quiet or noisy situations: on transport, in an open office, outdoors with background noise like radio or TV.</li>
</ul>
<p>So a lot of people have a reason to use subtitles. Do it and Youtube get tracking data that will pair to a Youtube account if you have one.</p>
<pre><code> GET /api/timedtext?v=ZqzGM8nUsDo&asr_langs=de%2Cen%2Ces%2Cfr%2Cit%2Cja%2Cko%2Cnl%2Cpt%2Cru&caps=asr&xorp=true&hl=en-GB&ip=0.0.0.0&ipbits=0&expire=1570167963&sparams=ip%2Cipbits%2Cexpire%2Cv%2Casr_langs%2Ccaps%2Cxorp&signature=D1395DA0C2116757EAA453EEE78B761FC2A18F07.12E6A1E623A964A2C5D3346DDA7C2511B98FA90B&key=yt8&kind=asr&lang=en&fmt=srv3&xorb=2&xobt=3&xovt=3 HTTP/1.1
Host: www.youtube.com
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Firefox/60.0
Accept: */*
Accept-Language: en-GB,en;q=0.5
Accept-Encoding: gzip, deflate, br
Referer: https://www.youtube-nocookie.com/embed/ZqzGM8nUsDo
Origin: https://www.youtube-nocookie.com
Cookie: PREF=f1=50000000; VISITOR_INFO1_LIVE=si2dxYzatEI; GPS=1; YSC=ZQ9Sf3PAtT8; CONSENT=WP.27ee48
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
</code></pre>
</div>
<div id="youtube-privacy">
<h3 id="ico-misrepresents-youtube-cookies" tabindex="-1">ICO misrepresents Youtube cookies <a class="direct-link" href="https://markalanrichards.com/posts/2019-10-08-british-privacy-regulator-breaches-privacy/#ico-misrepresents-youtube-cookies" aria-hidden="true">#</a></h3>
<p>Under the video in the <a href="https://ico.org.uk/global/privacy-notice/">Privacy Notice</a>, you can see</p>
<blockquote>
<p><em>Pressing play on the video above will set a third-party cookie Please read our <a href="https://ico.org.uk/global/cookies/">cookie policy</a> for more information.</em></p>
</blockquote>
<p>(However, the <a href="http://google.com/">google.com</a> cookie is already loaded before play if you are affected by it.)</p>
<p>The <a href="https://ico.org.uk/global/cookies/">Cookies Policy</a> states</p>
<blockquote>
<p><em>We embed videos from our official YouTube channel using YouTube's privacy-enhanced mode. This mode may set cookies on your computer once you click on the YouTube video player, but YouTube will not store personally-identifiable cookie information for playbacks of embedded videos using the privacy-enhanced mode. Read more at <a href="https://support.google.com/youtube/answer/171780?hl=en-GB">YouTube's embedding videos information page.</a></em></p>
</blockquote>
<p>Okay, so let's visit the Youtube page, which states</p>
<blockquote>
<p><em>(The privacy-enhanced mode only relates to tracking of viewer behaviour, not ad-serving behaviour. To disable tracking for advertising purposes, you can add yourself to the Tag for child-directed treatment page.)</em></p>
</blockquote>
<p>I'm not sure I trust Youtube's commitment.</p>
</div>
<h2 id="vimeo" tabindex="-1">Vimeo <a class="direct-link" href="https://markalanrichards.com/posts/2019-10-08-british-privacy-regulator-breaches-privacy/#vimeo" aria-hidden="true">#</a></h2>
<div id="vimeo-cookies">
<h3 id="vimeo-cookies" tabindex="-1">Vimeo cookies <a class="direct-link" href="https://markalanrichards.com/posts/2019-10-08-british-privacy-regulator-breaches-privacy/#vimeo-cookies" aria-hidden="true">#</a></h3>
<p>Loading the page with a video present, regardless of playing it, results in a request to Vimeo.</p>
<p>For users who've never been to Vimeo, you might be lucky and just have a vuid cookie set; pairing you to a tracking id that may reveal your identity to vimeo later.</p>
<p>For users who've got a Vimeo account, Vimeo get cookies that identify exactly who you are and the ICO page you are visiting.</p>
<h4 id="without-a-vimeo-account" tabindex="-1">Without a Vimeo account <a class="direct-link" href="https://markalanrichards.com/posts/2019-10-08-british-privacy-regulator-breaches-privacy/#without-a-vimeo-account" aria-hidden="true">#</a></h4>
<pre><code> GET /video/358070413?loop=1 HTTP/1.1
Host: player.vimeo.com
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Firefox/60.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-GB,en;q=0.5
Accept-Encoding: gzip, deflate, br
Referer: https://ico.org.uk/for-organisations/data-protection-and-brexit/data-protection-and-brexit-for-small-organisations/
Cookie: vuid=pl935718006.582706622
Connection: keep-alive
Upgrade-Insecure-Requests: 1
Cache-Control: max-age=0
</code></pre>
<h4 id="with-a-vimeo-account-some-cookies-look-like-they-are-from-google-and-facebook-analytics-software" tabindex="-1">With a Vimeo account: some cookies look like they are from Google and Facebook analytics software <a class="direct-link" href="https://markalanrichards.com/posts/2019-10-08-british-privacy-regulator-breaches-privacy/#with-a-vimeo-account-some-cookies-look-like-they-are-from-google-and-facebook-analytics-software" aria-hidden="true">#</a></h4>
<pre><code> GET /video/358070413?loop=1 HTTP/1.1
Host: player.vimeo.com
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Firefox/60.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-GB,en;q=0.5
Accept-Encoding: gzip, deflate, br
Referer: https://ico.org.uk/for-organisations/data-protection-and-brexit/data-protection-and-brexit-for-small-organisations/
Cookie: vuid=pl538282171.1754524407; _bpsid=e21af1b1-1ae2-4aaf-aa7d-914d2ae050d5; _gcl_au=1.1.117979163.1570144889; _ga=GA1.2.1411508309.1570144890; _gid=GA1.2.1730788029.1570144890; _fbp=fb.1.1570144893155.1441182793; __qca=P0-1981308565-1570144892675; vimeo_gdpr_optin=1; vimeo=OHL4SeXt4SeMVHLeZ4LdeLX4MxHXcBae%2CZPcDccceZ4c4tLN4XeS%2Cd4a3NZB43%2C4c4DMw3h_OI3uHLM5i_Ic9j3H9ubNwizNVi9wMIHeNa4ateePPDPN4X4tDet4%2CaZPNZacDNPNZP44XLBtZaXBBLXPd4ca%2C3BPaeSdN4D; __ssid=8a862efc-ebab-4cb4-9f9f-0700fdee5887; player=""; has_logged_in=1; site_settings=%7B%22browse_format_vid%22%3A%22video%22%7D; continuous_play_v3=1; __gads=ID=9de2d6ff5570d131:T=1570145696:S=ALNI_MYR0_jgJOqKfNfRRJ5jBUsfJfFwZg
Connection: keep-alive
Upgrade-Insecure-Requests: 1
Cache-Control: max-age=0
</code></pre>
</div>
<div id="vimeo-privacy">
<h3 id="ico-misrepresents-vimeo-cookies" tabindex="-1">ICO misrepresents Vimeo cookies <a class="direct-link" href="https://markalanrichards.com/posts/2019-10-08-british-privacy-regulator-breaches-privacy/#ico-misrepresents-vimeo-cookies" aria-hidden="true">#</a></h3>
<p><a href="https://ico.org.uk/for-organisations/data-protection-and-brexit/data-protection-and-brexit-for-small-organisations/">Stated below the video</a></p>
<blockquote>
<p><em>Pressing play on the videos above will set third-party cookies necessary for the video to play and collecting analytics such as the length of time the video was played. The third party cookies do not track users. Please read our cookie policy for more information</em></p>
</blockquote>
<p><a href="https://ico.org.uk/global/cookies/">The Cookies page then states</a></p>
<blockquote>
<p><em>We embed videos from our official Vimeo channel. When you press play Vimeo will drop third party cookies to enable the the video to play and to collect analytics data such as how long a viewer has watched the video. These cookies do not track individuals.</em></p>
</blockquote>
<p>Obviously these statements are both false.</p>
</div>
<div id="har-data">
<p><a href="https://markalanrichards.com/assets/ico.zip">Har data; Vimeo account was deleted.</a></p>
</div>
Firefox: Leave my DNS alone2019-09-14T00:00:00Zhttps://markalanrichards.com/posts/2019-09-14-firefox-leave-my-dns-alone/<p>Cloudflare DoH is not just a privacy problem.</p>
<h2 id="other-risks" tabindex="-1">Other risks <a class="direct-link" href="https://markalanrichards.com/posts/2019-09-14-firefox-leave-my-dns-alone/#other-risks" aria-hidden="true">#</a></h2>
<ul>
<li>Consumer protection and choice</li>
<li>Cloudflare Blocklists</li>
<li>Loss of jurisdiction</li>
<li>User confusion</li>
<li>A bad precedent... think Superfish</li>
</ul>
<h2 id="what-should-mozilla-do-to-help" tabindex="-1">What should Mozilla do to help? <a class="direct-link" href="https://markalanrichards.com/posts/2019-09-14-firefox-leave-my-dns-alone/#what-should-mozilla-do-to-help" aria-hidden="true">#</a></h2>
<p>Operating systems need better tooling, not just browsers, so make an unbiased DNS tool for the operating system and make it easy to install from Firefox.</p>
<p>dnsmasq demonstrates where this could techincally sit in the DNS stack.</p>
<p>Firewall and antivirus apps demonstrate the nature of app we need.</p>
<p>The app would need to check, notify, offer config options and recommendations: triggered by network changes.</p>
<p>Offer users</p>
<ul>
<li>Visibility: To see how bad their current DNS is</li>
<li>Control: to learn and change their DNS config with a UI</li>
<li>Choice: A marketplace of providers with pros and cons listed, sure Cloudflare should be listed</li>
<li>Plugins: Cache control, local overrides, Bonjour/Avahi, Gnunet, Namecoin, IPNS, etc might enjoy a common name resolver interface and users might trust Mozilla to install them</li>
</ul>
<h2 id="what-is-firefox-doing" tabindex="-1">What is Firefox doing? <a class="direct-link" href="https://markalanrichards.com/posts/2019-09-14-firefox-leave-my-dns-alone/#what-is-firefox-doing" aria-hidden="true">#</a></h2>
<p><a href="https://blog.mozilla.org/futurereleases/2019/09/06/whats-next-in-making-dns-over-https-the-default/">What's next in making Encrypted DNS-over-HTTPS the Default</a></p>
<p>Firefox is starting the rollout of Cloudflare being the DNS provider for Firefox installs by default.</p>
<p>Mozilla believes it knows better than the choices you made or the local network defaults.</p>
<p>Some opinions already expressed:</p>
<ul>
<li><a href="https://ungleich.ch/en-us/cms/blog/2019/09/11/turn-off-doh-firefox/">Turn off DoH, Firefox. Now.</a></li>
<li><a href="https://undeadly.org/cgi?action=article;sid=20190911113856">OpenBSD Journal: DoH disabled by default in Firefox</a></li>
</ul>
<h2 id="my-privacy" tabindex="-1">My Privacy <a class="direct-link" href="https://markalanrichards.com/posts/2019-09-14-firefox-leave-my-dns-alone/#my-privacy" aria-hidden="true">#</a></h2>
<p>I live in the EU, so Cloudflare appears to be a higher privacy risk.</p>
<p>I know I am a low privacy risk as I'm not a: soldier, doctor, journalist, politician, cancer sufferer, member of a demographic typically at risk of discrimination, ...</p>
<p>If I had a reason not to trust my network, I'd need a VPN, not a better DNS resolver.</p>
<h2 id="consumer-protection-and-choice" tabindex="-1">Consumer protection and choice <a class="direct-link" href="https://markalanrichards.com/posts/2019-09-14-firefox-leave-my-dns-alone/#consumer-protection-and-choice" aria-hidden="true">#</a></h2>
<p>My DNS is provided by an ISP that I pay for and because of this it has to be of merchantable quality under UK law.</p>
<p>If my ISP fails it has to answer to my wallet, my demands for a refund and potentially multiple regulators here.</p>
<p>Should Cloudflare fail for my local network or devices what action can I take or the UK regulators?</p>
<p>Will I be able to change if Cloudflare becomes mainstream? Why would my ISP provide DNS services? Like email it may disappear and I'm stuck with whatever Cloudflare offers.</p>
<h2 id="loss-of-jurisdiction" tabindex="-1">Loss of jurisdiction <a class="direct-link" href="https://markalanrichards.com/posts/2019-09-14-firefox-leave-my-dns-alone/#loss-of-jurisdiction" aria-hidden="true">#</a></h2>
<p>In the UK there are websites that have been banned.</p>
<p>Whether you agree with the Pirate Bay being blocked or not, you might agree that it's a good idea that UK users cannot resolve child pornogrphy sites.</p>
<p>Users who wish to circumvent local jurisdiction should be looking at VPNs not DNS. In some countries I might support their efforts if well intended..</p>
<p>As an account holder, on a home wifi I share with friends and family, I'm not just thinking about my own browsing when I want resolution to fail if they visit illegal sites.</p>
<p>The USA has different laws that mean it may force US companies to block content that may be okay abroad. Maybe Wikileaks, maybe SciHub or maybe The Guardian when the next Snowden style leaks happen.</p>
<h2 id="cloudflare-blocklists" tabindex="-1">Cloudflare Blocklists <a class="direct-link" href="https://markalanrichards.com/posts/2019-09-14-firefox-leave-my-dns-alone/#cloudflare-blocklists" aria-hidden="true">#</a></h2>
<p>Cloudflare has repeatedly been known to refuse to block hosting services to content that was controversial</p>
<p>However, it also has abided by some, notably removing hosting to 8chan</p>
<p>Whilst I agree that 8chan should have been removed by Cloudflare, if Cloudflare has a marketplace control, like over most users of Firefox, then the only blocking it should do is that necessary by law</p>
<p>It might make my day to see them block DNS resolution of a company like Google, on the grounds that Google is breaching privacy laws and therefore unethical to resolve, but that shouldn't be an option Cloudflare can take.</p>
<h2 id="user-confusion" tabindex="-1">User confusion <a class="direct-link" href="https://markalanrichards.com/posts/2019-09-14-firefox-leave-my-dns-alone/#user-confusion" aria-hidden="true">#</a></h2>
<p>Think about the following scenarios:</p>
<p>I can view my workplace email in Chrome, but not Firefox? Why? How will Firefox keep up with intranet resolvers that come and go according to users context and may be different on the open web than in the office?</p>
<p>Developers often play with DNS to investigate problems or avoid hitting production servers. This risks blacklists and overrides set in infrastructure or local settings no longer working, which may cause confusion or worse security hardening techniques failing.</p>
<p>A privacy invading hotel gets annoyed at 1.1.1.1 not being visible so blocks it on their wifi: what happens? I'm guessing Firefox gives up Cloudflare or the user gives up on Firefox.</p>
<h2 id="a-bad-precedent" tabindex="-1">A bad precedent <a class="direct-link" href="https://markalanrichards.com/posts/2019-09-14-firefox-leave-my-dns-alone/#a-bad-precedent" aria-hidden="true">#</a></h2>
<p>Firefox is an application, like any other and deciding that apps shuld be managing encrypted DNS is worrying.</p>
<p>With the privacy problems we've seen with period apps, Facebook SDK tracking and similar, users desparately need control and visibility of what apps can do on the network. DNS control and similar should be in the hands of the OS and global settings users can control.</p>
<p>Firefox is now going to be another app that is doing weird encrypted stuff you cannot see and maybe Firefox will have audit logs and network logs to see what Cloudflare gets, but will your Period app or the Facebook SDK when it starts using DoH too?</p>
<p>And why just your apps playing directly with DoH? If apps should be taking DNS control away from your network, why not your laptop manufacturer: why not Lenovo? Some manufacturers may love to take control of your network for their own purposes for ad distribution and if Firefox supports DoH controls over the network, then perhaps Lenovo should fork it and distribute it with new laptops set to use their DoH resolver?</p>
Ad tracking of Childline2019-03-17T00:00:00Zhttps://markalanrichards.com/posts/2019-03-17-ad-tracking-of-childline/<p>You may have spotted news about
<a href="https://www.bloomberg.com/news/articles/2019-01-24/how-period-tracking-apps-are-monetizing-women-s-extremely-personal-data">period</a>,
<a href="https://www.theguardian.com/world/2018/jan/28/fitness-tracking-app-gives-away-location-of-secret-us-army-bases">fitness</a> and
<a href="https://techcrunch.com/2017/08/24/accuweather-update-reveal-mobile/">weather</a> apps sharing data about their users.</p>
<p>This is a bit darker, primarily because the victims are children, the perpetrator a charity and the tracking
companies are once again household names.</p>
<p>Childline put ad tracking on their online help chat, whilst promising anonymity and confidentiality.</p>
<p>This tracking can often identify kids and included their activity on the site, posing three risks</p>
<ol>
<li>
<p>Ad algorithms are supposed to match data collected with adverts likely to be clicked on.</p>
<p>So, when a child visits pages about drug addiction and abuse at home, then joins a counsellor session, what adverts do you think the algorithms paired them with?</p>
<p>Maybe just teddy bears or maybe alcohol and painkillers. This pairing doesn't even require the real identity of the child</p>
</li>
<li>
<p>These companies combined employ thousands of staff in the UK</p>
<p>Whether they're kind people or not, their kids may not want their parents to have access to knowledge they're using Childline.</p>
</li>
<li>
<p>These companies have a history of information security failures, so how much of this data is likely
sitting in servers ready to be leaked or already has</p>
</li>
</ol>
<h2 id="who-is-affected" tabindex="-1">Who is affected? <a class="direct-link" href="https://markalanrichards.com/posts/2019-03-17-ad-tracking-of-childline/#who-is-affected" aria-hidden="true">#</a></h2>
<p>All users of the site, including children seeking help from counsellors.</p>
<h2 id="what-was-sent-to-the-ad-companies" tabindex="-1">What was sent to the ad companies? <a class="direct-link" href="https://markalanrichards.com/posts/2019-03-17-ad-tracking-of-childline/#what-was-sent-to-the-ad-companies" aria-hidden="true">#</a></h2>
<h3 id="their-activity" tabindex="-1">Their activity <a class="direct-link" href="https://markalanrichards.com/posts/2019-03-17-ad-tracking-of-childline/#their-activity" aria-hidden="true">#</a></h3>
<p>The pages children visited, including those to chat with counsellors</p>
<h3 id="identity" tabindex="-1">Identity <a class="direct-link" href="https://markalanrichards.com/posts/2019-03-17-ad-tracking-of-childline/#identity" aria-hidden="true">#</a></h3>
<p>The ad companies are well known to track users by cookies or even device identifiers (like IP addresses) that identify a device.</p>
<p>They may also hold advertising profiles they build up and potentially user accounts too.</p>
<p>But these identities are isolated from tracking Childline activity, until Childline adds their tracking software to
their own site too.</p>
<p>Just in case they didn't already have identities, Childline's actions resulted in ad tracking cookies being set, allowing subsequent tracking off the Childline site.</p>
<h3 id="the-extent" tabindex="-1">The extent <a class="direct-link" href="https://markalanrichards.com/posts/2019-03-17-ad-tracking-of-childline/#the-extent" aria-hidden="true">#</a></h3>
<p>I'm guessing most Childline pages were affected, so have a browse around the site and see how bad it might be.</p>
<p>These pages alone are enough to worry about</p>
<ul>
<li><a href="https://www.childline.org.uk/get-support/1-2-1-counsellor-chat/">Counsellor Chat</a></li>
<li><a href="https://childline.org.uk/registration/?returnPath=/get-support/1-2-1-counsellor-chat/chat-entry/">Registering to join a counsellor chat</a></li>
</ul>
<h2 id="why-did-childline-do-this" tabindex="-1">Why did Childline do this? <a class="direct-link" href="https://markalanrichards.com/posts/2019-03-17-ad-tracking-of-childline/#why-did-childline-do-this" aria-hidden="true">#</a></h2>
<p>You'll have to ask Childline for a clear answer</p>
<h3 id="at-a-guess" tabindex="-1">At a guess... <a class="direct-link" href="https://markalanrichards.com/posts/2019-03-17-ad-tracking-of-childline/#at-a-guess" aria-hidden="true">#</a></h3>
<p>The advertising companies offer a nasty bargain. You let them track your users and they'll give you useful data back about them.</p>
<p>Confused? Imagine a child browsing the web might be something like this:</p>
<ul>
<li>The ad company collects demographic data as a child visits other web sites (like <a href="https://support.google.com/analytics/answer/2799357?hl=en&ref_topic=2799375">Google</a> does).</li>
<li>Childline puts the ad companies' tracking on their site</li>
<li>A thirteen year old girl from Wales visits childline's website to join a counsellor session</li>
<li>The ad company tracks a visit has happened and also adds it to stats for Childline.</li>
<li>Childline may get aggregated data, so this would be part of a report like 40% of users are under 18, 10% from Wales and 49% female</li>
<li>The ad company then gets a visit soon after by that child from a site that shows its ads.</li>
<li>Which ones do their algorithms pair up? Perhaps, a childline chat using, thirteen year girl, perform well wih Baracdi Breezer ads. (Sorry Barcadi, maybe they don't, just emphasising the potential here)</li>
</ul>
<h3 id="then-there-s-youtube" tabindex="-1">Then there's Youtube <a class="direct-link" href="https://markalanrichards.com/posts/2019-03-17-ad-tracking-of-childline/#then-there-s-youtube" aria-hidden="true">#</a></h3>
<p>Childline decided to reach children using Youtube and not just by having a channel on Youtube, but by integrating Youtube into the Childline site.</p>
<p>By default Youtube videos added to your own site track users</p>
<p>And Youtube is very obviously an advertiser and one that companies were boycotting because of <a href="https://www.nytimes.com/2019/02/20/technology/youtube-pedophiles.html">other risks to children</a></p>
<p>Duck Duck Go (a growing alternative to Google Search) warn about privacy risks on their own site if you try watching a Youtube video.Try searching for <a href="https://duckduckgo.com/?q=cats">Cats</a>. This is a known problem with Youtube.</p>
<p>Video has been supported by default on the web for years without needing Youtube and Childline added Youtube's tracking to pages in their chat system that don't even show videos.</p>
<h2 id="childline-s-response" tabindex="-1">Childline's response <a class="direct-link" href="https://markalanrichards.com/posts/2019-03-17-ad-tracking-of-childline/#childline-s-response" aria-hidden="true">#</a></h2>
<p>Within hours of contacting the NSPCC on the 26th Feb, about their Childline site including tracking, much of it was removed. Notably, this included Facebook and their terms of service advise that Chidline needed consent and shouldn't send data for under 13s.</p>
<p>However, Childline insist on keeping Youtube as it's "unavoidable" .. given they load tracking on pages that don't have video, that's a lie. Also, within hours you can start moving video on your own site to html5 video with self hosting files... it is really simple to do.</p>
<p>I've asked them repeatedly to tell the children affected by this. In order to keep their trust, the organisation has to be open and honest about failings, but this has not happened and hence I'm writing this blog post about it.</p>
<h2 id="what-does-a-request-look-like" tabindex="-1">What does a request look like? <a class="direct-link" href="https://markalanrichards.com/posts/2019-03-17-ad-tracking-of-childline/#what-does-a-request-look-like" aria-hidden="true">#</a></h2>
<p>Here's an example of Youtube request. I've hidden my cookie values as the session ones may have security implications for my Youtube account</p>
<p>You may not understand the structure, but everything in the following block went to Youtube's server when I made a request and more (like IP address)</p>
<pre><code> GET /iframe_api HTTP/1.1
Host: www.youtube.com
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:65.0) Gecko/20100101 Firefox/65.0
Accept: */*
Accept-Language: en-GB,en;q=0.5
Accept-Encoding: gzip, deflate, br
Referer: https://www.childline.org.uk/login/?returnPath=/get-support/1-2-1-counsellor-chat/chat-entry/
Connection: keep-alive
Cookie: SID=...; HSID=...; SSID=...; APISID=...; SAPISID=...; CONSENT=YES+GB.en+20160501-18-0; LOGIN_INFO=...; VISITOR_INFO1_LIVE=...; PREF=...; enabledapps.uploader=0; SIDCC=...
DNT: 1
Pragma: no-cache
Cache-Control: no-cache
</code></pre>
<p>APISID is an interesting one <a href="https://cookiepedia.co.uk/cookies/APISID">https://cookiepedia.co.uk/cookies/APISID</a> but I'm sure you can find out more about the others too.</p>
<p>Because those same cookies will be used when a user visits Youtube, Youtube can pair this web page visit with a user account.</p>
<h2 id="what-next" tabindex="-1">What next? <a class="direct-link" href="https://markalanrichards.com/posts/2019-03-17-ad-tracking-of-childline/#what-next" aria-hidden="true">#</a></h2>
<p>If you're a child or know one who should know, then tell them not to trust their privacy is protected on Childline.</p>
<p>If you need Childline services, their phone line may protect privacy appropriately on 0800 1111</p>
<p>Tracking protection mechanisms in web browsers (including Privacy Badger) may reduce the amount of tracking that would be sent.</p>
<p>If you've used Childline and feel upset or angered, then please beware that Childline is not alone in this behaviour and it is common to breach users' privacy like this, although not usually with such sensitive data.</p>
Reset Password Links are a Security Failure according to the HTTP RFC2018-08-12T00:00:00Zhttps://markalanrichards.com/posts/2018-08-12-reset-password-links-are-a-security-failure-according-to-the-http-rfc/<h1 id="tl-dr" tabindex="-1">tl;dr <a class="direct-link" href="https://markalanrichards.com/posts/2018-08-12-reset-password-links-are-a-security-failure-according-to-the-http-rfc/#tl-dr" aria-hidden="true">#</a></h1>
<p><a href="https://tools.ietf.org/html/rfc7231#section-9.4">https://tools.ietf.org/html/rfc7231#section-9.4</a></p>
<pre><code>9.4. Disclosure of Sensitive Information in URIs
URIs are intended to be shared, not secured, even when they identify
secure resources. URIs are often shown on displays, added to
templates when a page is printed, and stored in a variety of
unprotected bookmark lists. It is therefore unwise to include
information within a URI that is sensitive, personally identifiable,
or a risk to disclose.
</code></pre>
<h1 id="reset-password-link" tabindex="-1">Reset Password Link <a class="direct-link" href="https://markalanrichards.com/posts/2018-08-12-reset-password-links-are-a-security-failure-according-to-the-http-rfc/#reset-password-link" aria-hidden="true">#</a></h1>
<p>Reset password links typically work by generating a unique URL containing enough random data to be considered impossible to guess.</p>
<p>The user opens the URL, the request is validated by the service provider and they then offer a user the ability to set a new password.</p>
<h1 id="why-a-failure" tabindex="-1">Why a failure? <a class="direct-link" href="https://markalanrichards.com/posts/2018-08-12-reset-password-links-are-a-security-failure-according-to-the-http-rfc/#why-a-failure" aria-hidden="true">#</a></h1>
<p>The reset password page may include the following and lose the link as a referer:</p>
<ul>
<li>links to same origin pages: document.referer available to third party JS</li>
<li>links to third party pages: referer sent to third parties when clicked</li>
<li>third party content: referer sent to third parties on reset password page load
<ul>
<li>shared libraries from CDNs (eg: bootstrapcdn)</li>
<li>analytics and social media spyware</li>
<li>ironic fraud detection JS (some finance sites)</li>
</ul>
</li>
</ul>
<h1 id="nobody-would-load-third-party-content-on-their-reset-password-page" tabindex="-1">Nobody would load third party content on their reset password page? <a class="direct-link" href="https://markalanrichards.com/posts/2018-08-12-reset-password-links-are-a-security-failure-according-to-the-http-rfc/#nobody-would-load-third-party-content-on-their-reset-password-page" aria-hidden="true">#</a></h1>
<p>I've found it on sites by these companies:</p>
<ul>
<li>NHS</li>
<li>Gumtree</li>
<li>Uber</li>
<li>Daily Mail</li>
<li>Zopa</li>
<li>123-reg</li>
<li>...</li>
</ul>
<p>*Some have fixed it!</p>
<h1 id="but-it-s-okay-on-https" tabindex="-1">"But it's okay on https"? <a class="direct-link" href="https://markalanrichards.com/posts/2018-08-12-reset-password-links-are-a-security-failure-according-to-the-http-rfc/#but-it-s-okay-on-https" aria-hidden="true">#</a></h1>
<p>No, that's a myth I've heard a few times. There is a security improvement on HTTPS, but it is only that it won't be sent to http sites. It is still available to third party http JS loaded on the page (document.referer) and it's sent to all other HTTPS sites.</p>
<h1 id="but-they-will-only-used-by-the-user" tabindex="-1">"But they will only used by the user"? <a class="direct-link" href="https://markalanrichards.com/posts/2018-08-12-reset-password-links-are-a-security-failure-according-to-the-http-rfc/#but-they-will-only-used-by-the-user" aria-hidden="true">#</a></h1>
<h2 id="what-evidence-do-you-have-of-this" tabindex="-1">What evidence do you have of this? <a class="direct-link" href="https://markalanrichards.com/posts/2018-08-12-reset-password-links-are-a-security-failure-according-to-the-http-rfc/#what-evidence-do-you-have-of-this" aria-hidden="true">#</a></h2>
<p>I saw opposing evidence, one company admitted 5% of requests to their reset password pages were from multiple sources and I've seen logs showing user agents for reset password links as bots.</p>
<h2 id="so-how-do-they-use-it" tabindex="-1">So how do they use it? <a class="direct-link" href="https://markalanrichards.com/posts/2018-08-12-reset-password-links-are-a-security-failure-according-to-the-http-rfc/#so-how-do-they-use-it" aria-hidden="true">#</a></h2>
<p>A percentage of users will not complete the request after opening it. They may get distracted (meeting notification, baby screaming, train entering a tunnel, endless numbers of reasons for why you might not finish what you are doing on a page).</p>
<p>Also, users cannot beat a bot. Once the password has leaked to a third party an automated system would reset the password quite quickly.</p>
<h2 id="but-wouldn-t-users-notice" tabindex="-1">But wouldn't users notice? <a class="direct-link" href="https://markalanrichards.com/posts/2018-08-12-reset-password-links-are-a-security-failure-according-to-the-http-rfc/#but-wouldn-t-users-notice" aria-hidden="true">#</a></h2>
<p>Maybe, but I'd suggest that without evidence, most users would consider it a bug that the reset password page failed and retry (maybe assume that the link expired) and if they got an email suggesting it succeeded, might believe they'd typed their password wrongly when entering it into the reset password flow (had caps lock on?) so would try again.</p>
<h2 id="but-wouldn-t-the-website-notice" tabindex="-1">But wouldn't the website notice? <a class="direct-link" href="https://markalanrichards.com/posts/2018-08-12-reset-password-links-are-a-security-failure-according-to-the-http-rfc/#but-wouldn-t-the-website-notice" aria-hidden="true">#</a></h2>
<p>Depends on what it is used for. If you wanted to steal data, then without any malicious changes to the site you could grab user data. Also, if you kept the percentage of requests low for malcious changes, like purchases, then it'd be within expected bounds for account fraud and the user would likely be blamed.</p>
<h1 id="but-you-can-protect-it-yes-but-can-your-developers" tabindex="-1">But you can protect it? Yes, but can your developers? <a class="direct-link" href="https://markalanrichards.com/posts/2018-08-12-reset-password-links-are-a-security-failure-according-to-the-http-rfc/#but-you-can-protect-it-yes-but-can-your-developers" aria-hidden="true">#</a></h1>
<p>As with most of the web, it is not designed with security in mind. It is an after thought.</p>
<p>In this instance, you need to learn about Referer policies and the dangers of loading third party JavaScript, or you could use multiple factors of authentication or only include the randomised token in the transmission to the user (so they have to type it).</p>
<p>Given the companies I've seen fail at this (and I'm guessing the list is very long I just don't have time to fish them all out) then I doubt most companies employ developers who know how to both create a secure reset password page and then maintain it (from the risks of someone thinking, great I'll add Google Analytics to the page, an explicit breach of GA's terms).</p>
<h1 id="bug-bounty-time" tabindex="-1">Bug Bounty Time <a class="direct-link" href="https://markalanrichards.com/posts/2018-08-12-reset-password-links-are-a-security-failure-according-to-the-http-rfc/#bug-bounty-time" aria-hidden="true">#</a></h1>
<p>This is a simple bug bounty win... go get 'em!</p>
NHS provided advertisers, analytics and social media companies with data about your health concerns2018-06-23T00:00:00Zhttps://markalanrichards.com/posts/2018-06-23-nhs-provided-advertisers-analytics-and-social-media-companies-with-data-about-your-health-concerns/<p><img src="https://markalanrichards.com/img/2018-06-23-nhs-privacy.png" alt="NHS sharing data with AppNexus, DoubleClick Ads, ComScore, Twitter, Facebook, Webtrends, ..." /></p>
<p>Back in 2010, Tom Watson MP raised a problem in parliament <a href="https://www.theregister.co.uk/2010/11/24/nhs_connect_facebook_privacy_fears/">https://www.theregister.co.uk/2010/11/24/nhs_connect_facebook_privacy_fears/</a></p>
<p>That was not resolved: instead, Facebook, Google, WebTrends and many more got and still get a lot of data about your browsing habits on the NHS services online.</p>
<p>Do not expect it to be anonymised: I found that the data is often identifiable to your email address or online accounts with the companies.</p>
<p>Where they are not, they are often identifiable to a profile about you <strong>which is also a breach of your privacy!</strong></p>
<p>FYI: I want this to stop as soon as possible so have added created two petitions that you can sign if you wish.</p>
<ul>
<li><a href="https://www.change.org/p/uk-parliament-nhs-should-respect-privacy-online">https://www.change.org/p/uk-parliament-nhs-should-respect-privacy-online</a> (can be petitioned on an international basis, NHS isn't just a service used by UK citizens and provides space to give details)</li>
<li><a href="https://petition.parliament.uk/petitions/222766">https://petition.parliament.uk/petitions/222766</a> (awaiting review, not such space to describe)</li>
</ul>
<p>This is illegal, privacy is a requirement for healthcare and has been long before GDPR, but there are three things to take away:</p>
<h2 id="what-they-got" tabindex="-1">What they got <a class="direct-link" href="https://markalanrichards.com/posts/2018-06-23-nhs-provided-advertisers-analytics-and-social-media-companies-with-data-about-your-health-concerns/#what-they-got" aria-hidden="true">#</a></h2>
<p>Facebook and others were told for over 7 years about what concerns you had for your health. The details sent to them were often in context of you, like your Facebook user id. The advertising arms of some of the companies uses this data as "audience" data and whether they filtered NHS or not, their motive for asking for it, was to discriminate on whether you were targeted for marketing campaigns: this is one of the primary reasons why healthcare should be private... if they did use the data, then expect to have suffered adverts for funeral directors when you looked for cancer, ecigarettes when you tried to stop smoking, etc, in an advertising context, this nature of data leaking is quite disturbing and would put people at risk of advertising when they are at most risk.</p>
<h2 id="they-put-at-risk-more-from-what-they-got" tabindex="-1">They put at risk more from what they got <a class="direct-link" href="https://markalanrichards.com/posts/2018-06-23-nhs-provided-advertisers-analytics-and-social-media-companies-with-data-about-your-health-concerns/#they-put-at-risk-more-from-what-they-got" aria-hidden="true">#</a></h2>
<p>If these companies wished to, then they had access to a treasure trove of information about significant people in the public. From companies executives and celebrities, to whistleblowers and criminals. Had this data leaked (leaks can easily happen <a href="https://www.zdnet.com/article/alteryx-s3-leak-leaves-120m-american-households-exposed/">https://www.zdnet.com/article/alteryx-s3-leak-leaves-120m-american-households-exposed/</a>) or been hacked then the risk to not just individuals but what they are involved with could have affected reputations, legal cases and allowed for insider trading.</p>
<h2 id="they-got-access-to-do-a-lot-more" tabindex="-1">They got access to do a lot more! <a class="direct-link" href="https://markalanrichards.com/posts/2018-06-23-nhs-provided-advertisers-analytics-and-social-media-companies-with-data-about-your-health-concerns/#they-got-access-to-do-a-lot-more" aria-hidden="true">#</a></h2>
<p>Most of the companies execute JavaScript on the NHS website. This capability allowed them to follow mouse movements, keyboard presses, read content on the pages and even load other pages on the NHS website with access to do any of those too (thanks to iframes in the web sharing a security context if from the same origin). They could also manipulate content, add in username/passwords fields or ask for any data they liked with the appearance that the NHS was asking. This isn't just hypothetical postulation, the security access was compromised when one of the third parties was hacked to use the NHS website (not all of the site used Browsaloud) for cryptomining on people's web browers <a href="https://www.tsg.com/blog/security/ico-nhs-among-thousands-websites-hacked-sneaky-crypto-mining-code">https://www.tsg.com/blog/security/ico-nhs-among-thousands-websites-hacked-sneaky-crypto-mining-code</a></p>
<h2 id="protect-yourselves-from-the-nhs" tabindex="-1">Protect yourselves from the NHS <a class="direct-link" href="https://markalanrichards.com/posts/2018-06-23-nhs-provided-advertisers-analytics-and-social-media-companies-with-data-about-your-health-concerns/#protect-yourselves-from-the-nhs" aria-hidden="true">#</a></h2>
<p>Look into Tor, Brave Browser, Privacy Badger and similar technologies to stop trackers.</p>
<p>Use one off private browsing mode sessions where possible too.</p>
<p>Look into alternative healthcare sites... seriously, there might be some other public health bodies, especially from other countries, that may protect your privacy better.</p>
<h2 id="next-steps" tabindex="-1">Next Steps <a class="direct-link" href="https://markalanrichards.com/posts/2018-06-23-nhs-provided-advertisers-analytics-and-social-media-companies-with-data-about-your-health-concerns/#next-steps" aria-hidden="true">#</a></h2>
<p>We should take legal action against the NHS. Not because we want to take money out of it, but because they need to stop. The precedent set by allowing the NHS to do this, would be to allow everyone to.</p>
<h2 id="some-background" tabindex="-1">Some background <a class="direct-link" href="https://markalanrichards.com/posts/2018-06-23-nhs-provided-advertisers-analytics-and-social-media-companies-with-data-about-your-health-concerns/#some-background" aria-hidden="true">#</a></h2>
<p>I noticed this last year when trying to make sense of how <a href="https://joinpouch.com/">https://joinpouch.com/</a> (seriously, do not join them, they were a security nightmare when I looked into this), were able to advertise an e-cigarette company on the NHS Stoptober campaign (their extension matched the nhs page against a dictionary they provided the extension to be sent the advert and captured tracking data on your visit).</p>
<p>Whilst investigating I spotted various analytics, tracking and advertising companies loading on the Stoptober page and thought, this can't all be Pouch: they're bad, but not that bad and sure enough, with the extension not installed it turned out the NHS website was a mess of online tracking.</p>
<p>Then started months of emails to and fro between NHS Choices/Digital, NHS England and Public Health England: along with my MP, Matthew Hancock's office, the ICO and a few organisations and journalists I've tried to rally to help.</p>
<h2 id="the-position-now" tabindex="-1">The position now: <a class="direct-link" href="https://markalanrichards.com/posts/2018-06-23-nhs-provided-advertisers-analytics-and-social-media-companies-with-data-about-your-health-concerns/#the-position-now" aria-hidden="true">#</a></h2>
<ul>
<li>NHS England largely agreed, they removed much of the advertisers/social media tracking: I think they can do better</li>
<li>NHS Digital largely agreed and they removed much advertisers/social media on the NHS Choices pages.</li>
<li>Public Health England pretty much ignored the complaint and said users have agreed to it.</li>
</ul>
Facebook JavaScript SDK is often illegal2018-06-23T00:00:00Zhttps://markalanrichards.com/posts/2018-06-23-facebook-javascript-sdk-is-often-illegal/<p><a href="https://developers.facebook.com/docs/javascript/">Facebook JavaScript SDK</a> is often included in websites.</p>
<p>It provides feature to help integrate with Facebook.</p>
<p>It provides Facebook with tracking capabilities that assist with audience data and their advertising targeting.</p>
<p>From a privacy perspective, under GDPR, this is a consent nightmare and although it may be possible to get legitimate explicit consent to send data to Facebook, is it still legal to be given when there is a second problem... security and access control.</p>
<p>If a website loads third party JavaScript into a page using a <script> tag then by default it loads with a security context of same-origin - this means that it often it can do whatever JavaScript hosted from the websites' server can do, so likely:</p>
<ul>
<li>Read any content on the page it is loaded
<ul>
<li>Read your user details and often session cookies</li>
</ul>
</li>
<li>Modify (add/change/remove) any content on the page
<ul>
<li>Add a username and password field, capture the values</li>
</ul>
</li>
<li>Make network requests to the websites' servers
<ul>
<li>POST form data</li>
<li>Send ajax requests to backend servers as you</li>
</ul>
</li>
<li>Make network requests elsewhere
<ul>
<li>Append data read to image or script links and add them to the page</li>
<li>Make an AJAX call to its own servers or elsewhere</li>
</ul>
</li>
<li><strong>Access any webpage on your site and do all of the above</strong>
<ul>
<li><strong>If Facebook is loaded on /about, it can iframe /user/account</strong></li>
<li><strong>Default security context of iframes in the same domain is that it can access the child iframe and execute scripts in that iframe.</strong></li>
</ul>
</li>
</ul>
<p>There are various security mechanisms that may reduce this risk, but the problem with these, is that they are very complex to implement: adding in security contexts to ban eval(), SRI, CORS headers and more, requires a lot of security review: but also it negates much if not all of the Facebook functionality if you ban Facebook from receiving data, so why load it?</p>
<blockquote>
<p><strong>Put this all together and you can demonstrate to organisations that they need to remove Facebook.</strong></p>
</blockquote>
<p><strong>So I got Facebook removed from RBS's online banking landing page because it could access the account pages (which it was not loaded on).</strong></p>
<p>And I got it removed off of a noticeable amount of <a href="http://nhs.uk/">nhs.uk</a> because when loaded on pages offering advice (like about Flu) it could access data about your GP and your account.</p>
<p><a href="https://www.youtube.com/watch?v=Ls08tSt-Dko">https://www.youtube.com/watch?v=Ls08tSt-Dko</a></p>
<p><a href="https://www.youtube.com/watch?v=IhrpWhOnVQE">https://www.youtube.com/watch?v=IhrpWhOnVQE</a></p>
<h2 id="why-is-it-illegal" tabindex="-1">Why is it illegal? <a class="direct-link" href="https://markalanrichards.com/posts/2018-06-23-facebook-javascript-sdk-is-often-illegal/#why-is-it-illegal" aria-hidden="true">#</a></h2>
<p>Especially in regulated contexts (finance, healthcare, etc) there are typically requirements that companies must maintain control of their systems (<a href="https://www.handbook.fca.org.uk/handbook/SYSC/3/1.html">https://www.handbook.fca.org.uk/handbook/SYSC/3/1.html</a>) and this cannot mean providing an advertising company with unaudited, uncontrolled access to do whatever it likes. This isn't like self-hosted JS that would have gone through QA processes to validate it.</p>
<p>But GDPR and similar privacy laws internationally, also demand that companies have access controls. Not just for what they want to give companies (that's a consent/legitimate interest problem), but to make sure they cannot access other data they don't have rights to. So should Facebook have access to do whatever they like without any control?</p>
<p>Why should Facebook get access to your account data, be able to do anything on a page or more? Whether you believe Facebook is safe or not is not important. Whatever you justify here for Facebook to have access to, you justify for any organisation, (so gambling, religious, policing, political, etc: why is an advertising company any better?) in any jurisdiction that the UK has a data protection relationship with and when it comes to the USA, that relationship is pretty terrible: the ICO rarely if ever does anything (beyond getting 'promises') when it comes to US companies and in dialogue with them appears to not be able to regulate them.</p>
<p>For NHS users, please check this petition: <a href="https://www.change.org/p/uk-parliament-nhs-should-respect-privacy-online">https://www.change.org/p/uk-parliament-nhs-should-respect-privacy-online</a> as Facebook is not completely removed from their online services, only from some areas.</p>
Mozilla is Evil2018-04-08T00:00:00Zhttps://markalanrichards.com/posts/2018-04-08-mozilla-is-evil/<p>Firstly, many browsers are not your friends, so this is not a Mozilla is worse than X post.</p>
<h2 id="so-why-bash-mozilla" tabindex="-1">So why bash Mozilla? <a class="direct-link" href="https://markalanrichards.com/posts/2018-04-08-mozilla-is-evil/#so-why-bash-mozilla" aria-hidden="true">#</a></h2>
<p>Google get bashed, Microsoft get bashed and Apple do, but the alternative is not a saint. It boasts about privacy, but doesn't enable it for most users, it complains about tracking and then teaches web developers how to do it. It has had complaints for around a <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=467257">decade</a> (since then there have been others, like <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=970092">970092</a>) that user privacy is being invaded because of browser features.</p>
<h2 id="but-mozilla-are-just-following-a-standard" tabindex="-1">But Mozilla are just following a standard? <a class="direct-link" href="https://markalanrichards.com/posts/2018-04-08-mozilla-is-evil/#but-mozilla-are-just-following-a-standard" aria-hidden="true">#</a></h2>
<p>Mozilla staff can often play a key role in changing the web, from work on drafting standards to work on demonstrating new ideas with new features that are yet to be fully standardised.
Web standards are not legal requirements and there is nothing to stop Mozilla either breaking from them to fix privacy and security or providing a default alternative release or feature flags that protect users.</p>
<h2 id="fixing-the-design-that-would-break-everyone" tabindex="-1">Fixing the design that would break everyone? <a class="direct-link" href="https://markalanrichards.com/posts/2018-04-08-mozilla-is-evil/#fixing-the-design-that-would-break-everyone" aria-hidden="true">#</a></h2>
<p>So? Apple broke a lot when they stopped supporting Flash. Is Firefox incapable of leading beyond broken standards, to protect users when others have already demonstrated a precedent that it can be done? Firefox can even re-use the same security pattern adopted for SSL certificates that if you get into trouble you can opt-in to delegate to a less secure mode on a site.</p>
<h2 id="so-why-does-mozilla-have-to-lead" tabindex="-1">So why does Mozilla have to lead? <a class="direct-link" href="https://markalanrichards.com/posts/2018-04-08-mozilla-is-evil/#so-why-does-mozilla-have-to-lead" aria-hidden="true">#</a></h2>
<p>Because they boast of caring about privacy.</p>
<p>Sites like <a href="https://advocacy.mozilla.org/en-US">https://advocacy.mozilla.org/en-US</a> and <a href="https://www.mozilla.org/en-US/privacy/firefox/">https://www.mozilla.org/en-US/privacy/firefox/</a> boast of how they wish to defend privacy, but their flagship product fails most users.</p>
<p>Sorry, but whatever you do to cure the minority, if the majority are still suffering, then boasting about the minority is a falsehood. It's like BP boasting about it's solar energy project... great job, but they're still mostly an oil company. Firefox is still mostly a web browser business for which most of their users have their privacy breached because of the insecure design of the flagship product.</p>
<h2 id="but-they-have-private-browsing-mode-and-tracking-protection" tabindex="-1">But they have private browsing mode and tracking protection? <a class="direct-link" href="https://markalanrichards.com/posts/2018-04-08-mozilla-is-evil/#but-they-have-private-browsing-mode-and-tracking-protection" aria-hidden="true">#</a></h2>
<ul>
<li>Private browsing is designed primarily at local privacy from others users of a machine, don't confuse it. In doing so it achieved some mitigation of tracking cookies, but not saving history, searches, cookies, temporary files is quite an expensive feature set to lose that people typically would like to have because they trust their local machine, it's the remote ones they want to protect themselves from.</li>
<li>Which brings us to tracking protection that when included blocks "many" trackers.... Many? That's not enough and on notable sites including health services I've found tracking still happens and referer urls are still sent.</li>
<li>It isn't turned on by default, so for you <em>to be beter protected, your first thought after installing Firefox has to be, I don't trust Firefox to protect my privacy by default,</em> I need to configure that in and how many users think like that and then how many know what to do - (please at least install something like Privacy Badger from a very trusted source).</li>
<li>But... neither solve the problems of third party JavaScript running in the same context as the site you are using. This is a fundamental failure in the design of the web and one they acknowledge <a href="https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Security_best_practices">https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Security_best_practices</a> - so they advise devs (if you find this page), don't do it, but don't advise their users when it is happening. Show a red flag, a do you want to continue notice or something to advise people this site executes remote JS.</li>
</ul>
<h2 id="but-it-s-not-their-fault-websites-include-tracking-it-s-web-developers-who-add-this-stuff" tabindex="-1">But it's not their fault websites include tracking, it's web developers who add this stuff?# <a class="direct-link" href="https://markalanrichards.com/posts/2018-04-08-mozilla-is-evil/#but-it-s-not-their-fault-websites-include-tracking-it-s-web-developers-who-add-this-stuff" aria-hidden="true">#</a></h2>
<ul>
<li>Mozilla teach developers to add it <a href="https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Introduction">https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Introduction</a></li>
<li>Mozilla even showcase tracking happening on their own site <a href="https://developer.mozilla.org/en-US/docs/Learn/HTML/Multimedia_and_embedding/Other_embedding_technologies">https://developer.mozilla.org/en-US/docs/Learn/HTML/Multimedia_and_embedding/Other_embedding_technologies</a> ironically, whilst also describing it is a security problem</li>
<li>You have to go out of your way to then find the pages on why you shouldn't do this if you need security <a href="https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Security_best_practices">https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Security_best_practices</a> then from my experience and watching other developers, the time between learning how to add insecure features and learning how to spot and fix that is typically years... not one or two years, maybe 5-10 if you're a good developer.</li>
</ul>
<h2 id="but-you-re-blowing-this-out-of-proportion" tabindex="-1">But you're blowing this out of proportion <a class="direct-link" href="https://markalanrichards.com/posts/2018-04-08-mozilla-is-evil/#but-you-re-blowing-this-out-of-proportion" aria-hidden="true">#</a></h2>
<p>No, when Snowden blew the whistle and shouted we were all being watched, he didn't recommend Firefox, he suggested Tor browser and that was five years ago. The fundamental design of the internet was failing society and in the last five years since, Mozilla hasn't protected most of its users. It cares about them as much as maybe BP cares about clean energy.</p>
<p>I've been complaining to various companies and regulators for years about browsers leaking data. The UK regulator even blogged about my complaint <a href="https://iconewsblog.org.uk/2015/09/16/does-your-website-have-a-leak/">https://iconewsblog.org.uk/2015/09/16/does-your-website-have-a-leak/</a> as millions of users and several major sites suffered a major problem I found.</p>
<p>Since then I've started demonstrating some of the problems I've found <a href="https://www.youtube.com/channel/UCt0RTPkU-38xn5rUxZsWTig/videos">https://www.youtube.com/channel/UCt0RTPkU-38xn5rUxZsWTig/videos</a> and typically these problems boil down to URLs are leaking personal information in referer headers, tracking IDs are shared in cookies that allow cross referencing of personal information between sites to build up an identifiable tracking picture and third party JavaScript executed in the same context as same-origin scripts can perform complete account takeover and surveillance on a per user basis with little if any ability for a website to audit or realise it happening if an attack uses a little competence.</p>
<p>I'm not alone... browser based attacks are becoming more common and you only have to search Google News briefly to find things like:</p>
<ul>
<li><a href="https://www.v3.co.uk/v3-uk/news/3026428/ico-website-taken-down-after-it-was-hacked-to-spread-coinhive-monero-mining-malware">https://www.v3.co.uk/v3-uk/news/3026428/ico-website-taken-down-after-it-was-hacked-to-spread-coinhive-monero-mining-malware</a></li>
<li><a href="https://arstechnica.com/information-technology/2017/10/equifax-website-hacked-again-this-time-to-redirect-to-fake-flash-update/">https://arstechnica.com/information-technology/2017/10/equifax-website-hacked-again-this-time-to-redirect-to-fake-flash-update/</a></li>
</ul>
<p>Some aren't even attacks that were intended to be malicious:</p>
<ul>
<li><a href="https://mixpanel.com/blog/2018/02/05/update-autotrack-data-collection/">https://mixpanel.com/blog/2018/02/05/update-autotrack-data-collection/</a></li>
</ul>
<p>The businesses that use analytics, advertising and social media services are often leaking a lot of tracking data and handing over keys to their castles. Their management and often even web developers are so naive about how insecure the web is by default, they don't realise that users are at risk from what these third parties are allowed to do <em>in the browser</em>.</p>
<h2 id="so-why-is-mozilla-evil-perhaps-they-re-just-not-the-best" tabindex="-1">So why is Mozilla Evil, perhaps they're just, not the best? <a class="direct-link" href="https://markalanrichards.com/posts/2018-04-08-mozilla-is-evil/#so-why-is-mozilla-evil-perhaps-they-re-just-not-the-best" aria-hidden="true">#</a></h2>
<p>Remember they're not alone, they have company in their sins, but I'm pointing them out because people fail to and because I feel they are two faced. They are likely a lesser evil than some, but still...</p>
<p>They boast about why you should use them, because they care about privacy.</p>
<p>They boast of features that don't work properly, like tracking protection, that "mostly" works: what does mostly mean? Would you use a condom that was mostly watertight?</p>
<p>They don't inform most users. You don't know that when you visit this blog, your own computer has been used to send tracking data to various other companies... did you read my cookie policy? Do you know who's got access to this page? Are you reading what I wrote or what the analytics company JavaScript replaced it with?</p>
<h2 id="i-m-no-angel" tabindex="-1">I'm no angel <a class="direct-link" href="https://markalanrichards.com/posts/2018-04-08-mozilla-is-evil/#i-m-no-angel" aria-hidden="true">#</a></h2>
<p><em>Edit 2019/03/22: This blog is being migrated off <a href="http://wordpress.com/">wordpress.com</a> and hopefully does protect your privacy appropriately.</em></p>
<p>I'm not going to tell you this website is secure or private. Maintaining a website requires an operational overhead I feel I might get wrong and put users at a higher risk (it could get cryptojacked) and I've delegated instead to <a href="http://wordpress.com/">wordpress.com</a>. Maybe I should find something better, but the reason I'm not evil, is I'm not lying to you. I'm not pretending this site is something that it isn't and I'm not advising you to use this site in a manner that would put more users privacy at risk. Can I do better, yes, but then my comment about the risks you face when reading this blog wouldn't be possible.</p>
We need to talk about Agile2018-03-07T00:00:00Zhttps://markalanrichards.com/posts/2018-03-07-we-need-to-talk-about-agile/<p>"Agile" is not a software methodology, it is an ideology... it is built on a manifesto, that in practice is often corrupted as meaning something beyond what it states. There's too many articles on what Agile does or doesn't mean, but essentially it does demand design, process, documentation and tooling; it just suggests they should be enriched with greater attention to the functions that lead to results. It was created at at time, when you could still buy software off the shelves with user manuals that were hundreds of pages long and if it didn't work, you couldn't easily update it.</p>
<p>As an ideology it has a desired goal, which is to enable software development, but promoting ways of working that help reach functional goals. It does also tend to be a bad fit for heavily regulated environments or security conscious environments.</p>
<p>It has very obvious missing goals, it does not address non-functional requirements like compliance, performance, reliability, consistency, accessibility, maintainability, backups, ..., the list goes on.</p>
<p>Therefore, it is a an ideology to achieve a function, regardless of how well that function works in an ever changing and complex environment.</p>
<p>So what is missing and what do we need to add to or replace in Agile. I'd like to introduce two very important ideologies that we should add to Agile.</p>
<h1 id="the-right-people-we-need-expertise-not-just-devs" tabindex="-1">The Right People: we need expertise, not just devs <a class="direct-link" href="https://markalanrichards.com/posts/2018-03-07-we-need-to-talk-about-agile/#the-right-people-we-need-expertise-not-just-devs" aria-hidden="true">#</a></h1>
<p>Most devs can write great functional code based on business ideas for most logical and presentation requirements but they come unstuck when they need expertise in:</p>
<ul>
<li>Encryption</li>
<li>Information Security architecture</li>
<li>ACID /transactions</li>
<li>Deadlock and concurrency</li>
<li>Legal requirements - audit, auth, retention, access control, ...</li>
<li>Accessibility</li>
<li>...</li>
</ul>
<h2 id="an-example-encryption" tabindex="-1">An example: Encryption <a class="direct-link" href="https://markalanrichards.com/posts/2018-03-07-we-need-to-talk-about-agile/#an-example-encryption" aria-hidden="true">#</a></h2>
<p>I do not know a single software developer who can write encryption libraries, like TLS 1.2 level encryption and I include myself. I believe there are lots of mathematicians and computer scientists who could develop individual encryption functions, but combined into a framework that is secure through the whole layer, I'm not sure many can.</p>
<p>I have not met a single developer qualified to identify what encryption libraries are good or bad.</p>
<p>So why do we let software developers pick encryption libraries and configure their implementation?</p>
<p>AES 256 and RSA 4096 are surely all you need? Well, no, you'll still need to understand at least the following to use them:</p>
<ul>
<li>PRNGs</li>
<li>IVs</li>
<li>Sources of random</li>
<li>Blacklists</li>
<li>key lengths</li>
<li>key randomisation</li>
<li>key management</li>
<li>information leakage (especially dangers of using compression, caches or any other indexed data)</li>
<li>Appropriateness of re-use</li>
</ul>
<h2 id="but-our-team-is-small-and-only-average-software-developers-and-qa" tabindex="-1">But our team is small and only average software developers and QA? <a class="direct-link" href="https://markalanrichards.com/posts/2018-03-07-we-need-to-talk-about-agile/#but-our-team-is-small-and-only-average-software-developers-and-qa" aria-hidden="true">#</a></h2>
<ul>
<li>Contract expertise for design, review and testing</li>
<li>Delegate features to specialist teams (information security development)</li>
<li>Adopt a recognised standard (NIST, OWASP, WCAG, Mozilla recommends server sidde encryption configurations, etc)</li>
<li>Adopt a recognised library/application: but does the proprietary or open source library guarantee standards met to help choose adoption? You should probably avoid hashids.</li>
<li>Adopt a recognised service: cloud services mean everything except your business logic can likely be bought as a service, so why not do that: then it is someone else's responsibility... just have <a href="https://ico.org.uk/media/for.../cloud_computing_guidance_for_organisations.pdf">fun making sure the cloud is appropriate</a>.</li>
<li>Alternatively, don't do it - if a small building firm can't build a skyscraper it will find something else to do - some things are not supposed to be done by small teams and startups. Is the business value really there, is it worth employing specialist help? If the business value doesn't warrant the expertise, then it probably isn't valuable enough to be worth doing.</li>
</ul>
<h1 id="maintenance-it-isn-t-just-bugs" tabindex="-1">Maintenance: it isn't just bugs <a class="direct-link" href="https://markalanrichards.com/posts/2018-03-07-we-need-to-talk-about-agile/#maintenance-it-isn-t-just-bugs" aria-hidden="true">#</a></h1>
<p>Agile typically does cater for bug fixing, but maintenance is more than that.</p>
<ul>
<li>Legal changes</li>
<li>Vulnerability management</li>
<li>Licences end, projects die</li>
</ul>
<p>With GDPR arriving soon, hopefully everyone is reviewing all systems that hold, transport and ... access PII. However, it's not just GDPR that is and has been changing, especially in more regulated environments with PCI, MIFID, GCP, Accessibility law, etc often have amendments too. Contracts with third parties typically demand levels of security that must be adhered to as well. Some of these changes are passive (you have to discover a legal change) and some are active (you are told of a contractual change) but both need to cycle into the maintenance of what would otherwise be ignored code running in production.</p>
<p>Access is actually a really worrying problem. Many systems are setup with walls at perimeter, but not inside. So the web frontends and web api gates into the system are typically offered some lifecycle management to check for greater maintenance risks, but the other services can be just as dangerous.</p>
<p>XXE, Remote Code Execution (reflection, SQL, etc) and even internal tooling are all often one step away from attackers and that step might not be designed to worry about the concern.</p>
<p>The last concern is licences and discovering that your licence for proprietary software can leave you in a legal dilemma (do you shutdown to respect the licence or steal some more time, hopefully only to migrate or negotiate renewal) or that the open source project you use has died... do you take a risk and continue with unsupported and increasingly likely vulnerable software or refactor off. To do the right thing means knowing about it.</p>
<h2 id="this-requires-audit" tabindex="-1">This requires audit <a class="direct-link" href="https://markalanrichards.com/posts/2018-03-07-we-need-to-talk-about-agile/#this-requires-audit" aria-hidden="true">#</a></h2>
<p>Where is audit mentioned in the Agile manifesto?</p>
<p>Audit is a function of all business environments have and whether it is a legally qualified audit, like an accountancy audit or regulatory audit for compliance that has a high process demand or whether it is a just a regular check, like are the toilets clean with a tickbox to fill, it happens everywhere... except so much in software development.</p>
<p>How do you check your toilets are clean in your website in production? Sounds a bit strange, but how many of us are testing for vulnerabilities, reviewing log cleanliness, etc. We might be doing the functional parts that we know will break the application: is the server running, does the database have disk space... but beyond that too many places have security problems or even embarrassingly suffer problems like their TLS certificates expiring... when that happens, it is not a failure of the dev/ops who set it up, it is a failure of the business to have a business control around it.</p>
<p>So we might clean the toilets with a quarterly automated penetration test, alarms when the disk levels are high and a Jira scheduled ticket (why doesn't that exist?) for renewing the TLS certs, but what about the other layers of audit.</p>
<ul>
<li>What about the full stock take? Double check everything is correct and proper annually?</li>
<li>The expired goods? Third party software validation of not just CVEs but that there still is support from the third party</li>
<li>The health and safety risk assessments? Still in their early days, privacy impact assessments are becoming part of software development, but many still don't do them and are they maintained on a lifecycle basis or on a first release basis? Are the requirements drawn out from them validated?</li>
</ul>
<p>As a lifecycle event it should be driven by business controls, which means they know what to control and that requires documentation, which is fine in Agile, Agile only really demanded you didn't write thousand page usage manuals like you used to get with software in the 90s (okay, some were only 600 pages).</p>
<p>This is the key reason why Agile Software Development fails as a project management methodology alone: the business behaviours demanded are always changing and yet the project leaves features dead in Jira: with just bug fixing idling along until a new feature is demanded.</p>
NPM is lying to you and Facebook misses copyright attribution2017-01-14T00:00:00Zhttps://markalanrichards.com/posts/2017-01-14-npm-is-lying-to-you-and-facebook-misses-copyright-attribution/<p>Update: Originally titled "NPM is lying to you and Facebook is stealing copyright" I've amended it out of respect to those who weren't happy with this, but this error should reflect on Facebook audit processes (due diligence) of copyright attribution, which would hopefully have caught this. Regarding concerns about attribution to Mozilla in the issue (<a href="https://github.com/facebook/react/issues/8789">https://github.com/facebook/react/issues/8789</a>) I think there is a misrepresentation of CC0/dedicated to public domain in the comments: it is not the same as copyright expiry and it's important that the rights holder (which I believe is still Mozilla) is tracked by Facebook even if not attributed in published bundles. If nobody tracked that <a href="http://obect.is/">Obect.is</a> came from Mozilla, then when the page goes, the first to copy the page can sue everyone.</p>
<p>Firstly, copyright is complicated and getting this right is difficult and I don't believe that the npm website is trying to lie to you, but that some of the projects on there are (hopefully accidentally) doing so.</p>
<p>No billion dollar company has the right to get this wrong and they should all be running regular audits, but even they might slip up and if they do, <a href="http://www.groklaw.net/">SCO vs open source</a> and <a href="https://news.ycombinator.com/item?id=11722514">Google's 9 lines</a> were painful moments, so if they could lead by example it would be great. I do hope everyone believes individual developers should be given a little room on accuracy in this domain, we're unlikely to be lawyers, but if you do spot this kind of thing... please please please let the parties affected know in a respectful fashion that allows them to resolve it sooner rather than later, it is one thing to slip up for a short period of time and another as it gets longer: the longer it is left without resolution, the more dependent projects that might be affected too.</p>
<p>When you look at the licences in a library in npm, you think great it is Apache, BSD, MIT, etc and I can probably use it pretty freely.</p>
<p>When it's LGPL, GPL, AGPL or EPL it gets more complicated, but may not be impossible... it might even be okay if you wish to adopt these.</p>
<p>Well, those licences aren't complete in npm for many libraries. Partly because of wonderful technologies like webpack that bundle your code with your dependent code, but don't, by default, facilitate creating a combined licence file in the process.</p>
<p>npm isn't the only party getting this wrong, too many open source tools encourage you to label a project as one licence, when in truth it is more likely that your project's direct code is one licence, but when packaged it is a multi-licence project.</p>
<p>To make matters more complicated, some source code repositories include third party code directly in their source repository (perhaps because it isn't available from the repository they choose for the project, like npm) and this results in the source code repository itself being mixed licence... how do I fit that in the Github licence option?</p>
<p>If you publish code that is a mix of others work, including in a bundle or even as just accompanying assets, please ensure that the licences are published too. At least we don't have to make <a href="http://moba.i.daimler.com/bai-cars/ba/foss/content/en/licence_agreement.html">printable booklets</a> to ship with physical products.</p>
<h1 id="react" tabindex="-1"><a href="https://facebook.github.io/react/">react</a> <a class="direct-link" href="https://markalanrichards.com/posts/2017-01-14-npm-is-lying-to-you-and-facebook-misses-copyright-attribution/#react" aria-hidden="true">#</a></h1>
<p>Facebook is a big multinational software company. They obviously know about copyright law in their legal teams.</p>
<p>Well they've missed something... their current version of the <a href="https://facebook.github.io/react/">React</a> website uses this wonderful JavaScript <a href="https://facebook.github.io/react/js/react.js">file</a> which is full of copyright statements about Facebook, but none for third party libraries.</p>
<p>Hmm... strange, their <a href="https://www.npmjs.com/package/react">library</a> has dependencies on <a href="https://www.npmjs.com/package/object-assign">object-assign</a> (amongst others).</p>
<p>Let's npm install it and see what's in the dist folder. There's a basic react.min.js file and there's an <a href="https://facebook.github.io/react/docs/addons.html">add-ons</a> one that's also available online at the version I'm seeing locally: <a href="https://unpkg.com/react@15.4.2/dist/react-with-addons.js">15.4.2</a></p>
<p>Strange, again it only has Facebook copyright in, but no third parties.</p>
<p>Their add-ons page doesn't exactly tell you about the embedded object-assign copyright <a href="https://github.com/sindresorhus/object-assign/blob/master/license">licence</a> which is MIT and requires that if you include object-assign in your own works you need to include their MIT licence with it so that users know that parts of the React software include object-assign.</p>
<p>Bad Facebook, not only breaching copyright, but as developers often use them as a reference for how to build web pages, they risk setting a bad example for how to manage copyright. Their legal team should be on top this, ensuring a regular audit happens and helping to oversee it.</p>
<p>They have a similar <a href="https://github.com/facebook/draft-js/issues/944">issue</a> with <a href="https://facebook.github.io/draft-js/">Draft.js</a></p>
<h1 id="jsrsasign" tabindex="-1"><a href="https://github.com/kjur/jsrsasign">jsrsasign</a> <a class="direct-link" href="https://markalanrichards.com/posts/2017-01-14-npm-is-lying-to-you-and-facebook-misses-copyright-attribution/#jsrsasign" aria-hidden="true">#</a></h1>
<p>I spotted jsrsasign did this, but I've seen it before. Sorry to out jsrsasign, it looks like a great project... Javascript encryption enables client-side private keys and object level security instead of passwords over only network level https (mutual auth is great for your enterprises' servers, but isn't catching on for the open web).</p>
<p>Make sure you understand encryption export law if you wish to use it, I won't pretend I know enough to offer advice and <a href="https://www.thoughtworks.com/insights/blog/encryption-open-source-and-export-control">ThoughtWorks</a> have been good enough to offer some, but <em><strong>you should check with a legal expert</strong></em> .</p>
<p>This has a hidden <a href="https://github.com/kjur/jsrsasign/tree/master/ext">ext</a> folder when attempting to determine how to reference open source licences that you would need to publish with your end product, because this isn't referenced in npm. I think it can be, but unluckily jsrsasign haven't yet... hopefully they will soon.</p>
Complex Primitives2016-10-30T00:00:00Zhttps://markalanrichards.com/posts/2016-10-30-complex-primitives/<p>I have a crazy idea: create a cross-platform language, no not Java: something better. Primitives are supposed to the simplest form of data in a programming language. So how hard can it be to work with them...</p>
<h1 id="typical-representations" tabindex="-1">Typical representations <a class="direct-link" href="https://markalanrichards.com/posts/2016-10-30-complex-primitives/#typical-representations" aria-hidden="true">#</a></h1>
<ul>
<li>References (pointers)</li>
<li>Boolean</li>
<li>Integer numbers</li>
<li>Floating point numbers (binary and sometimes decimal)</li>
<li>Primitive structures (array, list)</li>
<li>Character(s)</li>
</ul>
<h1 id="boolean-is-complex" tabindex="-1">Boolean is complex <a class="direct-link" href="https://markalanrichards.com/posts/2016-10-30-complex-primitives/#boolean-is-complex" aria-hidden="true">#</a></h1>
<p>In typical computing systems, everything is a 0 or a 1, except usually nothing is.</p>
<p>CPUs typically look at numbers at bit sets of length 8, 16, 32 or 64: not usually 1.</p>
<p>Although most have somewhere that this doesn't hold true, either with longer primitive sizes (128/256), special floating point versions (56, 80, ...) or slightly weird 31 bitset sizes (bad IBM).</p>
<p>The easiest way to manage boolean is to choose 0 as true or false (often false) and anything else as the opposite. However, what size of bitset do you use? If you use the defacto int then it might be different in different compilers (32bit vs 64bit).</p>
<p>Luckily, all you need to know is the size of the bitset and the offset in memory.</p>
<h1 id="integer-is-much-more-complex" tabindex="-1">Integer is much more complex <a class="direct-link" href="https://markalanrichards.com/posts/2016-10-30-complex-primitives/#integer-is-much-more-complex" aria-hidden="true">#</a></h1>
<p>So boolean is an offset in ram and a size of the bitset to use: all 0s then it's false and anything else it is true.</p>
<p>Integers share the problem that you need to know the size of the bitset, but suffer a further problem: order and signing.</p>
<p>The signed number part is simple: a bit is reserved at the most significant bit to be used for representing positive (zero) or negative (1: with 2s complement), but order gets complex..</p>
<h1 id="bits-and-byte-ordering" tabindex="-1">Bits and Byte Ordering <a class="direct-link" href="https://markalanrichards.com/posts/2016-10-30-complex-primitives/#bits-and-byte-ordering" aria-hidden="true">#</a></h1>
<p>So what is order: well that "most significant bit" is the problem. Endian of bits and bytes comes into play (and they're not always the same as each other).</p>
<p>The order of bits varies between processors and usually this problem is something that is more likely to affect you at a very low level (drivers, hardware, etc): to make it more fun most computers have more than one cpu. Your sound card, graphics card, network card, etc might all see bits a different way around: nevermind the busses.</p>
<p>At the software level you usually find everything is the same (let me know if I've got this wrong), but here you suffer byte order differences where different protocols (network, inter-process, file formats) can each represent things larger than a byte in different order. This isn't too difficult to solve (<a href="https://github.com/markalanrichards/bitcoin/blob/master/src/compat/byteswap.h">https://github.com/markalanrichards/bitcoin/blob/master/src/compat/byteswap.h</a>) you just need to remember to use it everywhere your program interfaces with the world.</p>
<h1 id="floating-points" tabindex="-1">Floating Points <a class="direct-link" href="https://markalanrichards.com/posts/2016-10-30-complex-primitives/#floating-points" aria-hidden="true">#</a></h1>
<p>Luckily floating points are strictly described in IEEE-754, well I say luckily: except the complexities of implementing it mean that not all languages actually adhere to it: <a href="https://en.wikipedia.org/wiki/Criticism_of_Java#Floating_point_arithmetic">https://en.wikipedia.org/wiki/Criticism_of_Java#Floating_point_arithmetic</a></p>
<h1 id="characters" tabindex="-1">Characters <a class="direct-link" href="https://markalanrichards.com/posts/2016-10-30-complex-primitives/#characters" aria-hidden="true">#</a></h1>
<p>Characters and Strings are terrifying.</p>
<p>There are hundreds (maybe thousands) of character sets: in a large part because some base character sets (Latin1) have multiple versions for different languages. Not all are easy to work with (I remember something odd about Turkish EBCDIC and xml processing problems as symbols can be remapped). The simplest solution is to make everyone fit into a box and force UTF-8: then hope that nobody adds a BOM, let's hope UTF-8 never gets deprecated.</p>
<h1 id="references" tabindex="-1">References <a class="direct-link" href="https://markalanrichards.com/posts/2016-10-30-complex-primitives/#references" aria-hidden="true">#</a></h1>
<p>So you have a reference to some data.... how do you reference it and what kind of data might you have to reference:</p>
<p>The reference could be a nice compile time fixed size (like a pair of integers, I mean a pair of 64 bit integers).</p>
<p>It might be a variable size (String of characters) holding some JSON: so maybe a block of memory.</p>
<p>Or it might be a continuous stream (/dev/urandom)</p>
<p>Or it might be a channel of offset data (File on disk) with parts that might no longer be available later in the day or new parts that arrive whilst reading.</p>
<p>It's easiest to manage the fixed size case (c style) and then re-use the fixed size blocks for streams of data, but sometimes you need more complex references like File handles.</p>
<p>So a VLQ (<a href="https://en.wikipedia.org/wiki/Variable-length_quantity">https://en.wikipedia.org/wiki/Variable-length_quantity</a>) might do for the simple case, and then a VLQ that contains References to further VLQs might be usable for the rest of the use cases.</p>
<h1 id="arrays-and-lists" tabindex="-1">Arrays and Lists <a class="direct-link" href="https://markalanrichards.com/posts/2016-10-30-complex-primitives/#arrays-and-lists" aria-hidden="true">#</a></h1>
<p>I don't think I really consider these to be primitive types</p>
<p>Great, I don't need to write these in my language: I can borrow them? Well maybe, except when it comes to mixing primitives with polymorphic types: well maybe I can still use them I guess I can just put the type into the box as the first entry.</p>
<h1 id="it-s-all-in-the-bus" tabindex="-1">It's all in the bus <a class="direct-link" href="https://markalanrichards.com/posts/2016-10-30-complex-primitives/#it-s-all-in-the-bus" aria-hidden="true">#</a></h1>
<p>Eventually, much of the data you use ends up moving through the buses on your system and they have different sizes and then on top of that you get fixed sized pages that move over buses, which you hope are an integer multiple of the bus size: typically the one everyone knows that isn't is the MTU (which varies between broadband, ethernet and modem systems).</p>
<p>So when you use these complex primitives you might not want to just use the language primitives: but optimise for the bus/packet/page sizes involved. Should these be primitives? Well that might depend on your architecture and for a cross platform language I guess you should let it be a language specific optimization to curry in an outside primitive.</p>
<h1 id="so-how-to-solve-this-for-writing-a-new-language" tabindex="-1">So how to solve this for writing a new language? <a class="direct-link" href="https://markalanrichards.com/posts/2016-10-30-complex-primitives/#so-how-to-solve-this-for-writing-a-new-language" aria-hidden="true">#</a></h1>
<p>Copy Scala and Groovy: use the JVM to solve this for you and give you a consistent view of the world and force everyone to map using Java data structure until later... although I'm tempted to checkout the CLR/Mono too.</p>
Keeping in Time2016-09-11T00:00:00Zhttps://markalanrichards.com/posts/2016-09-11-keeping-in-time/<p>Now it is 15:31 on the 11-09-2016 and I'm in London.</p>
<h2 id="writing-and-reading-dates" tabindex="-1">Writing and Reading dates <a class="direct-link" href="https://markalanrichards.com/posts/2016-09-11-keeping-in-time/#writing-and-reading-dates" aria-hidden="true">#</a></h2>
<p>Always use the order or full year, month then day of month.</p>
<ul>
<li>Text ordering is now time ordered
<ul>
<li>2016-06-06 is always after 2015-06-07 in text and time</li>
<li>06-07-2016 is before 07-06-2015 and after 05-06-2014 in text ordering, but not in time.</li>
<li>This useful in table ordering, like when listing files.</li>
</ul>
</li>
<li>Local differences don't matter so much (Europe vs USA format)</li>
</ul>
<h2 id="offset-time" tabindex="-1">Offset Time <a class="direct-link" href="https://markalanrichards.com/posts/2016-09-11-keeping-in-time/#offset-time" aria-hidden="true">#</a></h2>
<p>The UK has British Summer Time, so that time point is 1 hour ahead of where it should be, so the time is actually 2016-09-11T15:31:00+01:00 (in ISO 8601 format).</p>
<h2 id="zoned-time" tabindex="-1">Zoned Time <a class="direct-link" href="https://markalanrichards.com/posts/2016-09-11-keeping-in-time/#zoned-time" aria-hidden="true">#</a></h2>
<p>If I asked you to call me at this time in 6 months, I might not appreciate a call at 2017-03-11T15:31:00+01:00 because I'm then out of Daylight Savings, so instead it's useful to capture the time zone.</p>
<p>Like this, 2017-03-11T15:31:00 [Europe/London] where Europe/London is an official (designation)[<a href="https://en.wikipedia.org/wiki/List_of_tz_database_time_zones">https://en.wikipedia.org/wiki/List_of_tz_database_time_zones</a>] of my time zone. Except this isn't quite good enough...</p>
<p>What if I wanted a call at 2am on 29th of October, 2017?</p>
<p>2017-10-29T02:00:00 [Europe/London] happens twice and so to be as distinct as possible then perhaps 2017-10-29T02:00:00+00:00 [Europe/London] and 2017-10-29T02:00:00+01:00 [Europe/London] would be enough to know which is which.</p>
<h2 id="gps-time-is-ordered" tabindex="-1">GPS Time is ordered? <a class="direct-link" href="https://markalanrichards.com/posts/2016-09-11-keeping-in-time/#gps-time-is-ordered" aria-hidden="true">#</a></h2>
<p>Be wary of using GPS time. Although GPS time is an unadjusted series of seconds since a point in time, will it always be so? It's use case is for positioning and if there ever were a need, I would guess adjusting time to fix positioning would be preferred to adjusting positioning to fix time.</p>
<h2 id="use-tai-time-when-you-need-time-order-or-better-use-incrementing-ids" tabindex="-1">Use TAI time when you need time order or better use incrementing ids. <a class="direct-link" href="https://markalanrichards.com/posts/2016-09-11-keeping-in-time/#use-tai-time-when-you-need-time-order-or-better-use-incrementing-ids" aria-hidden="true">#</a></h2>
<p>You want to know about the series of events, such as, in a server log or transaction log.</p>
<p>The problem is UTC goes back in time and as Unix time typically uses UTC, your logs will too. <a href="https://en.wikipedia.org/wiki/Unix_time">https://en.wikipedia.org/wiki/Unix_time</a></p>
<p>But, it doesn't have to be this way: TAI time is ordered and not affected by adjustments to keep time in order with our solar cycle, so no leap seconds... that doesn't mean there aren't adjustments, but the adjustments should be such much smaller fractions of a second.</p>
<p>But, even with TAI, that fraction of a second can still get bigger: you don't poll NTP at a rate of a fraction of a second and PC clocks fall out of sync and on VMs sometimes more than expected.</p>
<p>So why not just use an incrementing counter? The order of log lines effectively does this, but assumes that they are written in order and kept in order, so I guess the question here is now that you aggregate your log files to central servers (Splunk, Logstash, etc) are they still in order of events or are they in order of adjustable time stamps.Summary</p>
<ul>
<li>For everyday usage use a Zoned Offset
<ul>
<li>1999-12-31T23:59:59-04:00 [America/New_York]</li>
</ul>
</li>
<li>For scientific calculations use TAI, but how to distinguish from UTC?
<ul>
<li>2017-03-11T14:31:36</li>
</ul>
</li>
<li>For strict ordering of events, don't use time: but keep a reference for indexing (finding the log lines)</li>
</ul>
ICO has no powers over webcams2016-09-02T00:00:00Zhttps://markalanrichards.com/posts/2016-09-02-ico-has-no-powers-over-webcams/<p><a href="https://web.archive.org/web/20150913003517/https://ico.org.uk/media/1043287/ico-letter-to-webcam-manufacturers.pdf">ICO published a letter to Webcam manufacturers...</a> well you don't have to pay much attention to it if you are one.</p>
<p><a href="https://www.eff.org/deeplinks/2015/11/superfish-20-now-dell-breaking-https">Dell decided to break https encryption on their laptops by installed a vulnerable root certificate.</a></p>
<p>If you run a business and store personal data, you must go through heaps of hoops to ensure you are compliant with data protection law. But the manufacturer of the server, network equipment and laptops you have to use has no requirements: so they can be as insecure as they like and you pick up the bill when the ICO chases down their breach.</p>
<div style="font-style: italic">
<blockquote>
<h2 id="case-reference-number-rfa0606701" tabindex="-1">Case Reference Number RFA0606701 <a class="direct-link" href="https://markalanrichards.com/posts/2016-09-02-ico-has-no-powers-over-webcams/#case-reference-number-rfa0606701" aria-hidden="true">#</a></h2>
<p>I write in relation to your concerns about Dell’s new equipment security fault, about which my colleague has previously responded to you.</p>
<p>The DPA works by placing obligations on organisations that hold personal information. The DPA does not however place any obligations on the manufacturers of equipment that may be used for storing personal information.</p>
<p>The security requirement of the DPA (the seventh data protection principle) requires an organisation holding personal data to have adequate technical and organisational measures in place to protect the personal data (taking account of the nature of the information being held, the availability of technology, and the cost of implementing those measures).</p>
<p>As such, an organisation that has purchased Dell equipment subject to the fault for the storage of personal data may be contravening the DPA if they have failed to keep personal data secure as a result of their use of insecure equipment for the storage of personal data.</p>
<p>Dell is not contravening any requirements of the DPA by selling insecure equipment. The DPA does not, in any way, require suppliers of equipment to ensure their products are secure. The obligations arising from the DPA are for organisations using the equipment for the storage of personal data.</p>
<p>Because our powers are specific to the DPA there is therefore no punitive or other action we can take against Dell over its failure to sell secure computer equipment.</p>
</blockquote>
</div>
CompletableFuture does it block2016-06-22T00:00:00Zhttps://markalanrichards.com/posts/2016-06-22-completablefuture-does-it-block/<h2 id="what-happens-with-this-full-code-below" tabindex="-1">What happens with this (full code below)? <a class="direct-link" href="https://markalanrichards.com/posts/2016-06-22-completablefuture-does-it-block/#what-happens-with-this-full-code-below" aria-hidden="true">#</a></h2>
<pre class="language-java"><code class="language-java"> <span class="token annotation punctuation">@Test</span><br /> <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">obviouslySecondFirst</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><br /> <span class="token function">allOf</span><span class="token punctuation">(</span><br /> <span class="token function">supplyAsync</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">-></span> first<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">thenAccept</span><span class="token punctuation">(</span><span class="token function">addDelayed</span><span class="token punctuation">(</span>concurrentLinkedQueue<span class="token punctuation">,</span> delay<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span><br /> <span class="token function">supplyAsync</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">-></span> second<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">thenAccept</span><span class="token punctuation">(</span>concurrentLinkedQueue<span class="token operator">::</span><span class="token function">add</span><span class="token punctuation">)</span><br /> <span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">join</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token function">assertThat</span><span class="token punctuation">(</span><span class="token function">copyOf</span><span class="token punctuation">(</span>concurrentLinkedQueue<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">equalTo</span><span class="token punctuation">(</span><span class="token function">of</span><span class="token punctuation">(</span>second<span class="token punctuation">,</span> first<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span></code></pre>
<p><em>This will randomly swap between returning ["second","first"] and ["first","second"] and therefore, randomly block second</em></p>
<h2 id="repeat-it" tabindex="-1">Repeat it... <a class="direct-link" href="https://markalanrichards.com/posts/2016-06-22-completablefuture-does-it-block/#repeat-it" aria-hidden="true">#</a></h2>
<pre class="language-java"><code class="language-java"> <span class="token annotation punctuation">@Test</span><br /> <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">obviouslySecondFirstWithWaitBeforeCall</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><br /> <span class="token keyword">final</span> <span class="token class-name">CompletableFuture</span><span class="token generics"><span class="token punctuation"><</span><span class="token class-name">String</span><span class="token punctuation">></span></span> suppliedFirst <span class="token operator">=</span> <span class="token function">supplyAsyncFirst</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token function">delay</span><span class="token punctuation">(</span>delay<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token function">allOf</span><span class="token punctuation">(</span><br /> suppliedFirst<span class="token punctuation">.</span><span class="token function">thenAccept</span><span class="token punctuation">(</span><span class="token function">addDelayed</span><span class="token punctuation">(</span>concurrentLinkedQueue<span class="token punctuation">,</span> delay<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span><br /> <span class="token function">supplyAsyncSecond</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">thenAccept</span><span class="token punctuation">(</span>concurrentLinkedQueue<span class="token operator">::</span><span class="token function">add</span><span class="token punctuation">)</span><br /> <span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">join</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token function">assertThat</span><span class="token punctuation">(</span><span class="token function">copyOf</span><span class="token punctuation">(</span>concurrentLinkedQueue<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">equalTo</span><span class="token punctuation">(</span><span class="token function">of</span><span class="token punctuation">(</span>second<span class="token punctuation">,</span> first<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /><span class="token punctuation">}</span></code></pre>
<p><em>This is a bad design!</em></p>
<p>If the methods were split between two classes (AsyncCompletableFuture and SyncCompletableFuture) then I might forgive this as I could easily code review the differences, but they're all thrown in the same one.</p>
<p>To make matters worse, some methods don't explicitely have an async option.</p>
<p>So there's a method exceptionally(), but no exceptionallyAsync(), will that block when you do supplyAsync(()->x).exceptionally(t->blockingLogging(t))?</p>
<h2 id="confusing-chaining" tabindex="-1">Confusing chaining <a class="direct-link" href="https://markalanrichards.com/posts/2016-06-22-completablefuture-does-it-block/#confusing-chaining" aria-hidden="true">#</a></h2>
<pre class="language-java"><code class="language-java"> <span class="token annotation punctuation">@Test</span><br /> <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">secondsecondShouldBeFirstFirst</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><br /> <span class="token function">allOf</span><span class="token punctuation">(</span><br /> <span class="token function">supplyAsync</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">-></span> first<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">thenApply</span><span class="token punctuation">(</span><span class="token function">addDelayed</span><span class="token punctuation">(</span>concurrentLinkedQueue<span class="token punctuation">,</span> delay <span class="token operator">*</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">thenApply</span><span class="token punctuation">(</span><span class="token function">addDelayed</span><span class="token punctuation">(</span>concurrentLinkedQueue<span class="token punctuation">,</span> delay <span class="token operator">*</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span><br /> <span class="token function">supplyAsync</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">-></span> second<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">thenApply</span><span class="token punctuation">(</span><span class="token function">addDelayed</span><span class="token punctuation">(</span>concurrentLinkedQueue<span class="token punctuation">,</span> delay<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">thenApply</span><span class="token punctuation">(</span><span class="token function">addDelayed</span><span class="token punctuation">(</span>concurrentLinkedQueue<span class="token punctuation">,</span> delay <span class="token operator">*</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">join</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token function">assertThat</span><span class="token punctuation">(</span><span class="token function">copyOf</span><span class="token punctuation">(</span>concurrentLinkedQueue<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">equalTo</span><span class="token punctuation">(</span><span class="token function">of</span><span class="token punctuation">(</span>second<span class="token punctuation">,</span> second<span class="token punctuation">,</span> first<span class="token punctuation">,</span> first<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span></code></pre>
<p><em>This will randomly block and randomly not: sometimes returning [first,first,second,second] and sometimes [second,first,second,first]</em></p>
<h2 id="the-code" tabindex="-1">The code ... <a class="direct-link" href="https://markalanrichards.com/posts/2016-06-22-completablefuture-does-it-block/#the-code" aria-hidden="true">#</a></h2>
<pre class="language-java"><code class="language-java"><span class="token keyword">package</span> <span class="token namespace">com<span class="token punctuation">.</span>example</span><span class="token punctuation">;</span><br /><br /><span class="token keyword">import</span> <span class="token keyword">static</span> <span class="token import static"><span class="token namespace">java<span class="token punctuation">.</span>util<span class="token punctuation">.</span>concurrent<span class="token punctuation">.</span></span><span class="token class-name">CompletableFuture</span><span class="token punctuation">.</span><span class="token static">allOf</span></span><span class="token punctuation">;</span><br /><span class="token keyword">import</span> <span class="token keyword">static</span> <span class="token import static"><span class="token namespace">java<span class="token punctuation">.</span>util<span class="token punctuation">.</span>concurrent<span class="token punctuation">.</span></span><span class="token class-name">CompletableFuture</span><span class="token punctuation">.</span><span class="token static">supplyAsync</span></span><span class="token punctuation">;</span><br /><span class="token keyword">import</span> <span class="token keyword">static</span> <span class="token import static"><span class="token namespace">java<span class="token punctuation">.</span>util<span class="token punctuation">.</span>concurrent<span class="token punctuation">.</span></span><span class="token class-name">TimeUnit</span><span class="token punctuation">.</span><span class="token static">SECONDS</span></span><span class="token punctuation">;</span><br /><span class="token keyword">import</span> <span class="token keyword">static</span> <span class="token import static"><span class="token namespace">org<span class="token punctuation">.</span>eclipse<span class="token punctuation">.</span>collections<span class="token punctuation">.</span>api<span class="token punctuation">.</span>factory<span class="token punctuation">.</span></span><span class="token class-name">Lists</span><span class="token punctuation">.</span><span class="token static">immutable</span></span><span class="token punctuation">;</span><br /><span class="token keyword">import</span> <span class="token keyword">static</span> <span class="token import static"><span class="token namespace">org<span class="token punctuation">.</span>hamcrest<span class="token punctuation">.</span></span><span class="token class-name">MatcherAssert</span><span class="token punctuation">.</span><span class="token static">assertThat</span></span><span class="token punctuation">;</span><br /><span class="token keyword">import</span> <span class="token keyword">static</span> <span class="token import static"><span class="token namespace">org<span class="token punctuation">.</span>hamcrest<span class="token punctuation">.</span></span><span class="token class-name">Matchers</span><span class="token punctuation">.</span><span class="token static">equalTo</span></span><span class="token punctuation">;</span><br /><br /><span class="token keyword">import</span> <span class="token import"><span class="token namespace">java<span class="token punctuation">.</span>util<span class="token punctuation">.</span>concurrent<span class="token punctuation">.</span></span><span class="token class-name">CompletableFuture</span></span><span class="token punctuation">;</span><br /><span class="token keyword">import</span> <span class="token import"><span class="token namespace">java<span class="token punctuation">.</span>util<span class="token punctuation">.</span>concurrent<span class="token punctuation">.</span></span><span class="token class-name">ConcurrentLinkedQueue</span></span><span class="token punctuation">;</span><br /><span class="token keyword">import</span> <span class="token import"><span class="token namespace">java<span class="token punctuation">.</span>util<span class="token punctuation">.</span>function<span class="token punctuation">.</span></span><span class="token class-name">Function</span></span><span class="token punctuation">;</span><br /><span class="token keyword">import</span> <span class="token import"><span class="token namespace">java<span class="token punctuation">.</span>util<span class="token punctuation">.</span>function<span class="token punctuation">.</span></span><span class="token class-name">Supplier</span></span><span class="token punctuation">;</span><br /><span class="token keyword">import</span> <span class="token import"><span class="token namespace">org<span class="token punctuation">.</span>eclipse<span class="token punctuation">.</span>collections<span class="token punctuation">.</span>api<span class="token punctuation">.</span>list<span class="token punctuation">.</span></span><span class="token class-name">ImmutableList</span></span><span class="token punctuation">;</span><br /><span class="token keyword">import</span> <span class="token import"><span class="token namespace">org<span class="token punctuation">.</span>junit<span class="token punctuation">.</span>jupiter<span class="token punctuation">.</span>api<span class="token punctuation">.</span></span><span class="token class-name">Test</span></span><span class="token punctuation">;</span><br /><br /><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">SupplyItAsyncMaybeTest</span> <span class="token punctuation">{</span><br /> <span class="token keyword">private</span> <span class="token keyword">void</span> <span class="token function">delay</span><span class="token punctuation">(</span><span class="token keyword">int</span> seconds<span class="token punctuation">)</span> <span class="token punctuation">{</span><br /> <span class="token keyword">try</span> <span class="token punctuation">{</span><br /> SECONDS<span class="token punctuation">.</span><span class="token function">sleep</span><span class="token punctuation">(</span>seconds<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span><span class="token class-name">InterruptedException</span> e1<span class="token punctuation">)</span> <span class="token punctuation">{</span><br /> e1<span class="token punctuation">.</span><span class="token function">printStackTrace</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /><br /> <span class="token keyword">static</span> <span class="token generics"><span class="token punctuation"><</span><span class="token class-name">T</span><span class="token punctuation">></span></span> <span class="token class-name">ImmutableList</span><span class="token generics"><span class="token punctuation"><</span><span class="token operator">?</span> <span class="token keyword">extends</span> <span class="token class-name">T</span><span class="token punctuation">></span></span> <span class="token function">ofAll</span><span class="token punctuation">(</span><span class="token class-name">Iterable</span><span class="token generics"><span class="token punctuation"><</span><span class="token operator">?</span> <span class="token keyword">extends</span> <span class="token class-name">T</span><span class="token punctuation">></span></span> ts<span class="token punctuation">)</span> <span class="token punctuation">{</span><br /> <span class="token keyword">return</span> immutable<span class="token punctuation">.</span><span class="token function">ofAll</span><span class="token punctuation">(</span>ts<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /><br /> <span class="token keyword">static</span> <span class="token generics"><span class="token punctuation"><</span><span class="token class-name">T</span><span class="token punctuation">></span></span> <span class="token class-name">ImmutableList</span><span class="token generics"><span class="token punctuation"><</span><span class="token class-name">T</span><span class="token punctuation">></span></span> <span class="token function">of</span><span class="token punctuation">(</span><span class="token class-name">T</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span> ts<span class="token punctuation">)</span> <span class="token punctuation">{</span><br /> <span class="token keyword">return</span> immutable<span class="token punctuation">.</span><span class="token function">of</span><span class="token punctuation">(</span>ts<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /><br /> <span class="token keyword">final</span> <span class="token class-name">String</span> first <span class="token operator">=</span> <span class="token string">"first"</span><span class="token punctuation">,</span> second <span class="token operator">=</span> <span class="token string">"second"</span><span class="token punctuation">;</span><br /> <span class="token keyword">final</span> <span class="token keyword">int</span> delay <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">;</span><br /> <span class="token keyword">final</span> <span class="token class-name">ConcurrentLinkedQueue</span><span class="token generics"><span class="token punctuation"><</span><span class="token class-name">String</span><span class="token punctuation">></span></span> concurrentLinkedQueue <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">ConcurrentLinkedQueue</span><span class="token generics"><span class="token punctuation"><</span><span class="token punctuation">></span></span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /><br /> <span class="token keyword">private</span> <span class="token class-name">Supplier</span><span class="token generics"><span class="token punctuation"><</span><span class="token class-name">String</span><span class="token punctuation">></span></span> <span class="token function">supplyFirstAfterDelay</span><span class="token punctuation">(</span><span class="token keyword">int</span> seconds<span class="token punctuation">,</span> <span class="token keyword">final</span> <span class="token class-name">String</span> initalValue<span class="token punctuation">)</span> <span class="token punctuation">{</span><br /> <span class="token keyword">return</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">-></span> <span class="token punctuation">{</span><br /> <span class="token function">delay</span><span class="token punctuation">(</span>seconds<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">return</span> initalValue<span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /><br /> <span class="token keyword">private</span> <span class="token class-name">Function</span><span class="token generics"><span class="token punctuation"><</span><span class="token class-name">String</span><span class="token punctuation">,</span> <span class="token class-name">String</span><span class="token punctuation">></span></span> <span class="token function">addDelayed</span><span class="token punctuation">(</span><br /> <span class="token keyword">final</span> <span class="token class-name">ConcurrentLinkedQueue</span><span class="token generics"><span class="token punctuation"><</span><span class="token class-name">String</span><span class="token punctuation">></span></span> concurrentLinkedQueue<span class="token punctuation">,</span> <span class="token keyword">final</span> <span class="token keyword">int</span> seconds<span class="token punctuation">)</span> <span class="token punctuation">{</span><br /> <span class="token keyword">return</span> <span class="token punctuation">(</span>e<span class="token punctuation">)</span> <span class="token operator">-></span> <span class="token punctuation">{</span><br /> <span class="token function">delay</span><span class="token punctuation">(</span>seconds<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> concurrentLinkedQueue<span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span>e<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">return</span> e<span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /><br /> <span class="token annotation punctuation">@Test</span><br /> <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">secondShouldBeFirst</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><br /> <span class="token function">allOf</span><span class="token punctuation">(</span><br /> <span class="token function">supplyAsync</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">-></span> first<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">thenApply</span><span class="token punctuation">(</span><span class="token function">addDelayed</span><span class="token punctuation">(</span>concurrentLinkedQueue<span class="token punctuation">,</span> delay<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span><br /> <span class="token function">supplyAsync</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">-></span> second<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">thenApply</span><span class="token punctuation">(</span>concurrentLinkedQueue<span class="token operator">::</span><span class="token function">add</span><span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token punctuation">.</span><span class="token function">join</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token function">assertThat</span><span class="token punctuation">(</span><span class="token function">ofAll</span><span class="token punctuation">(</span>concurrentLinkedQueue<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">equalTo</span><span class="token punctuation">(</span><span class="token function">of</span><span class="token punctuation">(</span>second<span class="token punctuation">,</span> first<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /><br /> <span class="token annotation punctuation">@Test</span><br /> <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">secondsecondShouldBeFirstFirst</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><br /> <span class="token function">allOf</span><span class="token punctuation">(</span><br /> <span class="token function">supplyAsync</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">-></span> first<span class="token punctuation">)</span><br /> <span class="token punctuation">.</span><span class="token function">thenApply</span><span class="token punctuation">(</span><span class="token function">addDelayed</span><span class="token punctuation">(</span>concurrentLinkedQueue<span class="token punctuation">,</span> delay <span class="token operator">*</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token punctuation">.</span><span class="token function">thenApply</span><span class="token punctuation">(</span><span class="token function">addDelayed</span><span class="token punctuation">(</span>concurrentLinkedQueue<span class="token punctuation">,</span> delay <span class="token operator">*</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span><br /> <span class="token function">supplyAsync</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">-></span> second<span class="token punctuation">)</span><br /> <span class="token punctuation">.</span><span class="token function">thenApply</span><span class="token punctuation">(</span><span class="token function">addDelayed</span><span class="token punctuation">(</span>concurrentLinkedQueue<span class="token punctuation">,</span> delay<span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token punctuation">.</span><span class="token function">thenApply</span><span class="token punctuation">(</span><span class="token function">addDelayed</span><span class="token punctuation">(</span>concurrentLinkedQueue<span class="token punctuation">,</span> delay <span class="token operator">*</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token punctuation">.</span><span class="token function">join</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token function">assertThat</span><span class="token punctuation">(</span><span class="token function">ofAll</span><span class="token punctuation">(</span>concurrentLinkedQueue<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">equalTo</span><span class="token punctuation">(</span><span class="token function">of</span><span class="token punctuation">(</span>second<span class="token punctuation">,</span> second<span class="token punctuation">,</span> first<span class="token punctuation">,</span> first<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /><br /> <span class="token annotation punctuation">@Test</span><br /> <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">secondsecondShouldBeFirstFirstAlways</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><br /> <span class="token class-name">CompletableFuture</span><span class="token generics"><span class="token punctuation"><</span><span class="token class-name">String</span><span class="token punctuation">></span></span> stringCompletableFuture <span class="token operator">=</span> <span class="token function">supplyAsync</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">-></span> first<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token function">delay</span><span class="token punctuation">(</span>delay<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token function">allOf</span><span class="token punctuation">(</span><br /> stringCompletableFuture<br /> <span class="token punctuation">.</span><span class="token function">thenApply</span><span class="token punctuation">(</span><span class="token function">addDelayed</span><span class="token punctuation">(</span>concurrentLinkedQueue<span class="token punctuation">,</span> delay <span class="token operator">*</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token punctuation">.</span><span class="token function">thenApply</span><span class="token punctuation">(</span><span class="token function">addDelayed</span><span class="token punctuation">(</span>concurrentLinkedQueue<span class="token punctuation">,</span> delay <span class="token operator">*</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span><br /> <span class="token function">supplyAsync</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">-></span> second<span class="token punctuation">)</span><br /> <span class="token punctuation">.</span><span class="token function">thenApply</span><span class="token punctuation">(</span><span class="token function">addDelayed</span><span class="token punctuation">(</span>concurrentLinkedQueue<span class="token punctuation">,</span> delay<span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token punctuation">.</span><span class="token function">thenApply</span><span class="token punctuation">(</span><span class="token function">addDelayed</span><span class="token punctuation">(</span>concurrentLinkedQueue<span class="token punctuation">,</span> delay <span class="token operator">*</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token punctuation">.</span><span class="token function">join</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token function">assertThat</span><span class="token punctuation">(</span><span class="token function">ofAll</span><span class="token punctuation">(</span>concurrentLinkedQueue<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">equalTo</span><span class="token punctuation">(</span><span class="token function">of</span><span class="token punctuation">(</span>second<span class="token punctuation">,</span> second<span class="token punctuation">,</span> first<span class="token punctuation">,</span> first<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /><br /> <span class="token annotation punctuation">@Test</span><br /> <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">secondsecondShouldBeFirstFirstDelayedFutureSupplier</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><br /> <span class="token function">allOf</span><span class="token punctuation">(</span><br /> <span class="token function">supplyAsync</span><span class="token punctuation">(</span><span class="token function">supplyFirstAfterDelay</span><span class="token punctuation">(</span>delay<span class="token punctuation">,</span> first<span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token punctuation">.</span><span class="token function">thenApply</span><span class="token punctuation">(</span><span class="token function">addDelayed</span><span class="token punctuation">(</span>concurrentLinkedQueue<span class="token punctuation">,</span> delay <span class="token operator">*</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token punctuation">.</span><span class="token function">thenApply</span><span class="token punctuation">(</span><span class="token function">addDelayed</span><span class="token punctuation">(</span>concurrentLinkedQueue<span class="token punctuation">,</span> delay <span class="token operator">*</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span><br /> <span class="token function">supplyAsync</span><span class="token punctuation">(</span><span class="token function">supplyFirstAfterDelay</span><span class="token punctuation">(</span>delay<span class="token punctuation">,</span> second<span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token punctuation">.</span><span class="token function">thenApply</span><span class="token punctuation">(</span><span class="token function">addDelayed</span><span class="token punctuation">(</span>concurrentLinkedQueue<span class="token punctuation">,</span> delay<span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token punctuation">.</span><span class="token function">thenApply</span><span class="token punctuation">(</span><span class="token function">addDelayed</span><span class="token punctuation">(</span>concurrentLinkedQueue<span class="token punctuation">,</span> delay <span class="token operator">*</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token punctuation">.</span><span class="token function">join</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token function">assertThat</span><span class="token punctuation">(</span><span class="token function">ofAll</span><span class="token punctuation">(</span>concurrentLinkedQueue<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">equalTo</span><span class="token punctuation">(</span><span class="token function">of</span><span class="token punctuation">(</span>second<span class="token punctuation">,</span> second<span class="token punctuation">,</span> first<span class="token punctuation">,</span> first<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /><br /> <span class="token annotation punctuation">@Test</span><br /> <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">secondIsNeverFirst</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><br /> <span class="token keyword">final</span> <span class="token class-name">CompletableFuture</span><span class="token generics"><span class="token punctuation"><</span><span class="token class-name">String</span><span class="token punctuation">></span></span> suppliedFirst <span class="token operator">=</span> <span class="token function">supplyAsync</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">-></span> first<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token function">delay</span><span class="token punctuation">(</span>delay<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token function">allOf</span><span class="token punctuation">(</span><br /> suppliedFirst<span class="token punctuation">.</span><span class="token function">thenApply</span><span class="token punctuation">(</span><span class="token function">addDelayed</span><span class="token punctuation">(</span>concurrentLinkedQueue<span class="token punctuation">,</span> delay<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span><br /> <span class="token function">supplyAsync</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">-></span> second<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">thenAccept</span><span class="token punctuation">(</span>concurrentLinkedQueue<span class="token operator">::</span><span class="token function">add</span><span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token punctuation">.</span><span class="token function">join</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token function">assertThat</span><span class="token punctuation">(</span><span class="token function">ofAll</span><span class="token punctuation">(</span>concurrentLinkedQueue<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">equalTo</span><span class="token punctuation">(</span><span class="token function">of</span><span class="token punctuation">(</span>second<span class="token punctuation">,</span> first<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /><br /> <span class="token annotation punctuation">@Test</span><br /> <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">secondIsNeverFirstWhenDelayIsLonger</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><br /> <span class="token keyword">final</span> <span class="token class-name">CompletableFuture</span><span class="token generics"><span class="token punctuation"><</span><span class="token class-name">String</span><span class="token punctuation">></span></span> suppliedFirst <span class="token operator">=</span><br /> <span class="token function">supplyAsync</span><span class="token punctuation">(</span><span class="token function">supplyFirstAfterDelay</span><span class="token punctuation">(</span>delay<span class="token punctuation">,</span> first<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token function">delay</span><span class="token punctuation">(</span>delay <span class="token operator">*</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token function">allOf</span><span class="token punctuation">(</span><br /> suppliedFirst<span class="token punctuation">.</span><span class="token function">thenApply</span><span class="token punctuation">(</span><span class="token function">addDelayed</span><span class="token punctuation">(</span>concurrentLinkedQueue<span class="token punctuation">,</span> delay<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span><br /> <span class="token function">supplyAsync</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">-></span> second<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">thenAccept</span><span class="token punctuation">(</span>concurrentLinkedQueue<span class="token operator">::</span><span class="token function">add</span><span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token punctuation">.</span><span class="token function">join</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token function">assertThat</span><span class="token punctuation">(</span><span class="token function">ofAll</span><span class="token punctuation">(</span>concurrentLinkedQueue<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">equalTo</span><span class="token punctuation">(</span><span class="token function">of</span><span class="token punctuation">(</span>second<span class="token punctuation">,</span> first<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /><br /> <span class="token annotation punctuation">@Test</span><br /> <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">asyncSimple</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><br /> <span class="token function">allOf</span><span class="token punctuation">(</span><br /> <span class="token function">supplyAsync</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">-></span> first<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">thenApply</span><span class="token punctuation">(</span><span class="token function">addDelayed</span><span class="token punctuation">(</span>concurrentLinkedQueue<span class="token punctuation">,</span> delay<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span><br /> <span class="token function">supplyAsync</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">-></span> second<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">thenAcceptAsync</span><span class="token punctuation">(</span>concurrentLinkedQueue<span class="token operator">::</span><span class="token function">add</span><span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token punctuation">.</span><span class="token function">join</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token function">assertThat</span><span class="token punctuation">(</span><span class="token function">ofAll</span><span class="token punctuation">(</span>concurrentLinkedQueue<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">equalTo</span><span class="token punctuation">(</span><span class="token function">of</span><span class="token punctuation">(</span>second<span class="token punctuation">,</span> first<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /><br /> <span class="token annotation punctuation">@Test</span><br /> <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">asyncWithADelay</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><br /> <span class="token keyword">final</span> <span class="token class-name">CompletableFuture</span><span class="token generics"><span class="token punctuation"><</span><span class="token class-name">String</span><span class="token punctuation">></span></span> suppliedFirst <span class="token operator">=</span> <span class="token function">supplyAsync</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">-></span> first<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token function">delay</span><span class="token punctuation">(</span>delay <span class="token operator">*</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token function">allOf</span><span class="token punctuation">(</span><br /> suppliedFirst<span class="token punctuation">.</span><span class="token function">thenApply</span><span class="token punctuation">(</span><span class="token function">addDelayed</span><span class="token punctuation">(</span>concurrentLinkedQueue<span class="token punctuation">,</span> delay<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span><br /> <span class="token function">supplyAsync</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">-></span> second<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">thenAcceptAsync</span><span class="token punctuation">(</span>concurrentLinkedQueue<span class="token operator">::</span><span class="token function">add</span><span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token punctuation">.</span><span class="token function">join</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token function">assertThat</span><span class="token punctuation">(</span><span class="token function">ofAll</span><span class="token punctuation">(</span>concurrentLinkedQueue<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">equalTo</span><span class="token punctuation">(</span><span class="token function">of</span><span class="token punctuation">(</span>second<span class="token punctuation">,</span> first<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /><br /> <span class="token annotation punctuation">@Test</span><br /> <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">asyncWithMultipleDelays</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><br /> <span class="token class-name">CompletableFuture</span><span class="token generics"><span class="token punctuation"><</span><span class="token class-name">String</span><span class="token punctuation">></span></span> stringCompletableFuture <span class="token operator">=</span><br /> <span class="token function">supplyAsync</span><span class="token punctuation">(</span><span class="token function">supplyFirstAfterDelay</span><span class="token punctuation">(</span>delay<span class="token punctuation">,</span> first<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token function">delay</span><span class="token punctuation">(</span>delay <span class="token operator">*</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token function">allOf</span><span class="token punctuation">(</span><br /> stringCompletableFuture<span class="token punctuation">.</span><span class="token function">thenApply</span><span class="token punctuation">(</span><span class="token function">addDelayed</span><span class="token punctuation">(</span>concurrentLinkedQueue<span class="token punctuation">,</span> delay<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span><br /> <span class="token function">supplyAsync</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">-></span> second<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">thenApply</span><span class="token punctuation">(</span>concurrentLinkedQueue<span class="token operator">::</span><span class="token function">add</span><span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token punctuation">.</span><span class="token function">join</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token function">assertThat</span><span class="token punctuation">(</span><span class="token function">ofAll</span><span class="token punctuation">(</span>concurrentLinkedQueue<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">equalTo</span><span class="token punctuation">(</span><span class="token function">of</span><span class="token punctuation">(</span>second<span class="token punctuation">,</span> first<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /><span class="token punctuation">}</span></code></pre>
Programming Languages are Broken2016-05-12T00:00:00Zhttps://markalanrichards.com/posts/2016-05-12-programming-languages-are-broken/<p><em>In the context of this post, immutability is the surface of the feature that stays the same, allowing it to be reused with reliability</em></p>
<h2 id="it-s-not-just-left-pad" tabindex="-1">It's not just Left-pad <a class="direct-link" href="https://markalanrichards.com/posts/2016-05-12-programming-languages-are-broken/#it-s-not-just-left-pad" aria-hidden="true">#</a></h2>
<p>It's left-pad; dependency, jar or dll hell; segfault, a conflict warning, a NoClassDefFoundError or unexpected behaviour; HTTP errors, marshalling errors and can even be unexpected timeouts, infinite loops and any other unexpected behaviour.</p>
<h2 id="what-did-sql-get-right" tabindex="-1">What did SQL get right? <a class="direct-link" href="https://markalanrichards.com/posts/2016-05-12-programming-languages-are-broken/#what-did-sql-get-right" aria-hidden="true">#</a></h2>
<p>If you model an order system in SQL, you could contract a SQL guru to do it in 2003 and years later it'd likely still work. I'd be suprised if the average Node app can last months without some form of npm dependency problem.</p>
<h2 id="banks-didn-t-trust-us" tabindex="-1">Banks didn't trust us <a class="direct-link" href="https://markalanrichards.com/posts/2016-05-12-programming-languages-are-broken/#banks-didn-t-trust-us" aria-hidden="true">#</a></h2>
<p>Enterprise software industry was <em><strong>maybe</strong></em> making progress on this: W3C (in the old days), JSRs, OMG and OASIS were making immutable standards with backwards compatibility.</p>
<p>But outside the "Enterprise" umbrella, the rest decided to shun strict xhtml, ebXML, SOAP, CORBA IDL and jumped into HTML5, REST, JSON and <em><strong>agile</strong></em> moving targets that steer and depend on many <em><strong>open source software projects</strong></em>.</p>
<h2 id="most-businesses-aren-t-going-to-have-a-business-model-that-changes-very-much-so-why-does-the-software-that-supposedly-represents-it" tabindex="-1">Most businesses aren't going to have a business model that changes very much; so why does the software that supposedly represents it? <a class="direct-link" href="https://markalanrichards.com/posts/2016-05-12-programming-languages-are-broken/#most-businesses-aren-t-going-to-have-a-business-model-that-changes-very-much-so-why-does-the-software-that-supposedly-represents-it" aria-hidden="true">#</a></h2>
<p>Microsoft's did do something good (never let me say that again), with <em>relatively</em> <a href="https://www.youtube.com/watch?v=8WP7AkJo3OE">immutable</a> contracts in their API layers and they weren't the only ones, resulting in the famous acronym: <a href="https://www-01.ibm.com/support/docview.wss?uid=swg27008656%22">VRMF</a>.</p>
<p>Enterprise computing was dominated by some degree of immutable contracts from Oracle, Microsoft, IBM, Sun, Intel, etc and we still enjoy their efforts. Now, they weren't doing all of this for fun... <a href="http://www.cptech.org/at/ibm/ibm1984ec.html">regulators liked interfaces</a>.</p>
<h2 id="so-what-is-relatively-immutable" tabindex="-1">So what is relatively immutable? <a class="direct-link" href="https://markalanrichards.com/posts/2016-05-12-programming-languages-are-broken/#so-what-is-relatively-immutable" aria-hidden="true">#</a></h2>
<p>Most of these...</p>
<ul>
<li>Instruction Sets</li>
<li>Assembly</li>
<li>POSIX</li>
<li>Enterprise programming languages</li>
<li>Enterprise Document Formats</li>
<li>Network protocols</li>
<li>Enterprise database interfaces</li>
<li>Filesystem data structures</li>
<li>Games console libraries</li>
</ul>
<p>They share something in common. They are either used in regulated environments like for major industries' core business (banking systems, medical uses, etc) or governments, run on embedded systems that are hard to update or tied to hardware.</p>
<h2 id="and-the-rest" tabindex="-1">And the rest ... <a class="direct-link" href="https://markalanrichards.com/posts/2016-05-12-programming-languages-are-broken/#and-the-rest" aria-hidden="true">#</a></h2>
<ul>
<li>Application code: but to be fair, this may not have any consumers except Human Beings</li>
<li>Custom, internal integration services and models developed internally in companies. From startup to multinational, their internal services are only as good as the care dedicated to the project. Sometimes you're lucky to have a spec and other times that specification isn't as long lasting as you'd hoped.</li>
<li>.., and I hate to say it, but if feels like most open source libraries and applications.</li>
</ul>
<p>Open source projects seem to thrive on the ability to break users of their interfaces and those that don't often have strong relationships with Enterprise businesses... not always, sometimes ties to Enterprise don't help either.</p>
<h2 id="hacking-safety-in" tabindex="-1">Hacking safety in <a class="direct-link" href="https://markalanrichards.com/posts/2016-05-12-programming-languages-are-broken/#hacking-safety-in" aria-hidden="true">#</a></h2>
<p>Some build systems (usually rather poorly) try to enforce immutable versions on top of a programming language and at runtime plugin systems can try to do the same.</p>
<p>But it's not an easy process to work with. Both often require a lot of hand-holding to ensure that migration between immutable models, interfaces or services happens without disruption. If you're lucky, they'll warn you about problems and that is great... Maven would be a lot worse without Enforcer, but even in this case the tools aren't always there by default.</p>
<p>They highlight the other problem of strange behaviours in that why would you ever allow multiple versions of a library to be imported at the same time: this isn't unique to Java or Maven, in fact they are probably a better pairing then most.</p>
<h2 id="why-programming-languages-are-to-blame" tabindex="-1">Why programming languages are to blame? <a class="direct-link" href="https://markalanrichards.com/posts/2016-05-12-programming-languages-are-broken/#why-programming-languages-are-to-blame" aria-hidden="true">#</a></h2>
<p>Although the languages themselves are relatively Immutable (when did java.lang.String not have backwards compatibility) they encourage software development that isn't.</p>
<p>The first mistake is to use text files for programming languages and depend on REST for build systems. Neither of which are immutable and yet both of which usually underpin the dependencies for a language, either the packaged library modules or the import/require statements use them, but if you imagine a language that only imported by torrent hashes, then breaking compatibility would be much harder, maybe impossible?</p>
<p>Using a hash based database might work quite well, code might be unreadable:</p>
<pre><code>import sha512[23123213...]
sha512[23123213...].apply(1))
</code></pre>
<p>But then you can map readability:</p>
<pre><code>identify sha512[23123213...] as listbuilder
...
import listbuilder
listbuilder.apply(1)
</code></pre>
<p>Other problems are programming languages encourage mutable design patterns with abstract classes, implicits, annotation preprocessors/dynamic dependency injection.</p>
<p>Things often get worse you start using a languages' custom DSL for XML or JSON: are you creating an XSD first?</p>
<p>Sometimes they embed auto serialization/deserialization to object formats, so code (that mutates) becomes the contract for middleware services, taking a problem at a language level and turning it into one that affects libraries and service layers alike.</p>
<h2 id="fixing-it" tabindex="-1">Fixing it <a class="direct-link" href="https://markalanrichards.com/posts/2016-05-12-programming-languages-are-broken/#fixing-it" aria-hidden="true">#</a></h2>
<ul>
<li>Let's create immutable build dependencies and imports.</li>
<li>Ban version conflicts</li>
<li>Let's drop JSON and REST</li>
<li>Code to interfaces, don't interface from code</li>
<li>Ban inheritance of mutable features and implicits that can modify the runtime behaviour unexpectedly</li>
<li>Ban Javascript</li>
<li>Simplify languages</li>
<li>Aim for code to last 10 years for business domain logic, or maybe just ask the business more often about whether they realise the risks in the choices the development team is making.</li>
</ul>