Tuesday 20 October 2020

Web applications, registration and confirmation

If we want to be able to manage sessions for people who have logged in successfully, we need a way to register those users.
We want to make sure people do use a name (email address) that is already taken and we need to verify that the mail address is valid.
This all means that we will not register them right away but store their email address and password along with a confirmation key in a temporary table. We then send them this key to their email address in the form of a clickable link. If this link is clicked within an acceptable time (like 15 minutes or so) their registration is made permanent and they are redirected to the login page.

The preliminary workflow looks like this

Note that we do not have a separate process that looks for expired requests but that we deal with those during the request or verification event itself. The idea being that registration and verification are relatively rare events and running a separate process the remove expired requests would just waste cpu resources.
The picture isn't complete yet because we also need to create a workflow for resetting passwords that people have forgotten.
On top of that we also need to implement some rate limiting because now it is pretty easy to swamp a mailer by flooding the server with registration requests.

Saturday 17 October 2020

Web applications, authentication, authorization and auditing (AAA)

Formally this blog is about Docker, or precisely, about creating a dockerized web application. However, without thinking about security and access control, building a web application is a disaster waiting to happen.

Now security is a rather broad concept that for example also includes things like availability, disaster recovery and secure deployment but today we will focus on access control, specifically controlling access to our application.

So let's discuss briefly what we want to achieve. The title of this article mentions three things but actually there are four things we want to achieve:

  • Identification to determine who the person is who is accessing our app
  • Authentication to prove someone's identity
  • Authorization to assign privileges based on someone's identity
  • Auditing to keep a record of someone's activity

The first two things are closely related: we identify someone by their username (or email address)  but anybody can claim any identity so without proof this is almost useless. If we do not verify the claim, anybody can claim to be someone else.

Proving someone's identity is often based on asking for something that someone knows or has, for example a secret, like a password, or perhaps a fingerprint, and compare this to something we have on file, like a password database.

Once we know for sure that someone is who they claim to be, we can determine what they are allowed to do in our app. Sometimes this authorization is implicit, a user may only access their own information for example, sometimes this is role based authorization, where we assign a role to a user (like 'administrator' or 'regular user') and each role has a set of allowed actions. 

The final part of application access control is auditing: we might want to keep track of some or all activity of user, perhaps to spot suspicious behavior or simply to identify usage patterns and improve the app (the latter is often referred to as 'metrics' or 'instrumentation'.

Implementation

In practical terms that means that our app will need a login page to let people identify themselves and authenticate them using a password. In order to authorize activitities inside the app we need to keep track of them once they have succesfully logged in. And for good measure they also need to be able to log out.

To keep track we issue a session cookie once people are logged in. This cookie is an unguessable random number that we store in a database along with the username and send back in the response to the browser. The browser will subsequently send this cookie along with every request, so the only thing we have to do on the server side is to check if we have this session cookie in our database. If we do, we know the user and can determine if they are allowed to do what they are requesting. If we don't have the session cookie in our database we deny the request and redirect the user to the logon page.

Schematically this looks like the diagram below where the large blue arrows on the left depict access requests to html pages or resources.


Session lifecycle

Sessions do not live forever and the creation, expiration and deletion are depicted below


Of course there is more to this subject, like how to create new passwords and how to offer a reset option to a user, but that's for a future article.