La seguretat no és una funcionalitat que s'"afegeix al final": és una propietat transversal que ha d'estar present des de la primera línia del disseny. Això és el que significa seguretat per disseny (security by design). Un sistema que funciona, escala i està sempre disponible no serveix de res si un atacant pot robar les dades dels usuaris o suplantar-ne la identitat. En aquesta lliçó aprendràs els principis fonamentals de la seguretat (defensa en profunditat i mínim privilegi), la diferència essencial entre autenticació i autorització, els protocols moderns que les implementen (OAuth2, OIDC i JWT), les vulnerabilitats més freqüents segons OWASP i, finalment, com protegir les dades mitjançant xifratge en trànsit i en repòs.

Nota professional: el contingut d'aquesta lliçó és educatiu sobre arquitectura. Qualsevol implementació real de seguretat en un sistema de producció ha de ser revisada per especialistes en seguretat i complir la normativa aplicable (per exemple GDPR/LOPDGDD).

Contingut

  1. Principis: defensa en profunditat i mínim privilegi
  2. Autenticació vs Autorització
  3. OAuth2, OpenID Connect i JWT
  4. OWASP Top 10 resumit
  5. Xifratge en trànsit i en repòs
  6. Errors habituals i consells
  7. Exercicis

  1. Principis: defensa en profunditat i mínim privilegi

Dos principis sostenen tota arquitectura segura.

La defensa en profunditat consisteix a no confiar en una única barrera, sinó a col·locar múltiples capes de seguretat independents. Si una falla, les altres continuen protegint. És el principi del castell medieval: fossat, muralla, portes, torres.

graph LR
    A[Internet] --> F[Firewall / WAF]
    F --> G[API Gateway + Auth]
    G --> S[Validació al servei]
    S --> D[(BD amb permisos mínims)]

Cada capa del diagrama protegeix de manera independent: encara que un atacant travessi el firewall, encara ha de superar l'autenticació del gateway, la validació del servei i els permisos de la base de dades.

El mínim privilegi (least privilege) estableix que cada usuari, servei o procés ha de tenir només els permisos estrictament necessaris per a la seva funció, ni un més. Un compte de servei que només llegeix informes no ha de poder esborrar taules.

-- MALAMENT: l'aplicació fa servir un usuari totpoderós
GRANT ALL PRIVILEGES ON *.* TO 'app'@'%';

-- BÉ: només els permisos que realment necessita, sobre la base concreta
GRANT SELECT, INSERT, UPDATE ON tienda.* TO 'app'@'10.0.%';

A l'exemple "MALAMENT", si comprometen l'aplicació, l'atacant té control total de totes les bases de dades. Al "BÉ", només pot llegir i escriure a tienda, ni tan sols esborrar (DELETE), i només des de la xarxa interna 10.0.%. El dany potencial queda contingut.

  1. Autenticació vs Autorització

Aquests dos conceptes es confonen constantment, però són diferents:

Autenticació (AuthN) Autorització (AuthZ)
Pregunta Qui ets? Què pots fer?
Verifica Identitat Permisos
Passa Primer Després (ja identificat)
Exemple Iniciar sessió amb usuari i contrasenya "Pot aquest usuari esborrar factures?"
Resultat típic Un token d'identitat Permetre o denegar l'operació

La regla mnemotècnica: AuthN = autenticNació (qui ets); AuthZ = autoritZació (què pots). Sempre s'autentica primer i s'autoritza després.

Els models d'autorització més habituals són:

  • RBAC (Role-Based Access Control): els permisos s'assignen a rols (admin, editor, lector) i els usuaris reben rols. Simple i molt estès.
  • ABAC (Attribute-Based Access Control): la decisió es basa en atributs (departament, hora, ubicació, antiguitat). Més flexible i granular, però més complex.

  1. OAuth2, OpenID Connect i JWT

Aquests tres termes solen barrejar-se. La clau per no confondre's:

Tecnologia Per a què serveix Respon a
OAuth 2.0 Autorització delegada (donar accés a recursos) Què pot fer aquesta app en nom teu?
OpenID Connect (OIDC) Autenticació (capa sobre OAuth2) Qui és l'usuari?
JWT Format de token (transporta la informació) (No és un protocol, és un contenidor)

OAuth 2.0 permet que una aplicació accedeixi a recursos en nom de l'usuari sense conèixer la seva contrasenya (per exemple, "Iniciar sessió amb Google"). OIDC es construeix a sobre d'OAuth2 i afegeix la peça que li faltava: identificar l'usuari, mitjançant un ID Token. JWT (JSON Web Token) és el format més comú en què viatgen aquests tokens.

Un JWT té tres parts separades per punts: capçalera.payload.signatura.

// Capçalera (header): algorisme i tipus
{ "alg": "RS256", "typ": "JWT" }

// Payload (claims): la informació, NO xifrada, només codificada en Base64
{
  "sub": "usuario-123",        // subject: identificador de l'usuari
  "name": "Ana García",
  "roles": ["editor"],          // usat per a l'autorització
  "iat": 1718000000,            // issued at: quan es va emetre
  "exp": 1718003600             // expiration: quan caduca (1 hora després)
}

Punt crític que confon els principiants: el payload d'un JWT no està xifrat, només codificat en Base64. Qualsevol el pot llegir. El que garanteix la signatura (la tercera part) és la integritat i autenticitat: que ningú no ha modificat el contingut i que el va emetre qui diu que és. Per això mai no s'han de posar secrets en un JWT.

// Validar un JWT signat amb RS256 (clau pública/privada)
Claims claims = Jwts.parserBuilder()
    .setSigningKey(clavePublica)   // Verifiquem la signatura amb la clau pública de l'emissor
    .build()
    .parseClaimsJws(tokenRecibido) // Llança una excepció si la signatura o l'expiració no són vàlides
    .getBody();

String userId = claims.getSubject();          // Extraiem el "sub"
List<String> roles = claims.get("roles", List.class);  // i els rols per autoritzar

Aquest codi verifica que el token no ha estat manipulat (gràcies a la signatura) ni ha caducat (exp), i només llavors extreu l'identificador i els rols. Si la validació falla, llança una excepció i es rebutja la petició.

  1. OWASP Top 10 resumit

OWASP (Open Worldwide Application Security Project) publica periòdicament el Top 10 dels riscos de seguretat web més crítics. És lectura obligada. Resum de les categories principals:

# Categoria En què consisteix Mitigació clau
A01 Pèrdua de control d'accés Accedir a recursos sense permís Autorització al servidor, denegar per defecte
A02 Fallades criptogràfiques Dades sensibles mal protegides Xifrar en trànsit i repòs, no inventar criptografia
A03 Injecció (SQL, etc.) Dades malicioses com a codi Consultes parametritzades, validar entrades
A04 Disseny insegur Fallades de disseny, no de codi Modelatge d'amenaces des del disseny
A05 Configuració incorrecta Valors per defecte, errors exposats Enduriment (hardening), revisar la configuració
A06 Components vulnerables Llibreries obsoletes amb CVE Actualitzar, escanejar dependències
A07 Fallades d'autenticació Sessions febles, força bruta MFA, límits d'intents, gestió de sessió segura
A08 Fallades d'integritat Dades/codi sense verificar Signatures, verificar la cadena de subministrament
A09 Fallades de registre/monitoratge No detectar atacs Logs de seguretat, alertes, observabilitat
A10 SSRF Forçar el servidor a demanar URL internes Validar i restringir destinacions de les peticions

L'exemple clàssic és la injecció SQL (A03):

// MALAMENT: concatenar l'entrada de l'usuari directament a la consulta
String sql = "SELECT * FROM usuarios WHERE email = '" + email + "'";
// Si email = "' OR '1'='1", la consulta retorna TOTS els usuaris.

// BÉ: consulta parametritzada; el motor tracta "email" com a dada, mai com a codi
PreparedStatement ps = conn.prepareStatement(
    "SELECT * FROM usuarios WHERE email = ?");
ps.setString(1, email);   // El driver escapa el valor de manera segura

A la versió "MALAMENT", un atacant pot injectar SQL al camp email i manipular la consulta. A la "BÉ", el ? és un marcador de posició: el motor mai no interpreta el valor de l'usuari com a instruccions SQL, eliminant la vulnerabilitat d'arrel.

  1. Xifratge en trànsit i en repòs

Les dades s'han de protegir en els seus dos estats:

  • En trànsit (in transit): mentre viatgen per la xarxa. Es protegeix amb TLS (el cadenat d'HTTPS). Evita que algú que intercepti el trànsit el pugui llegir (man in the middle).
  • En repòs (at rest): mentre estan emmagatzemades al disc, base de dades o còpies de seguretat. Es protegeix xifrant l'emmagatzematge o columnes concretes.
En trànsit En repòs
Amenaça Interceptació a la xarxa Robatori del disc o backup
Tecnologia TLS / HTTPS Xifratge de disc/columna (AES)
Exemple Connexió https:// Base de dades amb xifratge transparent (TDE)
# Forçar HTTPS i redirigir tot el trànsit HTTP a Nginx
server {
    listen 80;
    return 301 https://$host$request_uri;   # Qualsevol petició HTTP es redirigeix a HTTPS
}
server {
    listen 443 ssl;
    ssl_protocols TLSv1.2 TLSv1.3;          # Només versions modernes i segures de TLS
    ssl_certificate     /etc/ssl/cert.pem;
    ssl_certificate_key /etc/ssl/key.pem;
}

Aquest fragment garanteix que mai no se serveixi contingut per HTTP sense xifrar: el primer bloc redirigeix (codi 301) tot el trànsit del port 80 a HTTPS. El segon configura TLS permetent només les versions 1.2 i 1.3 (les antigues tenen vulnerabilitats conegudes).

Una regla essencial sobre contrasenyes: mai no es xifren ni es desen en text pla; s'apliquen funcions de hash lentes i amb sal (bcrypt, scrypt, Argon2). Així, encara que robin la base de dades, no poden recuperar les contrasenyes originals.

Errors habituals i consells

  • Confiar només en el client. La validació i l'autorització del navegador o l'app mòbil es poden saltar trivialment. Tot es valida i s'autoritza al servidor.
  • Creure que el JWT està xifrat. No ho està. No posis dades sensibles al payload; qualsevol el pot llegir.
  • Inventar la teva pròpia criptografia. Gairebé sempre acaba malament. Fes servir llibreries i protocols estàndard, revisats i mantinguts.
  • Desar contrasenyes amb MD5/SHA o en clar. Fes servir funcions de hash dissenyades per a contrasenyes (bcrypt, Argon2) amb sal.
  • Missatges d'error massa detallats. Dir "l'usuari no existeix" davant de "contrasenya incorrecta" ajuda l'atacant. Respon de manera genèrica.
  • No actualitzar dependències. Les llibreries obsoletes (A06) són una de les vies d'atac més freqüents. Escaneja i actualitza.
  • Consell: pensa com un atacant. A cada entrada de dades pregunta't "què passa si això és maliciós?".

Exercicis

  1. AuthN vs AuthZ. Un usuari inicia sessió correctament però, en intentar accedir al panell d'administració, rep un error 403 (Prohibit). Va fallar l'autenticació o l'autorització? Justifica-ho.

  2. Detectar la vulnerabilitat. Revisa aquest codi i digues quin risc de l'OWASP Top 10 conté i com el corregiries:

    String consulta = "SELECT * FROM productos WHERE nombre = '" + busqueda + "'";
    statement.executeQuery(consulta);
    
  3. Decisió de xifratge. Una aplicació de missatgeria envia missatges entre usuaris i els emmagatzema a la seva base de dades. Quins tipus de xifratge necessita i per què cadascun?

Solucions

  1. Va fallar l'autorització (AuthZ), no l'autenticació. L'error 403 (Prohibit) significa que el sistema sap qui és l'usuari (es va autenticar bé, no és un 401), però aquest usuari no té permisos per accedir al panell d'administració. Si hagués fallat l'autenticació, el codi seria 401 (No autoritzat/no identificat).

  2. És injecció SQL (A03): la variable busqueda es concatena directament a la consulta, permetent que un atacant manipuli el SQL. Correcció amb consulta parametritzada:

    PreparedStatement ps = conn.prepareStatement(
        "SELECT * FROM productos WHERE nombre = ?");
    ps.setString(1, busqueda);
    ps.executeQuery();
    

    El ? impedeix que el valor de l'usuari s'interpreti com a codi SQL.

  3. Necessita tots dos. Xifratge en trànsit (TLS/HTTPS) perquè ningú no pugui interceptar els missatges mentre viatgen per la xarxa entre el dispositiu i el servidor. I xifratge en repòs per protegir els missatges emmagatzemats a la base de dades davant del robatori del disc o d'una còpia de seguretat. (Les apps més exigents afegeixen xifratge d'extrem a extrem, on ni el mateix servidor no els pot llegir.)

Conclusió

Has après que la seguretat es dissenya des del principi mitjançant capes (defensa en profunditat) i permisos mínims, que autenticar (qui ets) és diferent d'autoritzar (què pots), que OAuth2/OIDC/JWT són les peces estàndard de la identitat moderna, que l'OWASP Top 10 cataloga els riscos que has de conèixer, i que les dades es xifren tant en trànsit com en repòs. La seguretat mai no és un producte acabat: és un procés continu de prevenció, detecció i millora.

I per detectar tant atacs com problemes de rendiment necessitem veure què passa dins del sistema. A la lliçó següent, Observabilitat: Logging, Mètriques i Traçabilitat, aprendrem a instrumentar l'aplicació per entendre el seu comportament en producció.

Curs d'Arquitectura d'Aplicacions

Mòdul 1: Fonaments de l'Arquitectura d'Aplicacions

Mòdul 2: Principis i Tàctiques de Disseny

Mòdul 3: Estils i Patrons Arquitectònics

Mòdul 4: Arquitectures Distribuïdes i Microserveis

Mòdul 5: Arquitectures Dirigides per Esdeveniments i Missatgeria

Mòdul 6: Disseny Dirigit pel Domini (DDD)

Mòdul 7: Dades i Persistència

Mòdul 8: Arquitectura al Núvol i Desplegament

Mòdul 9: Qualitat, Seguretat i Observabilitat

Mòdul 10: Evolució, Governança i Casos Pràctics

© Copyright 2026. Tots els drets reservats