Authentication

Usernames and passwords, limiting attempts, and stronger ways to prove who someone is.

F6.2Robust programsGCSE15 min

Do this lesson in the simulator

A robot that obeys anyone who types a command is a robot anyone can crash. Authentication is checking that a user is who they claim to be before letting them in. In this lesson BugBot only drives for its registered operators, and only after they prove it.

Something you know

The most common kind of authentication is a username and password: the username says who you claim to be, and the password proves it, because only that person should know it.

# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()

operators = {"ada": "robot42", "alan": "turing1"}

name = input("Username? ")
password = input("Password? ")
if name in operators and operators[name] == password:
    print("welcome", name)
    led("green")
else:
    print("access denied")
    led("red")

Run this in the simulator

The operators are stored in a dictionary from lesson F3.6: each username is a key, and its password is the value. name in operators checks the username exists; operators[name] == password checks the password belongs to that user, not just to someone.

Try ada and robot42, then ada and turing1. The second is a real password, but not Ada's.

Say less when it fails

Notice the program says access denied whether the username or the password was wrong. If it said "no such user", an attacker would learn which usernames exist, and could concentrate on guessing their passwords. Good authentication gives away as little as possible.

Limiting attempts

A password can be guessed if an attacker is allowed unlimited tries. So programs allow only a few:

# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()

operators = {"ada": "robot42", "alan": "turing1"}

def login(tries=3):
    """Ask for a username and password up to `tries` times. Return the username, or None."""
    for attempt in range(tries):
        name = input("Username? ")
        password = input("Password? ")
        if name in operators and operators[name] == password:
            return name
        print("access denied")
        tone(220, 0.3)
    return None

user = login()
if user:
    print("welcome", user)
    led("green")
    forward(50, distance=20)
else:
    print("locked out")
    led("red")

Run this in the simulator

After three wrong attempts the function gives up and returns None, which is false in the if, so the robot never moves. Real systems also lock the account for a while, or ask for another check.

Better than a password

  • Two-factor authentication asks for two different kinds of proof: something you know (a password) and something you have (a code sent to your phone).
  • Biometrics use something you are: a fingerprint or a face.
  • Real systems never store passwords as plain text the way this lesson's dictionary does. They store a hash, a scrambled version that cannot be turned back into the password, so a stolen list of hashes does not give away the passwords.

Authentication and validation together

They answer different questions. Validation asks is this input sensible? Authentication asks is this person allowed? A robust program does both: the login is checked first, and then every command the user gives is validated.

Task: operator login

Use operators = {"ada": "robot42", "alan": "turing1"}. Ask Username? and Password? up to three times. For each wrong pair print access denied. When a pair is right, print welcome <name>, turn the LED green and drive 20 cm forward. The task types alan and wrong, then alan and turing1.

# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()

operators = {"ada": "robot42", "alan": "turing1"}

Challenges

  1. After three failures, make the robot flash red and refuse any more attempts.
  2. Add a new operator by asking for a username and a password twice, and only saving it if both passwords match. What is that second check called?
  3. Add a validation check that passwords are at least 8 characters with at least one digit.