Control d'accés
El control d'accés inclou les activitats de registre, autenticació i autorització d'usuaris.
Registre
El registre d'usuaris té associat l'emmagatzematge d'aquella informació necessària per poder autenticar-los posteriorment. És important evitar deixar la informació en clar en fitxers o bases de dades, per estalviar-nos problemes de seguretat. També, evitar encriptar els passwords.
Un esquema habitual és l'ús de resums o hash. Si guardem el hash a la BBDD, no sabrem quin és el password, però podem comparar el que entra l'usuari amb el hash guardat, i dir si és el mateix.
Això només té un problema: hi ha taules preconstruïdes per a cercar les correspondències entre hash i password. Això ens obliga a afegir un string random (salt) al costat del password, i llavors el hash de tot plegat no és sempre el mateix per al mateix password. Aquest salt no ha de ser privat, compleix l'objectiu de fer inútils les tàctiques habituals per esbrinar passwords, i per tant es pot guardar en clar a la BBDD.
A l'hora de fer l'autenticació només haurem de fer la comparació entre el hash emmagatzemat i el calculat:
hash(salt + password1) és igual a hash(salt + password2)?
Una tècnica per a generar resums més segurs és el key stretching, que fa que la seva generació sigui lenta per a fer més difícil un atac de força bruta. Els algorismes KDF (Key Derivation Function) són un exemple.
Autenticació
L'autenticació implica, habitualment, recollir la identificació de l'usuari per tal de comprovar la seva autenticitat.
Un cop tenim l'usuari autenticat, aquest pot rebre un identificador generat pel servidor i que el client haurà de fer arribar cada petició al servidor per tal de confirmar que està autenticat.
Les aplicacions client / servidor es poden diferenciar en dos tipus: stateful i stateless: amb i sense estat. Això es refereix al fet que el servidor emmagatzemi o no dades associades a l'usuari autenticat, el que s'anomena sessió.
- Stateful: amb sessió i dades emmagatzemades al servidor. L'identificador generat és el de la sessió. El servidor passa un ID al client, que utilitza cada cop que es comunica amb el servidor. El servidor l'utilitza per obtenir les dades que té associades.
- Stateless: sense sessió i dades emmagatzemades al client. L'identificador generat es diu token. Pot ser simplement un ID aleatori generat, però habitualment contenen informació associada que ha estat signada criptogràficament.
Identificador al client
A les aplicacions web, si un client està autenticat cal que li faci saber al servidor mitjançant algun tipus d'identificador secret. El client podria ser un navegador, si és una aplicació web d'usuari, o una aplicació client.
Si el client és un navegador, hi ha bàsicament dos esquemes per guardar aquest identificador al client: cookies i web storage.
- Les cookies són part del protocol HTTP. Permeten guardar galetes nom/valor mitjançant una capçalera "Set-Cookie" des del servidor (resposta), i informen el servidor de les galetes actuals mitjançant una capçalera "Cookie" des del navegador.
- El web storage és un mecanisme activable des del client exclusivament, mitjançant scripting. Tenim dos objectes, sessionStorage i localStorage, que permeten accions del tipus setItem/getItem sobre parelles nom/valor. No és un mecanisme que directament substitueixi les cookies, tot i ser semblants.
Aquestes dues tecnologies podrien emmagatzemar identificacions per accedir a aplicacions. Les cookies envien la informació directament al servidor, mentre el web storage permet gestionar la informació al client, exclusivament.
Si es tracta d'una aplicació client, aquesta informació la pot guardar el programari corresponent, i enviar-la quan calgui al servidor.
En el cas que l'identificador no estigui xifrat, és important que no sigui fàcilment deduïble per evitar que es puguin construir maliciosament (ID aleatori i llarg). JWT proporciona l'opció de xifrar la informació d'accés i autorització.
Enviament de l'identificador
A continuació, es comenten alguns possibles mètodes per a enviar l'identificador al servidor.
-
HTTP Basic Authentication utilitza una capçalera del tipus:
Authorization: Basic base64(username:password)
-
Les cookies són el mètode més clàssic, i permeten dos headers especials, un del servidor:
Set-Cookie: sessionId=shakiaNg0Leechiequaifuo6Hoochoh; path=/; Secure; HttpOnly; SameSite
i un altre des del client:
Cookie: sessionId=shakiaNg0Leechiequaifuo6Hoochoh
-
Els tokens (bearer) es passen utilitzant una capçalera:
Authorization: Bearer ujoomieHe2ZahC5b
Els tokens solen tenir un límit de validesa, i s'utilitzen sovint amb aplicacions stateless.
-
Les firmes (signatures) signen i envien les dades significatives de la petició en format formulari. Per exemple: API AWS.
-
Els certificats de client TLS realitzen un handshake abans de cap petició HTTP.
Factors combinats
L'autenticació es pot fer a partir d'alguna cosa que l'usuari sap, té o és. Podem tenir un sol factor d'autenticació, o combinar-los. És habitual tenir un doble factor d'autenticació en serveis més segurs.
Un segon factor habitual és el One-Time Password (OTP). Es poden basar en sincronització de temps o algorismes matemàtics que generen cadenes. Hi ha dues implementacions: HOTP i TOTP. La diferència és què comparteixen per generar la contrasenya: un comptador o el temps (Google Authenticator).
- El servidor crea una clau secreta per a l'usuari, i la comparteix amb un codi QR sobre una sessió segura (HTTPS).
- Les dues parts generaran l'OTP utilitzant un secure hash (tipus HMAC), i el servidor haurà de validar si és l'esperat.
La generació es fa amb aquesta fòrmula:
- hash (shared secret + counter) = HOTP
- hash (shared secret + time) = TOTP
Autorització
Un cop l'usuari ha estat autenticat, hi ha un nombre de permisos que se li assignen en funció del seu rol dins de l'aplicació. Hi ha diferents formes d'assignar-los:
- Nivell: els usuaris i les tasques tenen nivells, un usuari pot fer les tasques amb nivell igual o menor al seu.
- Usuari: es fan parelles usuari-tasca (many2many)
- Grup: un usuari té un grup, es fan parelles grup-tasca
- Responsabilitat: un usuari pot tenir diversos grups
Un cop assignats els permisos, és important fer-los efectius en cadascuna de les interaccions de l'usuari amb el sistema. Això pot fer-se tant stateless (exemple: autoritzacions dins de JWT) com stateful (emmagatzematge a la sessió del servidor).