Link Cerca Menu Expand Document

Seguretat

Resultats d’aprenentatge (compartit amb Criptografia):

  1. Protegeix les aplicacions i les dades definint i aplicant criteris de seguretat en l’accés, emmagatzematge i transmissió de la informació.

Parlarem de la seguretat lògica (software) i activa (preventiva) associats al desenvolupament de programari.

Un sistema es pot considerar segur si ens cuidem dels següents aspectes, de més a menys significatius:

  • Disponibilitat: els usuaris poden accedir a la informació quan ho necessiten.
  • Confidencialitat: la informació és accessible només per aquells autoritzats a tenir accés.
  • Integritat: mantenir les dades lliures de modificacions no autoritzades.
  • Autenticació: verificació de la identitat.
  • No repudi: ni l’emissor ni el receptor poden negar ser part en la comunicació que es produeix.

Dins de la programació, i en referència a la seguretat, parlarem dels següents aspectes:

  • Control d’accés: registre, autenticació i autorització d’usuaris.
  • Disseny segur de programari per evitar vulnerabilitats.

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)?

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 generat, o bé pot contenir informació 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 (HMAC) i TOTP (Time). La diferència és què compateixen per generar la contrasenya: un comptador o el temps (Google Authenticator).

  1. El servidor crea una clau secreta per a l’usuari, i la comparteix amb un codi QR (és llarga).
  2. Les dues parts generaran l’OTP, 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).

Autenticació amb sessió

Autenticació amb token

Disseny segur

La seguretat ha de ser una preocupació, no una funcionalitat.

Criteris de disseny

Aquesta és una llista de possibles criteris a tenir en compte per a dissenyar codi segur:

  • El menor privilegi: una entitat només ha de tenir el conjunt necessari de permisos per realitzar les accions per a les quals estiguin autoritzades, i cap altre més.
  • Fail-Safe per defecte: el nivell d’accés predeterminat d’un usuari a qualsevol recurs del sistema hauria de ser “denegat” a menys que se’ls concedís un “permís” explícitament.
  • Economia del mecanisme: el disseny ha de ser el més simple possible. Això els fa més fàcils d’inspeccionar i confiar.
  • Mediació completa: un sistema ha de validar els drets d’accés a tots i cadascun dels seus recursos.
  • Disseny obert: els sistemes s’han de construir de forma oberta, sense secrets ni algorismes confidencials.
  • Separació de privilegis: la concessió de permisos a una entitat ha de basar-se en múltiples condicions, no només una.
  • Mecanisme menys comú: qualsevol cosa que es comparteixi entre diferents components pot ser una via de comunicació i un potencial forat de seguretat, i per tant s’han de compartir les dades mínimes possibles.
  • Acceptabilitat psicològica: els mecanismes de seguretat no haurien de fer més difícil l’accés al recurs que si no hi fossin.
  • Responsabilitat: el sistema ha de registrar qui és responsable d’utilitzar un privilegi. Si hi ha abús, podrem identificar el responsable.

Pràctiques de codificació

Aspectes tècnics que potencien la seguretat del codi:

  • Immutabilitat: ens podem estalviar problemes associats a la integritat i disponibilitat de les dades.
  • Disseny fail-fast per contractes: establint clarament quines són les precondicions i postcondicions perquè quelcom funcioni correctament.
  • Validació: validem l’origen, la mida, el context, la sintaxi i semàntica de les dades que interactuen amb el sistema. Hi ha llibreries que ajuden a aquesta tasca, com la Commons Validator.

Pràctiques a Java

  • Utilitza correctament els modificadors d’accés i redueix al màxim l’acoblament (API mínima).
  • Evita serialització, reflection i introspection.
  • No exposis credencials o informació personal, ni l’emmagatzemis al codi font o a arxius de recursos: utilitza l’entorn.
  • Utilitza llibreries conegudes i testades, segueix les vulnerabilitats de dependències de tercers i actualitza a l’última versió.
  • Utilitza sempre prepared statements (evita SQL injection).
  • No mostris informació de la implementació als missatges d’error.
  • Controla que l’entrada al sistema no causi ús desproporcionat de CPU, memòria i espai de disc.
  • Allibera els recursos sempre: fitxers, memòria, etc.
  • Comprova que no es produeixen overflows a tipus primitius, com integer (pots utilitzar addExact, multiplyExact, decrementExact ).

Eines d’anàlisi

Tenim eines dinàmiques (que executen el codi) i estàtiques (analitzen el codi sense executar-lo).

Dinàmic:

  • Integration and unit testing: cal dissenyar proves d’integració i unitàries al codi. A Java, tenim junit.
  • Code coverage: eines que serveixen per detectar quin codi s’ha executat o no, i decidir si hem d’afegir test cases. Tenim una eina de coverage a Eclipse (Java), per exemple.

Estàtic:

  • Static code analysis: permet fer anàlisi de la qualitat del codi que hem escrit, amb la detecció dels errors semàntics més habituals del llenguatge. A Java, podem utilitzar SpotBugs i les seves dues extensions, fb-contrib i find-sec-bugs.

Top 10 de controls

Segons OWASP 2018, aquest és el TOP 10 dels controls que hauria de fer un desenvolupador:

  1. Definir els requisits de seguretat de l’aplicació. Cal identificar, investigar, documentar, implementar i provar les funcionalitats a l’aplicació en relació amb els requisits. Un bon punt de partida pot ser el catàleg que hi ha a l’ASVS.
  2. Aprofitar les llibreries de seguretat existents. Fes un catàleg de les llibreries, i assegura’t que són mantingudes i actualitzades. Intenta que quedin sempre encapsulades, per si cal substituir-les.
  3. Securitzar l’accés a la base de dades. Això aplica a consultes (evitar injecció), configuració (evita el valor per defecte), autenticació (gestió d’usuaris), autorització (només la necessària) i comunicació (xifrada).
  4. Codificar i escapar les dades. Això permet que qualsevol intèrpret no llegeixi caràcters especials i permeti executar accions no previstes a l’aplicació. Pots evitar injecció i cross site scripting.
  5. Validar totes les entrades. Sempre al servidor, tan sintàcticament (format: whitelisting / blacklisting) com semàntica (valor).
  6. Implementar la identitat digital. Hem de verificar la identitat de l’usuari (autenticació), i potser mantenir el seu estat (gestió de la sessió). Ho podem fer amb contrasenyes, amb múltiples factors i amb criptografia.
  7. Obligar el control d’accés. Cal permetre o denegar l’accés de forma granular i per a totes les peticions. Criteris: denegar per defecte, el privilegi menor, evitant rols hardcoded, i registrant els esdeveniments.
  8. Protegir les dades en qualsevol lloc. Tant en trànsit (xifrat end-to-end) com en descans. En descans, si és possible, no guardar res. Als mòbils, anar amb més precaució i utilitzar sempre magatzems segurs. Als servidors, mai al codi, millor a les variables d’entorn.
  9. Implementar el registre i monitoratge de la seguretat. Ens permet utilitzar sistemes de detecció d’intrusos, fer anàlisi forensic i implementar regulacions normatives.
  10. Gestionar tots els errors i excepcions. Fa el teu codi més segur i confiable. A més, els errors poden permetre detectar intents d’atac. Fes registre, i si mostres alguna cosa a l’usuari, que no contingui dades crítiques.

Top 10 d’atacs a la web

Segons OWASP 2017:

  • Injecció: Les falles d’injecció, com SQL, NoSQL, US o LDAP ocorren quan s’envien dades no fiables a un intèrpret, com a part d’un comando o consulta. Les dades nocives de l’atacant poden enganyar a l’intèrpret perquè executi ordres involuntaris o accedeixi a les dades sense la deguda autorització.
  • Trencament de l’autenticació: Les funcions de l’aplicació relacionades a autenticació i gestió de sessions són implementades incorrectament, permetent als atacants comprometre usuaris i contrasenyes, token de sessions, o explotar altres falles d’implementació per assumir la identitat d’altres usuaris (temporal o permanentment).
  • Exposició de dades sensibles: Moltes aplicacions web i APIs no protegeixen adequadament dades sensibles, com ara informació financera, de salut o Informació Personalment Identificable (PII). Els atacants poden robar o modificar aquestes dades protegides inadequadament per dur a terme fraus amb targetes de crèdit, robatoris d’identitat o altres delictes. Les dades sensibles requereixen mètodes de protecció addicionals, com el xifrat en emmagatzematge i trànsit.
  • Entitats externes XML (XXE): Molts processadors XML antics o mal configurats avaluen referències a entitats externes en documents XML. Les entitats externes poden utilitzar-se per revelar arxius interns mitjançant la URI o arxius interns en servidors no actualitzats, escanejar ports de la LAN, executar codi de forma remota i realitzar atacs de denegació de servei (DoS).
  • Pèrdua del control d’accés: Les restriccions sobre el que els usuaris autenticats poden fer no s’apliquen correctament. Els atacants poden explotar aquests defectes per accedir, de forma no autoritzada, a funcionalitats i / o dades, comptes d’altres usuaris, veure arxius sensibles, modificar dades, canviar drets d’accés i permisos, etc.
  • Configuració incorrecta de seguretat: La configuració de seguretat incorrecta és un problema molt comú i es deu en part a establir la configuració manualment, ad hoc o per omissió (o directament per la falta de configuració). Són exemples: S3 buckets oberts, capçaleres HTTP mal configurades, missatges d’error amb contingut sensible, manca de pegats i actualitzacions, frameworks, dependències i components desactualitzats, etc.
  • Cross-Site Scripting (XSS): Els XSS ocorren quan una aplicació presa dades no fiables i els envia al navegador web sense una validació i codificació apropiada; o actualitza una pàgina web existent amb dades subministrats per l’usuari utilitzant una API que executa JavaScript al navegador. Permeten executar ordres en el navegador de la víctima i l’atacant pot segrestar una sessió, modificar els llocs web, o redireccionar a l’usuari cap a un lloc maliciós.
  • Deserialització insegura: Aquests defectes ocorren quan una aplicació rep objectes serialitzats nocius i aquests objectes poden ser manipulats o esborrats per l’atacant per a realitzar atacs de repetició, injeccions o elevar els seus privilegis d’execució. En el pitjor dels casos, la deserialització insegura pot conduir a l’execució remota de codi al servidor.
  • Utilització de components amb vulnerabilitats: Els components com biblioteques, frameworks i altres mòduls s’executen amb els mateixos privilegis que l’aplicació. Si s’explota un component vulnerable, l’atac pot provocar una pèrdua de dades o prendre el control del servidor. Les aplicacions i API que utilitzen components amb vulnerabilitats conegudes poden afeblir les defenses de les aplicacions i permetre diversos atacs i impactes.
  • Registre i monitorització insuficients: El registre i monitorització insuficient, al costat de la manca de resposta davant incidents permeten als atacants mantenir l’atac en el temps, pivotear a altres sistemes i manipular, extreure o destruir dades. Els estudis mostren que el temps de detecció d’una bretxa de seguretat és major a 200 dies, sent típicament detectat per tercers en lloc de per processos interns.

Tecnologies

Webauthn

Webauthn (Web Authentication) és un estàndar web (W3C) especificat per la FIDO Alliance que defineix una interfície per autenticar usuaris a aplicacions web i serveis mitjançant criptografia de clau pública. En el client, es pot implementar de diverses formes: purament en software, o bé mitjançant un gadget hardware, com per exemple un dispositiu USB. També Android està certificat.

El procediment té dues parts:

  • El registre: el client envia una clau pública al servidor, que la registra.
  • L’autenticació: el servidor demana al client que signi unes dades, i verifica que es poden desxifrar amb la clau pública que té registrada.

Demo

Registre de credencials

Autenticació

Oauth

OAuth és un protocol web d’autorització per concedir als llocs web l’accés a algunes de les vostres dades personals o drets d’accés a algun sistema.

L’objectiu és obtenir un token d’accés per a accedir a un recurs protegit. Hi ha quatre modalitats:

  • Propietari del recurs (resource owner): l’usuari que autoritza una aplicació a accedir al seu compte.
  • Client: l’aplicació que vol accedir al compte d’usuari.
  • Servidor de recursos (resource server): conté els comptes d’usuari.
  • Servidor d’autorització (authorization server): verifica la identitat i emet els tokens d’accés a l’aplicació.

Aquests dos servidors se solen anomenar “API del servei”.

Hi ha dos conceptes relacionats amb OAuth:

  • El registre de l’aplicació: abans d’utilitzar OAuth, cal que l’aplicació es registri al servei indicant el seu nom, l’adreça web i la redirecció URI, on el servei redireccionarà després d’autoritzar l’aplicació i on l’aplicació gestiona els tokens d’accés. El registre genera un ID de client i un secret, utilitzat per autenticar l’aplicació a l’API.
  • La concessió de l’autorització: se soporten 4 tipus a OAuth 2:
    • Codi d’autorització: el més comú, utilitzat per aplicacions servidor.
    • Implícit: utilitzat per aplicacions mòbils o web (dispositiu d’usuari).
    • Credencials de contrasenya del propietari del recurs: utilitzat per aplicacions fiables.
    • Credencials del client: utilitzat amb API d’aplicacions.

JSON Web Token (JWT)

JWT ens permet fer autorització. És un estàndar obert basat en JSON que permet crear tokens d’accés per a propagar identitat i afirmacions (claims). El token és compacte i pot ser enviat en l’entorn web perquè es pugui emmagatzemar al client. El token està signat pel servidor (amb una clau privada), per la qual cosa tant el servidor com el client poden verificar que és legítim.

Les afirmacions estàndar són:

  • iss: issuer
  • sub: subject
  • aud: audience
  • exp: expiration time
  • nbf: not before
  • iat: issued at
  • jti: JWT ID

L’autenticació basada en token es pot utilitzar per habilitar una arquitectura stateless, però també es pot utilitzar en arquitectures stateful. Per exemple, un JWT pot contenir totes les dades de sessió necessàries, codificades directament al token, en aquest cas suporta una arquitectura stateless. JWT també es pot utilitzar per emmagatzemar una referència o ID per a la sessió; en aquest cas, les dades de sessió s’ha d’emmagatzemar del costat del servidor, fent que l’arquitectura sigui stateful.

Un esquema de funcionament habitual és el d’access token/refresh token:

  • Access token: no passa pel servidor d’autenticació, es tracta només criptogràficament. Duren poc (minuts).
  • Refresh token: passa pel servidor d’autenticació. Duren més, i es poden revocar.

Referències

Seguretat:

Autenticació / autorització: