password generator progressive-web-app

 

Back in 2015 I wrote a javascript-based password generator that I turned into a drag-and-droppable bookmarklet, which is a tool that I still use today.

However, as we move forward I found myself signing up for more and more accounts using my mobile device, which doesn’t have support for bookmarklets in the same way that a desktop does.

I also got fed up with having to sign into my password manager on my mobile every time I wanted to generate a new password.

So, after seeing a talk at Brighton PHP on progressive web-apps by Rowan Merewood, I decided to create a new password generator, specifically for mobile devices.

Check it out here. Source code available here.

Check out my original post from 2015 here.

Here is the original bookmarklet, drag it into your bookmarks to use it: [PwGen].

See the PwGen app on securityheaders.io.

Screenshot from PwGen on a mobile device

phones: don’t be complacent with your trust

We trust our phones to connect us to the world, and they allow us to prove our identity.
They are an authentication factor in themselves – proving we have the phone, is one measure of proving we are the owner of an account (via Email, SMS, Google Authenticator, etc).
Proving we can unlock the phone is itself another measure. (Mostly just to prove we didn’t recently steal the phone.)

So why do so many of us who also use our phones for work, agree to trust our employers with complete control over our phones?

I recently wanted to access my work email on my phone, so I installed the email app, and it told me I must have an administrator allow the connection.
So I contacted my friendly local sysadmin, and they said:

You need to install the policy tool on your phone before we can allow you to access work email on your phone.

Fine. So let’s look at the permissions this “policy” tool is requesting:


Notably, the app wants these permissions:

  • Erase all data on the phone by performing a factory reset.
  • Change the screen lock.
  • Lock the screen.
  • Enforce storage encryption.

I understand these requirements from a security perspective; they are all administrative functions I would want to have control over, if I owned the phone – which I do. The problem is that the company who I work for does not own my phone. I will never trust them to the same degree that I trust myself.

When I spoke to my colleagues about this, they all said the same thing to me:

But the company will never actually _use_ any of these permissions. – They just want to be able to delete your email from your phone if it’s lost or stolen.

This completely misses the point.

I refused to place my trust in this app for two reasons:

  1. Apps should not be granted more permissions than they need to fulfil their purpose.
    If I agree to these permissions, then it has the power to use them, regardless of any good intentions.
  2. Whether I trust the SysAdmins of my company is irrelevant.
    If a SysAdmin in my company can control my phone – then I’m also entrusting this control to a string of black-box processes and procedures that I have no control over.
    I treat my phone security very seriously – *Nobody else* has the same motives to protect my phone, as I do.

If my company gets hacked – or if any one of the SysAdmin’s accounts gets hacked (and there are probably multiple Sysadmins that have the same access to control my phone) – then a malicious actor now has the ability to lock out my phone, or wipe it with no warning.

This may have the following side-effects:

  • Loss of personal files/photos stored on the device (assuming they aren’t all backed up to the cloud somewhere)
  • Loss of 2-factor login codes (because you don’t have a U2F device)
  • Loss of 2-factor backup codes (unless you keep them stored somewhere safe, and not in a text file on your phone)
  • Loss of other account passwords that you keep in an encrypted text file that you keep on the encrypted SD card in your phone (which isn’t in the cloud, for “security”…)
  • Inability to contact anyone (because you don’t actually remember anyones phone number anymore)
  • Inability to buy things (because you rely on Apply|Android Pay and no longer carry cash or cards)
  • Inability to use public transport (because you use an App for that)
  • Inability to control your house heating/lighting/door-locks (because you can’t get enough of those IoT devices)

But these issues aren’t limited to you. This policy is something that everyone in the company who wants access to their email on their phone, has to agree with and accept.

So if I’m a hacker and I’ve compromised just one SysAdmin account – I have the ability to wipe the phone of everyone in the company who has placed their trust in this app.

Does this include the CEO or board of directors?
Does this include all of the security staff?

Desired Outcomes

A malicious actor might choose to disable these devices for the following reasons:

  • To destabilise a company during a critical period of business, causing financial harm.
  • As part of a campaign to cause as much damage to the company as possible.
  • To inhibit security personnel from countering the actions of the malicious actor.
  • To restrict the short-term management of company stocks and shares.

General Motives

  • Individual victimisation.
  • Retribution against the company.
  • Competitor motivated or financed.
  • Foreign government de-stabilisation.

Victim / Target

The intended victim in this attack can vary a lot. As a user, I might intentionally be the only victim in a directed attack, but I could also just be one of billions of victims.

  • Single targeted user.
  • A group of users within a company who share a common function. (eg. Security Personnel)
  • The company itself (All users of the app in the company)
  • All users of the app (If the app or app company is targeted)
  • All users in a specific country (In a state-sponsored attack on a foreign government, as part of a de-stabilisation process)

Mitigation

  • Any app you require your users to install on their devices, should only have the permissions required to serve its purpose.
  • The ability to perform actions on users’ personal devices must be restricted to those who absolutely need it.
  • Multiple SysAdmins should be required to act as a “group action” to carry out a non-reversible process such as ‘wiping a device’.

Summary

As a company, we need to be less cavalier about what we ask our users to trust us with.

As an employee, we need to be more protective of our own devices, our data, and our privacy.

As system designers, we need to allow for multi-admin safeguards, to ensure any action that results in any action against a user’s device can only be carried out as the collective actions of an authorised group of administrators.

As system engineers, we need to ensure any actions that are carried out are recorded and audited, so that misuse of the system can be identified, reported, and investigated thoroughly.

my password generator

Passwords are everywhere, we use them for logging into all sorts of services, and typically we use a very small number of passwords, sometimes with small variations. In this article I explain why and how you should be using a password generator.

are my passwords strong?

Using similar passwords everywhere is bad practise – it means if an attacker gets a password for one service you use, they will likely be able to gain access to your other accounts elsewhere.

The reason you don’t use lots of different passwords is because it’s difficult for us humans to remember them all, especially when we’re told to use special characters, numbers, and mixed case letters, and avoid using words, patterns, or repetition.

Because this is what goes into making an OK password, but there is a better way.

so what is a strong password?

To create a strong password the only real option is to use a secure password generator. These use a cryptographically-secure random number generator to create the strongest passwords possible with the available limitations, such as length, characters available, etc.

What secure passwords look like:
64 character alphanumeric password:
a40vr2IStSnuSJWYwscjSgX5zKNyxKjn4v0q6mxkCbY7I2wm9FvbZumD2fMEtKL
64 character alphanumeric password with symbols:
aY5v[kHDRo:tET"zIarFn4£4[ZP|%YIH{hR6"xRU[6£n,baS8[tf&d520ZhE:2

So you get the idea. Even short passwords (16 characters or less) are much more secure than any password you can actually think of, even mashing your face on the keyboard will result in reproducible patterns. If an attacker mashes their own face into a keyboard for hours and hours, not only is this hilarious for everyone watching, but chances are that they will have generated several passwords that are similar to yours. They can then add these “mashed face” passwords to a database to use in the future, to save themselves the face-pain if nothing else. (This is what password databases are for – they contain billions of passwords to use in cracking systems. I’m not covering rainbow-tables here, but please feel free to read up on it in your spare time.)

why are my normal passwords not strong?

Basically it comes down to the ease at which they can be computationally guessed, given whether the attacker has a hash, hint, or other personal data that you may have used to create your password, such as patterns you’ve used to create passwords on other sites.

If an attacker has one of your passwords, are your other passwords sufficiently different to prevent the attacker guessing the other ones?

If you use `las4nco7h3jpjse;facebook` as your facebook password, what combinations do you think the attacker might try to use to access your gmail account?
Perhaps `las4nco7h3jpjse;gmail` and `las4nco7h3jpjse;google` would be their first two attempts?

It only takes one of your accounts’ passwords to be compromised using this pattern for all of your other account passwords to become guessable.

how do i generate a strong random password?

I use a password generator that I wrote myself, which is clean and simple. It is based on principles of generating numbers with high entropy using a secure random number generator function built into Javascript, and available on most (if not all) browsers.
This extension works on Chrome and Firefox at the time of writing, and it doesn’t work in Internet Explorer.
(I would appreciate it if people would tell me via comments if it works in other obscure browsers.)

Drag the following button into your bookmarks bar to use this password generator, the code is also shown a bit further down the page.

Password Generator

Clicking on it in your toolbar should result in a window like this:

password generator

Click the buttons to generate passwords according to the length and complexity required.

but how am i supposed to remember all these passwords?

You aren’t.

There are several browser extensions and third-party applications that enable the secure storage of passwords, such as KeyPass, Keeper, and even as a core part of the Google Chrome browser.

Many of these secure password stores are available as extensions to your existing Firefox, Chrome or IE browsers, and on mobile devices, so you can generate and submit a new password on one device, and it will be available on your other devices automatically.

but what if someone gets my password manager password?

Using a password manager does mean you typically need to remember at least one relatively secure master password, but these services do typically offer two-factor authentication, which forces anyone who attempts to log in to your password storage to also have access to your phone or mobile device, so it can send you a text message to confirm the person who owns the password storage is also in control of the registered phone number for the account.

Google, Facebook, Twitter and others support two-factor authentication, and you should be using it whenever possible.

the geeky bit

The bookmarklet is a block of Javascript code that executes on the current page you are browsing, but doesn’t send any data to any server at all. This means the password generated only ever exists in the browser window. You have the option in the tool to generate various password sizes, with or without special characters. It is also relatively easy to change the code if you want additional buttons.

From a security perspective there are a couple of other features this password generator makes use of:

  1. By default it obscures most of the password from view, so if your screen is being watched (either by shoulder-surfing or by a more nefarious screen watching software utility) then the password is still moderately protected. There is a ‘show password’ button so you can check the password looks as you might expect, but this defeats the security feature.
  2. If you have a keylogger installed on the computer, the copy-paste action of the password text is not likely to be captured by the keylogger, which it would be if you had to type it in manually. Copy-pasting passwords also reduces the likelihood that you will get the password wrong, and makes you feel more comfortable using absurd-looking long passwords with lots of special characters.
  3. The bookmarklet relies on no third party code, so there are no connections made to any other resource to generate or store your password, or to facilitate any component of this utility.

Here’s the code for the password generator with a bit of wrapping and white-space to make it more readable.

javascript:(function() {
    var x='0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
        y=x+'!"£$%^&*()_+-={}[]:@~;#?,./|\',
        w=window.open('','',
            'height=110,width=600,top=100,left=100,location=no,menubar=no,'+
            'resizable=no,scrollbars=no,status=no,titlebar=no,toolbar=no'
        ),
        d=w.document,
        b=d.body,
        a='appendChild',
        C='createElement',
        B=d[C]('button'),
        e=d[C]('input'),
        ctn='createTextNode',
        f=function(c,ct){
            var bb = d[C]('button');
            bb[a](d[ctn]('x'+ct));
            bb.onclick=function(){
                var f=new Uint8Array(ct),
                    i=f.length-1,
                    o='';
                w.crypto.getRandomValues(f);
                while(i)o+=c[f[i--]%c.length];
                e.value=o;
                e.select();
            };
            b[a](bb);
        },
        m=function(R,t){
            b[a](d[R](t));
        };
    b.style.fontFamily='Tahoma';
    b.style.background='#cfc';
    e.style.width=20;
    b.onclick=function(){e.select();};
    B[a](d[ctn]('password hidden for security - click to show'));
    B.onclick=function(){
        e.style.width=550;
        B.style.display='none';
    };
    m(ctn,'Press Ctrl-C to copy your new password ');
    m(C,'br');
    b[a](e);
    b[a](B);
    m(C,'br');
    f(x,16);
    f(x,32);
    f(x,64);
    m(ctn,' a-zA-Z0-9');
    m(C,'br');
    f(y,16);
    f(y,32);
    f(y,64);
    m(ctn,' with symbols');
}());

The code is minified somewhat, as URLs are limited to 4096 bytes – this code is way below that anyway, but it makes it look more exciting if nothing else.

what is the difference between random and secure-random?

I’m glad you asked.

Generating random numbers with normal ‘random’ functions aren’t considered secure because although the output of these functions appears random, and the randomness usually stands up to basic statistical analysis, standard random number generators are only random enough to be used for non-security related scenarios. Normal random number generators should only be used where the numbers generated aren’t predictable or reproducible.

The last few digits of the current system time in microseconds might be used as a simple generator, but these numbers are selected at intervals from the same source, with little external influence, so reproducing or predicting the next number in the series would be a lot easier than if the numbers were produced by a more secure system. So `current microseconds mod 6` is great for generating dice rolls, but not so great for generating passwords.

To generate random numbers in Javascript that are strong, we use `window.crypto.getRandomValues()`. This is a built-in security component of modern web browsers. If we just need a normal ‘random’ number, we use `Math.random()` instead, which is quicker, but not secure.

further reading