Last weekend, I received a notification by text that my WhatsApp subscription had expired. Immediately recognising this as a scam, I decided to investigate further.

I began by opening the full conversation in my messaging app, so that I could see any extra details which might help. The sender was labelled as "WhatsApp", which confused me, because I hadn't had a text from WhatsApp before and this definitely wasn't a message from the company.

It turns out that instead of a phone number, an alphanumeric sender ID can be used as the value of the "TP-OA" field. It's this field that your phone uses to display the sender, and it can be set by anyone at will, making exploiting a user's trust in their messaging app surprisingly easy. In some countries, a sender ID must be verified by the SMS carrier first. In the UK, however, there are no restrictions other than that the value must be alphanumeric and cannot exceed a length of 11 characters.

Confident that no more trickery was going on in the text message, I next decided to work out what the scammers were aiming for. Of course, they made the next steps nice and clear to the user. All I had to do was click a short link which would take me to the page needed to 'renew my subscription'.

I didn't want to click the link immediately, but I was curious at to where it would lead. Running the 'curl' command on my machine quickly revealed that a URL shortening service had been used, Tiny Url to be specific. They offer public APIs for every hash, and so I was able to use this to determine the destination of this link as well as the number of times that it had been clicked:

It had only been created around an hour ago, and over 3000 unique visitors had been tracked, and so this text was definitely being sent on a fairly large scale. With the hash being so new, my guess is that some software has been created to generate new URLs and domains periodically so that the scam can continue.

The next step in my investigation was to take a look at the website itself. Other than the appalling design and a broken footer, there wasn't much to see, and so I went straight to the source code. Unfortunately, rather than seeing an inspirational use of the latest web platform features, I was greeted by some ugly JavaScript and a giant variable full of gibberish:

It turns out that the page was rendered by using AES decryption and a basic cipher to bring the source into memory, at which point it is dumped out onto the page. There wasn't much to hide, leaving me to guess that this was just a way of tricking abuse prevention tools. In fact, a StackOverflow search for ways of hiding a page's source code led me straight to a GitHub Gist containing the script being used. Bingo!

The site itself exists simply to harvest billing credentials. A PHP script (running over HTTP, of course) collected the needed information using a basic form. I never used my real details, for obvious reasons, but did follow through the whole procedure. A few POST requests later, and I was redirected to the actual WhatsApp website. The scam was complete!

To put all of this into context, here is a timeline of events:

  • 21/05/17: Four domains registered using the WHOIS details I found. Two referenced WhatsApp and one impersonated the DVLA (a Government agency in the UK). I was sadly unable to identify the fourth.
  • 21/05/17: Text message received. Shortened URL had been up for around an hour.
  • 21/05/17: Attempted to contact DNS and web server host.
  • 21/05/17: Google Chrome begins warning users that the site is deceptive, and deters users from accessing it. I had no involvement with this - presumably automated/based on user reports?
  • 22/05/17: Initial contact made with owner of Tiny Url site. Link disabled and Darian tells me that similar URLs have been spotted before.
  • 26/05/17: Domain suspended by registrar.
  • 28/05/17: Blog post published. No further activity spotted, although changing domain name and registration details would be fairly easy for the scammer.

    To wrap all of this up, I just want to thank Darian from Tiny Url who was extremely helpful in putting a stop to this. To do the responsible thing, I want to point out that both WhatsApp and Tiny Url are genuinely useful services. It's a shame that they have been abused for this purpose, but I wouldn't want for it to cause them any damage.

I've been using a service called Netlify recently, which is based entirely around the idea of static hosting. I decided to try and convert the popular TodoMVC application into a more complete progressive web app, and that's where we start our journey. I also published this article in video form, available here.

What's a progressive web app?

The concept behind being a progressive web app is to create a webpage providing a high enough level of quality to earn a place on a users home screen. There's a great page explaining more on the Google developers site, here.

Sounds great! Where do I start?

It's important to understand that progressive web apps are a concept, rather than a discrete set of rules. Each browser has its own set of criteria, and so you should research these before going forward. Lighthouse is a great starting point. It's a browser extension which generates a report for each page of your site identifying areas for improvement. For the sake of this article, we'll rely on it as our way of deciding what to focus on.

I ran the tool for our basic todo list app, and it highlighted a few things which we were missing:

  • HTTPS - our page isn't secure, and with services such as Let's Encrypt offering SSL for free, there's really no excuse not to encrypt your content. I was able to fix this quickly using Netlify's built in HTTPS integration, so I won't cover it too much in this article.
  • Critical Request Path - This is an indicator of the number of requests your browser has to make before it is able to reach what we call the 'first meaningful paint'. This refers to the point at which users can read the content on your site.
  • Application Manifest - Manifest files allow extra context to be given to the browser so that it can provide a native like experience when the app is added to a users home screen.
  • Service Workers - The ability to add a middleman between your browser and the internet, to provide a better experience with either unpredictable network conditions, or even in situations where the user is offline.

The easy bit - HTTPS, and optimising assets

2017 is a great year to be a web developer. HTTPS used to be so expensive it was reserved for large organisations and financial institutions, but it's now so cheap browsers such as Chrome (see here) are beginning to warn users against any site lacking this protection. Services such as Cloudflare and Netlify will add this for you, but if you're running your own server, tools such as Caddy are available which will setup TLS hassle free.


To optimise assets, I turned to the built in asset bundler in the Netlify panel (available to Pro users, and free for open source projects). If you aren't hosting a static site, you can achieve something similar with tools like Aspax for Node or Gulp for anything else.

Adding an Application Manifest

{
  "name": "TodoMVC",
  "short_name": "TodoMVC",
  "start_url": ".",
  "display": "standalone",
  ...
  View Source

Adding an application manifest really doesn't take too long. If you've worked with JSON before, it's quite simply a case of running through the keys listed here and setting them to suit your app. You'll also need the following meta tag in your header:

<link rel="manifest" href="/manifest.json">
I was initially confused as to which extension I should use, but Addy from Google helped me out over on Twitter:

What's the point of all this? Browsers will notice that you're offering everything a user would need if the app was to be placed onto their home screen, and so it'll ask them if they're interested. If they say yes, your app will appear with a native-like splash screen and in a fullscreen window without any of the browsers usual chrome. If you'd like to know what this looks like in terms of UX, an animation and further explanation is posted here.

Service Workers

New to the web, but being adopted quickly, Service Workers allow you to take control of the network and speed up page load times by deciding yourself what should be cached. When used wisely, they can be of great benefit especially in letting users access your web app even when offline. They can also be used to provide push notifications and more, but that's beyond the scope of this article.

For TodoMVC, I decided the app wasn't likely to change. As a result, I implemented a basic service worker which simply permanently caches requests and serves them up when they are requested again.

if ('serviceWorker' in navigator) {
  //Let's register the ServiceWorker
  navigator.serviceWorker.register('/sw.js').then(function () {
    //We're good to go
    console.log("ServiceWorker registered correctly.");
  }).catch(function (err) {
    console.log("ServiceWorker registration failed: " + err);
  });
}
View Source

Registering the service worker is just a case of checking to see if our browser supports the feature, and if so, calling the register function. This then triggers an install event inside this file, at which point we call self.skipWaiting() to activate the Service Worker immediately rather than after all related tabs have been closed. The code for this is a bit longer, so take a look at GitHub if you're interested. MDN has a great article taking you through the process step by step if Service Workers are new to you.

Conclusion

After making the changes listed above, I've gone from scoring 25/100 on Lighthouse to a full 100%. It only took a few days, and the existing codebase remained almost identical, showing that any app can be turned into a progressive web app with some thought.

If you'd like to take a look for yourself:

  • Here's the original implementation of TodoMVC, which is available on GitHub too. This can be considered my starting point.
  • The final site is here, proudly hosted by Netlify. Netlify makes deploying static sites easy and their website is full of handy documentation to get started.

As you probably already know if you're taking a look at my blog, I'm very enthusiastic about development and along with often writing programs myself I dedicate a fair amount of my time to mentoring younger children in order to teach them vital coding skills. In an article on site TrustedReviews, technology journalist Jason Bradbury made a statement which I personally find baffling: that the recent Government initiatives to educate our children in coding are a "complete waste of time".

I'm strongly compelled to write this article because it seems to be a move in the complete wrong direction. Nonetheless, I respect Jason and his work and following his follow-up on Twitter, will leave out any criticism of the "bad social skills" he initially claimed developers today possess.

The fundamental point of the article, as far as I can tell, is that in years to come his "kids won't need to code because soon computers will just code for them." While I don't know how much coding experience Jason has, I think the key misconception here is that coding is simply a task executed by either a human or a robot. The fact of the matter is, that while coding is necessary to write modern day applications, I think it's a more of a mind-set then a skill. It's about being able to break down a task into a number of smaller steps, and being able to write algorithms which could, for example, solve a Rubik's Cube when followed one by one. Even if a program can be written using "drag-and-drop and a little imagination," as Jason later alludes to, knowing how to efficiently break a task down into this steps is a fundamental skill which should, in my opinion, be taught without doubt.

Delving further into his reasoning, the second point Jason makes is that the future will "just be about being creative." He talks about the fact that what STEM (Science, Technology, Engineering and Maths) is missing is the art, the 'element of creativity'. I agree that this is extremely important, but I don't think this is all that is needed. As a rather specific example of this, many self-taught programmers take a formal course not because they don't have the creativity or understanding but because they lack the established rules which creative individuals have pieced together so that they don't have to. The axioms of development are already established and we should help to teach children how to do something in the generally accepted manor rather than simply in the way in which their mind wanders.

Hopefully this article explains my views clearly, and if you ever do read this Jason, I hope you see that I appreciate the need for creativity. My actual concern is the lack of acknowledgment of the actual discipline of coding itself. I'd love to know what you, and anyone reading this, have to say and I'm always available by email (oliver@oliverdunk.com) or Twitter (@oliverdunk_).