Disseny segur
- Criteris de disseny
- Pràctiques de codificació
- Verificació del codi
- OWASP Top 10
- Llista de verificació de seguretat
La seguretat ha de ser una preocupació, no una funcionalitat. Afegir-la a posteriori és costós i poc efectiu: les decisions de disseny preses al principi determinen la superfície d’atac de tot el sistema.
Aquest document s’organitza en cinc seccions progressives. Els criteris de disseny estableixen els principis fonamentals que han de guiar qualsevol decisió arquitectònica. Les pràctiques de codificació tradueixen aquests principis en hàbits concrets. La verificació del codi presenta les eines per detectar problemes. La taula OWASP Top 10 connecta riscos reals amb els controls que els prevenen. Finalment, la llista de verificació proporciona un checklist pràctic per auditar el codi abans de posar-lo en producció.
Els documents següents apliquen aquests principis en àrees específiques: Control d’accés desenvolupa el registre, l’autenticació i l’autorització d’usuaris, i Tecnologies, protocols i pràctiques cobreix les implementacions concretes de protocols i eines.
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 (per exemple, una connexió de base de dades que només necessita llegir no hauria de tenir permisos d’escriptura o eliminació).
- 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 (per exemple, un nou endpoint d’API hauria de requerir autenticació per defecte, no ser públic fins que algú recordi protegir-lo).
- Economia del mecanisme: el disseny ha de ser el més simple possible. Això els fa més fàcils d’inspeccionar i confiar (per exemple, una sola funció centralitzada de comprovació de permisos és més segura que verificacions disperses pel codi).
- Mediació completa: un sistema ha de validar els drets d’accés a tots i cadascun dels seus recursos (per exemple, comprovar permisos no només a la interfície sinó també a l’API i a la consulta SQL).
- Disseny obert: els sistemes s’han de construir de forma oberta, sense secrets ni algorismes confidencials (per exemple, la seguretat ha de dependre de les claus, no de mantenir l’algorisme en secret — principi de Kerckhoffs).
- Separació de privilegis: la concessió de permisos a una entitat ha de basar-se en múltiples condicions, no només una (per exemple, requerir MFA per a operacions crítiques, no només la contrasenya).
- 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 (per exemple, microserveis amb bases de dades separades en lloc d’una base de dades compartida).
- 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 (per exemple, passkeys que substitueixen contrasenyes oferint més seguretat amb menys fricció per a l’usuari).
- Responsabilitat: el sistema ha de registrar qui és responsable d’utilitzar un privilegi. Si hi ha abús, podrem identificar el responsable (per exemple, logs d’auditoria que registren qui ha accedit a dades sensibles i quan).
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. Existeixen llibreries de validació per a tots els llenguatges principals.
- Redueix l’acoblament i la superfície d’API exposada: utilitza els mecanismes de visibilitat del llenguatge per exposar només el mínim necessari.
- Evita mecanismes que eludeixen el sistema de tipus (serialització, reflection, introspection) tret que sigui estrictament necessari.
- No exposis credencials o informació personal al codi font o a arxius de recursos: utilitza variables d’entorn o un gestor de secrets.
- Utilitza llibreries conegudes i testades, segueix les vulnerabilitats de dependències de tercers i actualitza a l’última versió.
- Utilitza sempre prepared statements per a accés a bases de dades (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, connexions, memòria, etc.
- Preveu overflows aritmètics en operacions amb enters: utilitza les funcions de comprovació que ofereixi el teu llenguatge o llibreria estàndard.
Verificació del codi
Tenim eines dinàmiques (que executen el codi) i estàtiques (analitzen el codi sense executar-lo).
Dinàmic — DAST (Dynamic Application Security Testing):
- Proves d’integració i unitàries: cal dissenyar proves que verifiquin el comportament del codi. Cada llenguatge té els seus frameworks de test (JUnit, pytest, Jest, etc.).
- Code coverage: eines que mesuren quin codi s’ha executat durant els tests i quins camins queden sense cobrir, ajudant a decidir on cal afegir test cases.
Estàtic — SAST (Static Application Security Testing):
- Static code analysis: analitza el codi font sense executar-lo, detectant errors semàntics, patrons insegurs i vulnerabilitats. Eines com Semgrep o CodeQL són polivalents; la majoria de llenguatges tenen també eines específiques (SpotBugs per Java, Bandit per Python, clippy per Rust, etc.).
Per a una visió més completa de com integrar aquestes eines en pipelines CI/CD, vegeu la secció CI/CD Security.
OWASP Top 10
L’OWASP publica periòdicament el Top 10 de riscos de seguretat web i el Top 10 de controls proactius que tot desenvolupador hauria de conèixer. Són dues cares de la mateixa moneda: cada risc té un control que el prevé. La taula següent els relaciona i apunta a les seccions d’aquest curs on es desenvolupen en detall.
| Risc (OWASP 2025) | Control | Detall |
|---|---|---|
| Pèrdua del control d’accés | Control d’accés granular, denegar per defecte | Autorització, IDOR |
| Configuració incorrecta | Configuració segura per defecte, headers de seguretat | Security Headers |
| Fallades en la cadena de subministrament | Auditoria de dependències, SBOM, verificació d’integritat | Dependency Security, CI/CD Security |
| Fallades criptogràfiques | Xifrar dades en trànsit i en repòs amb protocols establerts | TLS/HTTPS, Secrets Management |
| Injecció | Prepared statements, validació d’entrades | Injection Attacks, Input Validation |
| Disseny insegur | Integrar seguretat des del disseny | Criteris de disseny |
| Fallades d’autenticació | MFA, gestió segura de sessions | Autenticació, Factors combinats |
| Fallades d’integritat | Verificació de dependències i pipelines | Dependency Security, SRI, CI/CD Security |
| Logging i alertes insuficients | Centralització de logs, monitoratge i alertes | Logging i Monitoring |
| Gestió incorrecta de condicions excepcionals | Errors segurs, IDs de correlació, no exposar informació interna | Gestió Segura d’Errors |
Llista de verificació de seguretat
Aquesta llista és un punt de partida per a una revisió de seguretat abans de posar en producció una aplicació. No és exhaustiva, però cobreix els controls més crítics.
Autenticació i Gestió de Sessions
- Les contrasenyes s’emmagatzemen amb un algorisme KDF (bcrypt, Argon2) amb salt
- Les contrasenyes noves es comproven contra bases de dades de filtracions conegudes (HaveIBeenPwned)
- Els missatges d’error d’autenticació són genèrics (no diferencien usuari inexistent de contrasenya incorrecta)
- Les sessions es regeneren immediatament després del login
- Les cookies de sessió tenen els flags
HttpOnly,SecureiSameSite - Hi ha un idle timeout i un absolute timeout de sessió configurats
- El logout invalida la sessió al servidor (no només elimina la cookie al client)
- MFA disponible i recomanat per als usuaris
Control d’Accés i Autorització
- Totes les peticions comproven autorització al backend, no al frontend
- Les consultes a la base de dades filtren per l’usuari autenticat (prevenció d’IDOR)
- Els rols i permisos es comproven al backend en cada petició
- El principi de privilegi mínim s’aplica a rols d’usuari i credencials de base de dades
- Cap camp sensible (rol, preu, estat) és modificable directament pel client (prevenció de mass assignment)
Validació d’Entrades i Sortides
- Totes les entrades es validen per longitud, tipus i format (whitelist)
- S’utilitzen prepared statements o ORMs per a totes les consultes SQL
- Les sortides HTML s’escapen automàticament per prevenir XSS
- Els fitxers pujats es validen pel contingut real (magic bytes), es renombren amb un UUID i s’emmagatzemen fora del web root
Gestió d’Errors i Logging
- Els errors retornats a l’usuari no contenen stack traces ni informació interna
- S’utilitzen IDs de correlació per relacionar errors d’usuari amb logs del servidor
- Les pàgines d’error per defecte del framework estan desactivades en producció
- S’enregistren els intents d’autenticació fallits, canvis de permisos i accés a recursos sensibles
Comunicació i Headers
- HTTPS és obligatori i HSTS està activat
- Les capçaleres de seguretat estan configurades: CSP,
X-Content-Type-Options,X-Frame-Options,Referrer-Policy - CORS no permet origens genèrics (
*) quan hi ha credencials implicades - La protecció CSRF està activa (tokens CSRF o cookies
SameSite)
Dependències i Configuració
- Les dependències s’escanegen per vulnerabilitats en el CI/CD
- Cap credencial ni secret està hardcoded al codi font ni al repositori
- Els secrets es gestionen via variables d’entorn o un vault
APIs (si aplica)
- El rate limiting protegeix els endpoints d’autenticació i les operacions costoses
- Els errors d’API no exposen missatges interns de base de dades ni stack traces
- La introspection de GraphQL està desactivada en producció