El mòdul anterior va acabar assenyalant una paraula que va aparèixer a les seves sis lliçons sense desenvolupar-se mai: verificar. El registre de riscos afirma que el port 5432 està exposat, el catàleg de controls promet un escaneig extern mensual que ningú no ha executat (C-10, «planificat») i el risc R-07 parla de «serveis oblidats» sense que ningú sàpiga quants n'hi ha avui. Aquesta lliçó converteix aquestes afirmacions en mesuraments: aprendràs a trobar què està exposat, decidir què s'arregla primer i demostrar que s'ha arreglat, amb eines de cost zero que caben al pressupost de Nimbus.
⚠️ Advertiment legal i d'autorització — llegeix-lo abans d'executar res
Tot el que hi ha en aquesta lliçó s'executa exclusivament sobre sistemes propis o amb autorització escrita, explícita i vigent.
- Escanejar ports o llançar un escàner de vulnerabilitats contra una màquina aliena sense autorització pot constituir delicte a Espanya (arts. 197 bis i 264 del Codi Penal). La curiositat no és una eximent.
- Al núvol has de complir a més la política de proves del proveïdor, i si el sistema l'opera un tercer —la consultora d'A-19, el proveïdor de correu, la passarel·la—, l'autorització ve de qui l'opera, no només de qui el contracta.
Tot el material treballa sobre el rang propi de Nimbus (
10.20.0.0/16a l'oficina,10.30.0.0/16al núvol) i el seu domininimbusreservas.example. No hi ha exploits ni payloads: cada troballa va amb la seva correcció. (La interpretació penal concreta depèn del cas; davant d'una prova amb impacte sobre tercers, consulta assessoria jurídica.)
Contingut
- La gestió de vulnerabilitats com a procés continu
- El mapa d'eines: què troba cada família
- Descobriment de xarxa amb nmap
- Escàner de vulnerabilitats: Greenbone/OpenVAS
- Dependències i contenidors: pip-audit i trivy
- Anàlisi estàtica de codi i escaneig de secrets
- Priorització: CVSS, EPSS, KEV i exposició
- Falsos positius, falsos negatius i validació
- Integració al cicle i mètriques del procés
- L'informe de vulnerabilitats
- La gestió de vulnerabilitats com a procés continu
Gairebé totes les pimes que «fan gestió de vulnerabilitats» fan en realitat escaneig puntual: un cop l'any algú llança una eina, exporta un PDF de 300 pàgines i l'arxiva. Això no redueix el risc: genera un document. La diferència és un cicle tancat amb verificació.
flowchart LR
I["0. INVENTARI\nQue tinc (A-01..A-22).\nSense aixo no hi ha cobertura"] --> D["1. DESCOBRIR\nnmap, escaner, SCA,\nSAST, secrets, cloud"]
D --> P["2. PRIORITZAR\nCVSS + EPSS + KEV\n+ exposicio + criticitat"]
P --> R["3. ESMENAR\nPedac, configuracio,\nmitigacio o acceptacio"]
R --> V["4. VERIFICAR\nReescanejar i TANCAR\namb evidencia"]
V --> N["5. INFORMAR\nMetriques i tendencia\n(KPI de 04-03)"]
N --> D
V -.->|"si no es corregeix"| E["EXCEPCIO amb caducitat\nal registre de riscos 04-01"]
Cinc regles separen el procés del teatre:
- El pas 0 no és opcional. Un escaneig sobre 12 màquines quan en tens 18 no troba res a les altres 6: la cobertura és la primera mètrica, no l'última.
- L'alimenten diverses eines, no una. Cap família no veu més del 30 % del problema.
- Prioritzar no és ordenar per CVSS. És la part que més valor aporta i la que gairebé ningú no fa bé (§7).
- Una troballa es tanca quan la nova passada d'escaneig ja no la troba, no quan algú diu que l'ha arreglada: aquesta és l'evidència auditable de 04-03. I el que no es corregeix es converteix en excepció amb caducitat (04-02), no en una fila que envelleix en silenci.
Precisió d'01-01: una versió d'OpenSSL amb CVE és una vulnerabilitat; que aquest servei escolti a Internet és l'exposició; el risc combina totes dues amb la criticitat de l'actiu. Una de crítica en una màquina apagada no és una urgència; una de mitjana a l'API pública que arriba a A-01 sí.
- El mapa d'eines: què troba cada família
| Família | Què troba / què no veu | Lliures | Comercial | On |
|---|---|---|---|---|
| Descobriment de xarxa | Hosts, ports, serveis i versions · no veu res dins de l'aplicació | nmap, masscan |
Runzero, Censys | §3 i 05-04 |
| Escàner d'infraestructura | CVE de sistema i serveis · no veu errors de negoci ni codi propi | Greenbone/OpenVAS, Nuclei | Nessus, Qualys | §4 |
| Escàner web dinàmic (DAST) | Injeccions, XSS, capçaleres · no veu codi no assolible per la interfície | OWASP ZAP, Nikto, testssl.sh |
Burp Pro, Invicti | 05-05 i 05-03 |
| Composició de programari (SCA) | CVE en dependències · no veu errors al teu propi codi | pip-audit, grype, osv-scanner |
Snyk, Mend | §5 |
| Anàlisi estàtica (SAST) | Patrons insegurs al codi propi · no veu el que depèn de l'entorn | semgrep, bandit, CodeQL |
Checkmarx, Fortify | §6 i 05-05 |
| Escàner de secrets · de contenidors | Claus a l'historial de git · CVE de la imatge i males pràctiques del Dockerfile |
gitleaks · trivy, grype |
GitGuardian · Aqua | §5-§6, 05-05 i 05-07 |
| Configuració cloud i IaC | Buckets públics, permisos excessius, xifratge absent · no veu l'aplicació | prowler, ScoutSuite, checkov, tfsec |
Wiz, Orca | 05-07 |
| Configuració del sistema | Desviació respecte d'una línia base CIS · no veu CVE d'aplicació | lynis, OpenSCAP |
Tenable | 05-06 |
La columna important és «què no veu». L'IDOR que Nimbus va corregir amb WHERE tenant_id no el troba cap d'aquestes famílies: no és una versió antiga ni un patró evident, és una fallada d'autorització que exigeix entendre el negoci. Per això l'escaneig es complementa amb revisió de codi (05-05) i proves manuals (05-03), i per això cap escàner no pot signar que un sistema és segur.
- Descobriment de xarxa amb nmap
nmap respon a la pregunta que Nimbus no sap contestar: què hi ha escoltant aquí fora i aquí dins?
# 1) Quines maquines estan vives a la VLAN d'usuaris de Valencia
sudo nmap -sn 10.20.10.0/24 -oA /var/log/nimbus-scan/oficina-hosts
# 2) Superficie completa de la VPC, executat DES DEL bastio
sudo nmap -sS -sV --version-intensity 5 -p- --max-retries 2 -T4 --open \
-oA /var/log/nimbus-scan/vpc-intern 10.30.10.0/24 10.30.20.0/24 10.30.90.0/24
# 3) La mateixa infraestructura vista des d'INTERNET
nmap -Pn -sV --top-ports 1000 --reason -oA /var/log/nimbus-scan/extern \
api.nimbusreservas.example preprod.nimbusreservas.example| Opció | Què fa | Per què importa aquí |
|---|---|---|
-sn / -sS |
Descobrir hosts sense escanejar ports / SYN scan que no completa la connexió | El primer es compara amb l'inventari d'01-04; el segon és ràpid i fiable, i requereix privilegis |
-sV |
Interroga el servei per deduir producte i versió | Converteix «5432 obert» en «PostgreSQL 14.7», que és el que es creua amb les CVE |
-p- / --top-ports 1000 |
Els 65.535 ports / els més utilitzats | El python -m http.server escoltava al 8000, fora del top 1000; però un -p- extern triga hores i es reserva per a la passada mensual |
-Pn |
No comprovar si el host viu abans d'escanejar | Obligatori des d'Internet: gairebé tot bloqueja ICMP i sense -Pn no trobaries res |
-T4 |
Plantilla de temporització agressiva (0-5) | Equilibri en xarxa pròpia; T5 perd precisió i T1-T2 són per no disparar deteccions |
--reason / -oA |
Per què classifica així cada port / desa en els tres formats | Distingeix «filtrat» de «tancat»; i sense la sortida anterior no hi ha diferencial, que és el 90 % del valor |
Sortida real de l'escaneig extern:
Nmap scan report for preprod.nimbusreservas.example (203.0.113.47)
PORT STATE SERVICE REASON VERSION
22/tcp open ssh syn-ack OpenSSH 8.9p1 Ubuntu 3ubuntu0.1
443/tcp open ssl/http syn-ack nginx 1.18.0 (Ubuntu)
5432/tcp open postgresql syn-ack PostgreSQL DB 14.7 - 14.9
6379/tcp open redis syn-ack Redis key-value store 6.0.16
8000/tcp open http syn-ack SimpleHTTPServer 0.6 (Python 3.10.6)
Nmap scan report for api.nimbusreservas.example (203.0.113.20)
443/tcp open ssl/http syn-ack nginx 1.24.0
22/tcp filtered ssh no-responseLes troballes d'01-04, ara mesurades i amb data: 5432 accessible des d'Internet confirma R-03 (només el protegeix una contrasenya); 6379 amb Redis sense autenticació és R-07; 8000 és el python -m http.server oblidat durant 94 dies; i el contrast entre 22/tcp open a preproducció i filtered a producció demostra que a producció sí que hi ha una regla i a preproducció no. A-22 és avui el baula més feble de Nimbus.
Calen els dos punts de vista i mesuren coses diferents. L'extern (mensual automatitzat, control C-10) mesura la superfície que veu un atacant d'Internet, és a dir, l'exposició. L'intern (trimestral, des del bastió i des de la VLAN d'usuaris) mesura el que abasta qui ja és dins o un portàtil compromès, i per tant revela fallades de segmentació i moviment lateral: és el que hauria descobert, abans de l'incident, que des de la xarxa d'administració s'arribava a la zona de dades sense control intermedi (dia 1-4 de 02-06).
- Escàner de vulnerabilitats: Greenbone/OpenVAS
nmap diu què hi ha; l'escàner diu què li passa al que hi ha. Greenbone Community Edition (l'antic OpenVAS) és gratuït i suficient per a Nimbus. Només fa dues coses, i convé no atribuir-li màgia:
- Comparar versions contra una base de vulnerabilitats. És ràpid i és la font de gairebé tots els falsos positius: les distribucions apliquen pedaços sense apujar el número visible (backporting).
- Comprovacions actives: envia una petició i observa la resposta —si accepta TLS 1.0, si un tauler respon amb credencials per omissió—. Més lent i molt més fiable.
# Definir objectiu i tasca, i llancar-la; tot automatitzable des de cron
gvm-cli socket --xml '<create_target><name>VPC produccio</name>
<hosts>10.30.10.0/24,10.30.20.0/24</hosts></create_target>'
gvm-cli socket --xml '<create_task><name>Mensual autenticat</name>
<config id="daba56c8-73ec-11df-a475-002264764cea"/><target id="TARGET_ID"/></create_task>'
gvm-cli socket --xml '<start_task task_id="TASK_ID"/>'El config id és la plantilla d'escaneig (Full and fast equilibra cobertura i temps). Un escàner que s'ha de llançar a mà es llança dues vegades l'any: es programa o no existeix.
Autenticat davant de no autenticat
| No autenticat | Autenticat | |
|---|---|---|
| Com funciona | Sondeja des de fora i dedueix | Entra per SSH i llegeix el sistema per dins |
| Què veu | Serveis exposats i els seus banners | Tots els paquets, pedaços, configuració, usuaris |
| Troballes per servidor Linux | 8-15 | 60-150 |
| Falsos positius | Molts (per backporting) | Pocs: compara la versió real del paquet |
| Risc | Cap | La credencial de l'escàner és un actiu crític |
Troba molt més perquè deixa d'endevinar: sense credencials no veu una biblioteca vulnerable que no escolta en cap port, i la majoria de les vulnerabilitats del sistema són exactament això. Per a Nimbus: compte svc-scanner sense sudo, clau Ed25519 dedicada (03-06), origen restringit i rotació semestral.
== Informe Greenbone · Escaneig mensual autenticat · 2026-04-06 ==
6 hosts analitzats · 1h42m · 3 Alt · 11 Mitja · 24 Baix · 63 Log
[10.0] 10.30.90.7 Redis sense autenticacio accessible a la xarxa
Comprovacio ACTIVA: s'ha executat INFO sense credencials QoD 99%
Solucio: requirepass + bind 127.0.0.1 + grup de seguretat
[9.8] 10.30.20.5 PostgreSQL accessible des de 0.0.0.0/0
Comprovacio ACTIVA: connexio establerta des d'origen extern QoD 98%
[7.5] 10.30.10.11 OpenSSL 3.0.2-0ubuntu1.9 - CVE-2026-1000
Comprovacio de VERSIO del paquet (escaneig autenticat) QoD 97%
[5.3] 10.30.10.11 nginx 1.18.0 - multiples CVE
Comprovacio de VERSIO per banner remot QoD 30%
^-- baixa confianca: probable backport de la distribucioTres claus de lectura: QoD (Quality of Detection) és el camp més útil i el més ignorat —99 % amb comprovació activa és un fet, 30 % per banner és una hipòtesi, així que es comença per QoD alt i no per CVSS alt—; els 63 «Log» no són soroll, són inventari per a 01-04; i un informe sense troballes només significa que l'escàner no ha trobat res del que sap cercar: l'IDOR d'A-04 no hi apareixerà mai.
- Dependències i contenidors
El 80 % del codi que executa l'API no el va escriure l'Iván: són dependències. És la superfície que més creix i la més barata de mesurar.
--requirement audita les dependències fixades del projecte (sense ella audites la màquina) i --strict falla també si alguna cosa no s'ha pogut analitzar: tractar un «no ho sé» com un «està bé» és l'arrel dels falsos negatius.
Found 3 known vulnerabilities in 2 packages
Name Version ID Fix Versions
jinja2 3.1.2 GHSA-h5c8-rqwp-cp95 3.1.3
requests 2.28.1 GHSA-j8r2-6x86-q33q 2.31.0
requests 2.28.1 GHSA-9wx4-h78v-vm56 2.32.0La de requests és la rellevant: l'API crida la passarel·la i el proveïdor de correu amb aquesta biblioteca. La de jinja2 només afecta plantilles del tauler intern. Mateixa severitat nominal, prioritat molt diferent.
trivy image --severity HIGH,CRITICAL --ignore-unfixed \
--scanners vuln,secret,misconfig --format table \
registry.nimbus.example/api:2026.04.1--severity HIGH,CRITICAL filtra el soroll (una imatge base típica llança 300 troballes baixes, i incloure-les garanteix que no se'n miri cap); --ignore-unfixed amaga el que encara no té pedaç, i és l'opció més discutible —política de Nimbus: usar-la al CI per no bloquejar per una cosa irresoluble i no usar-la a l'informe mensual—; i --scanners vuln,secret,misconfig afegeix secrets a les capes i males pràctiques del Dockerfile: tres eines pel preu d'una.
registry.nimbus.example/api:2026.04.1 (debian 12.4) Total: 14 (HIGH 12, CRITICAL 2)
┌───────────┬───────────────┬──────────┬───────────────┬──────────────┐
│ libssl3 │ CVE-2026-1000 │ CRITICAL │ 3.0.11-1 │ 3.0.13-1 │
│ zlib1g │ CVE-2026-1001 │ HIGH │ 1:1.2.13.dfsg │ 1:1.2.13-1+u1│
│ perl-base │ CVE-2026-1002 │ HIGH │ 5.36.0-7 │ (no fixat) │
└───────────┴───────────────┴──────────┴───────────────┴──────────────┘
Secret api/.env.sample AWS Access Key ID (linia 4) <-- revisarVulnerabilitat present ≠ vulnerabilitat explotable. perl-base és a la imatge perquè l'arrossega la base de Debian, però l'API no executa mai Perl: està present i no és abastable. Dos conceptes ho formalitzen:
- Abastabilitat: hi ha un camí d'execució des del codi de Nimbus fins a la funció vulnerable? Analitzar-ho descarta fins al 70 % de les troballes.
- VEX (Vulnerability Exploitability eXchange): document signat en què declares, per CVE i producte, si t'afecta (
affected,not_affected,fixed,under_investigation) i per què.
Nimbus emet el seu VEX juntament amb l'SBOM de 04-04: quan una clínica pregunti per una CVE famosa, la resposta serà un document i no una trucada d'urgència. La resposta a una troballa no explotable no és ignorar-la, és documentar-la. I la via més eficaç per reduir-ne el nombre és canviar a una imatge base mínima o distroless (05-07), que elimina de cop el 80 % d'aquestes línies.
- Anàlisi estàtica de codi i escaneig de secrets
bandit -r app/ -ll -f json -o /tmp/bandit.json
semgrep --config=p/python --config=p/security-audit --sarif -o /tmp/semgrep.sarif app/-ll limita a severitat mitjana o superior; --sarif produeix el format estàndard que GitHub mostra a la seva pestanya de seguretat. Troballa real al codi de Nimbus:
>> Issue: [B501:request_with_no_cert_validation] Requests call with verify=False
Severity: High Confidence: High CWE-295 app/integrations/pasarela.py:44# ABANS — el `verify=False` que va apareixer al modul 2. Desactiva la validacio
# del certificat: qualsevol a la ruta pot interposar-s'hi i llegir o alterar la
# peticio de pagament. TLS sense validacio no protegeix de res (03-05).
r = requests.post(URL_PASSARELA, json=payload, verify=False, timeout=10)
# DESPRES — validacio activa i confianca acotada de forma explicita.
r = requests.post(
URL_PASSARELA,
json=payload,
verify="/etc/ssl/certs/ca-certificates.crt", # cadena de confianca explicita
timeout=(3.05, 10), # connexio i lectura per separat
)
r.raise_for_status()El SAST encerta aquí perquè verify=False és un patró textual inequívoc, i falla amb l'IDOR perquè saber que hi falta WHERE tenant_id exigeix entendre el model de dades. Regla: troba errors de patró, no errors de raonament. A 05-05 escriuràs una regla semgrep pròpia que sí que detecta el patró concret de Nimbus.
--log-opts="--all" és l'opció crítica: sense ella només mira l'arbre actual; amb ella recorre tots els commits i branques. Un secret esborrat l'endemà continua a l'historial i continua sent vàlid.
Finding: DATABASE_URL=postgresql://nimbus_api:[email protected]:5432/nimbus
RuleID: postgres-connection-string
File: deploy/docker-compose.override.yml
Commit: a91f3c7 (2024-11-02) Author: [email protected]És el risc R-06 i l'escalada del dia 5 de 02-06. Correcció en aquest ordre: (1) rotar la credencial avui —està compromesa des del 2024 i esborrar el fitxer no la invalida; és el pas urgent i el que gairebé tothom posposa—; (2) moure-la al gestor de secrets (03-06); (3) reescriure l'historial amb git filter-repo, que és cosmètica comparada amb el pas 1; i (4) gitleaks com a hook de pre-commit i pas bloquejant del CI (control C-12).
- Priorització: CVSS, EPSS, KEV i exposició
Aquí el procés es guanya el sou. Un escaneig de Nimbus produeix ~180 troballes i la Lucía té 440 h/any per a tot. Ordenar per CVSS descendent és l'error més estès del sector.
| Grup CVSS | Què mesura | Qui el calcula |
|---|---|---|
| Base | Gravetat intrínseca i invariable | El fabricant o el NVD (9.8 per execució remota sense autenticació) |
| Temporal (Amenaça a la v4) | Si hi ha exploit públic i si hi ha pedaç | S'actualitza amb el temps: 9.8 baixa a 8.5 sense exploit conegut |
| Ambiental | El teu entorn: criticitat de l'actiu i controls presents | Només tu: 9.8 en una màquina aïllada baixa a 4.0 |
El grup ambiental és el que converteix una llista genèrica en una llista teva, i l'únic que ningú no pot calcular per tu. S'hi sumen dos senyals externs:
- EPSS (FIRST): probabilitat que una CVE sigui explotada els propers 30 dies, de 0 a 1, actualitzada diàriament. Més del 90 % de les CVE tenen EPSS < 0,05; una minoria concentra gairebé tota l'explotació real.
- KEV (CISA): catàleg de vulnerabilitats amb explotació confirmada al món real. No és predicció, és un fet observat; la llista és curta i consultar-la és gratis.
Regla operativa de Nimbus: tot el que sigui a KEV i sigui accessible es tracta com a crític, tingui el CVSS que tingui. Una de 7.5 a KEV és més urgent que una de 9.8 amb EPSS 0,001.
| Prioritat | Criteri | Termini |
|---|---|---|
| P0 Emergència | A KEV i exposat a Internet, o compromís actiu | 24 h, fora de finestra si cal |
| P1 Crítica | CVSS ≥ 9.0 o EPSS ≥ 0,10 sobre actiu crític accessible | 7 dies (coincideix amb C-16) |
| P2 Alta | CVSS 7.0-8.9 sobre actiu crític, o KEV no exposat | 30 dies |
| P3 Mitjana | CVSS 4.0-6.9, o alta sobre actiu no crític | 90 dies |
| P4 Baixa | CVSS < 4.0 o no abastable (documentat a VEX) | Cicle següent o excepció amb caducitat |
Els terminis compten des del descobriment, no des de la publicació de la CVE. I si un P1 no arriba a termini no es reetiqueta a P2: s'obre una excepció signada (04-02). Rebaixar la prioritat perquè el quadre de comandament quedi verd és la forma més comuna de corrompre el procés.
"""Ordena troballes combinant gravetat, explotacio real i exposicio."""
TROBALLES = [ # id, cvss, epss, kev, exposat, actiu, criticitat(1-5)
("CVE-2026-1000", 9.8, 0.72, True, True, "A-04 API", 5),
("CVE-2026-1002", 8.1, 0.004, False, False, "A-04 (perl)", 5),
("REDIS-SENSE-AUTH",10.0, 0.90, True, True, "A-22 preprod", 2),
("CVE-2026-1010", 7.5, 0.31, True, False, "A-01 BD", 5),
("CVE-2026-1044", 9.1, 0.002, False, False, "A-14 portatils", 3),
]
def prioritat(cvss, epss, kev, exposat, criticitat):
base = cvss / 10.0 # 1) gravetat normalitzada
explotacio = 1.0 if kev else min(1.0, epss * 3) # 2) KEV es FET; EPSS, matis
exposicio = 3.0 if exposat else 1.0 # 3) abastable triplica urgencia
importancia = criticitat / 5.0 # 4) inventari de 01-04
return round(base * (0.3 + 0.7 * explotacio) * exposicio * importancia, 3)
files = [(prioritat(c, e, k, x, cr), i, a) for i, c, e, k, x, a, cr in TROBALLES]
for p, ident, actiu in sorted(files, reverse=True):
termini = "24 h" if p >= 2.0 else "7 dies" if p >= 1.0 else "30 dies" if p >= 0.4 else "90 dies"
print(f"{p:>6} {ident:<16} {actiu:<18} -> {termini}") 2.940 CVE-2026-1000 A-04 API -> 24 h
2.250 CVE-2026-1010 A-01 BD -> 24 h
1.200 REDIS-SENSE-AUTH A-22 preprod -> 7 dies
0.257 CVE-2026-1002 A-04 (perl) -> 90 dies
0.230 CVE-2026-1044 A-14 portatils -> 90 diesEl que revela el resultat: REDIS-SENSE-AUTH té el CVSS més alt (10.0) i cau al tercer lloc per viure en un actiu de criticitat 2; CVE-2026-1044 té 9.1 —més que la 1010, de 7.5— i queda l'última perquè ni és a KEV, ni és abastable, ni afecta un actiu crític. Ordenar per CVSS hauria posat la Lucía a treballar tres dies en les dues vulnerabilitats menys urgents. Avís honest: que A-22 tingui criticitat 2 és la classificació documentada, i l'inventari admet que està «a revisar». Si preproducció té còpia de dades reals, la seva criticitat és 5 i el Redis puja al primer lloc: revisar aquella cel·la és més rendible que qualsevol escaneig.
- Falsos positius, falsos negatius i validació
| Definició | Cost | Exemple a Nimbus | |
|---|---|---|---|
| Fals positiu | Reporta una cosa que no existeix o no s'aplica | Temps i pèrdua de credibilitat del procés | nginx 1.18.0 marcat malgrat el backport d'Ubuntu |
| Fals negatiu | No reporta una cosa que sí que existeix | Risc real no gestionat | L'IDOR, que cap escàner no va detectar |
Validació d'una troballa, en ordre de cost: (1) comprovar la versió real del paquet (dpkg -l | grep nginx) resol el 60 % dels falsos positius d'infraestructura; (2) llegir l'avís de la distribució (USN d'Ubuntu, DSA de Debian), que diu si aquella versió ja està corregida; (3) comprovar l'abastabilitat; (4) reproduir de forma no destructiva només si persisteix el dubte —verificar que un port respon o que falta una capçalera, mai explotar en producció: aquesta conversa és de 05-03—; i (5) documentar la decisió, apta o no, perquè un fals positiu tancat sense registrar reapareix cada mes i costa el mateix cada vegada.
Un escàner no substitueix mai el criteri. No sap que A-01 conté historials que revelen informació de salut, ni que A-19 té accés permanent, ni que preproducció potser té dades reals, ni pot trobar una fallada d'autorització. Mesura versions i configuracions: el risc el posa el context, i el context el posa una persona. Això s'escriu a la declaració de limitacions de l'informe (§10).
- Integració al cicle i mètriques del procés
| Moment | Què s'executa | Durada | Bloqueja? |
|---|---|---|---|
| Cada pull request | gitleaks, semgrep, pip-audit |
< 3 min | Sí: secrets i crítiques noves |
| Cada desplegament | trivy sobre la imatge final |
< 2 min | Sí, segons llindar |
| Setmanal | ZAP baseline contra preproducció (05-05) | 20 min | No: informa |
| Mensual (C-10) | nmap extern + Greenbone autenticat + prowler (05-07) |
2-4 h | No: troballes amb propietari |
| Després de canvis d'infra. | nmap extern diferencial |
10 min | No: alerta de port nou |
L'últim és el més barat i el més infravalorat: comparar l'escaneig d'avui amb el d'ahir i avisar només del que és nou és el que hauria detectat el http.server el mateix dia, i no 94 dies després.
# .github/workflows/seguretat.yml
name: Analisi de seguretat
on:
pull_request:
push: { branches: [main] }
schedule: [{ cron: "0 5 * * 1" }] # dilluns: captura CVE noves SENSE canvis de codi
permissions: { contents: read, security-events: write }
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with: { fetch-depth: 0 } # historial COMPLET: sense aixo gitleaks no veu el passat
- uses: gitleaks/gitleaks-action@v2 # BLOQUEJANT: un secret no es negocia mai
- name: Dependencies Python
run: |
pip install pip-audit
pip-audit -r requirements.txt --strict --format json -o pip-audit.json || true
# `|| true` deixa que el llindar l'apliqui LA NOSTRA politica, no el binari
- run: python ci/llindar.py pip-audit.json --fallar-si CRITICAL,HIGH-KEV
- run: docker build -t nimbus/api:${{ github.sha }} .
- uses: aquasecurity/trivy-action@master
with:
image-ref: nimbus/api:${{ github.sha }} # la imatge d'AQUEST commit, no :latest
severity: CRITICAL,HIGH
ignore-unfixed: true # no bloquejar pel que encara no te pedac
exit-code: "1" # 1 = build trencat si queda res per sobre del llindar
format: sarif
output: trivy.sarif
- if: always() # publicar TAMBE quan el pas anterior falla
uses: github/codeql-action/upload-sarif@v3
with: { sarif_file: trivy.sarif }El principi de disseny: bloquejar el que és accionable i informar del que no ho és. Un pipeline que trenca el build per troballes que ningú no pot corregir acaba desactivat en dues setmanes, i llavors no protegeix de res. I el criteri de fallada el decideix Nimbus (ci/llindar.py), no una eina que canvia de versió: externalitzar-lo és cedir el govern del risc.
| Mètrica | Tipus | Objectiu | Què revela en fallar |
|---|---|---|---|
| Cobertura de l'escaneig | KPI | 100 % | Mira-la primer: la resta de mètriques menteixen si no és 100 %. És la que més sorpreses dona: sol revelar que el 30 % no cobert era preproducció |
| MTTR per prioritat | KRI | P1 ≤ 7 d · P2 ≤ 30 d | Capacitat insuficient o procés d'aplicació de pedaços trencat |
| Crítiques obertes fora de termini | KRI | 0 | És la xifra del comitè: si creix, cal invertir o acceptar formalment |
| Taxa de reobertura i % tancats amb nova passada d'escaneig | KPI | < 5 % · 100 % | Es tanca sense verificar: «tancat» significa «algú va dir que sí» |
- L'informe de vulnerabilitats
| Destinatari | Què necessita | Extensió |
|---|---|---|
| Marta (direcció) | Risc de negoci, tendència i quina decisió se li demana | 1 pàgina: semàfor, 3 xifres, 1 petició |
| Lucía (sistemes) | Què toca, en quina màquina, amb quina ordre i per a quan | Taula ordenada per prioritat |
| Iván (desenvolupament) | Fitxer, línia, correcció i prova de regressió | Issues al repositori, no un PDF |
| Client o auditor (06-04) | Que hi ha procés, cadència i evidència | 1-2 pàgines sense detall explotable |
Estructura de l'informe mensual: resum executiu, abast i limitacions, metodologia i versions de les eines, troballes prioritzades, tendència, tancats i verificats, i annex tècnic. Les limitacions són el que protegeix honestament el lector: diuen què no es va escanejar i quines fallades aquestes eines no troben.
### VUL-2026-014 · PostgreSQL de produccio accessible des d'Internet
- **Prioritat:** P0 (KEV no · CVSS 9.8 · **exposat** · actiu A-01, criticitat 5)
- **Actiu:** `db-prod-1` (10.30.20.5) · **Risc associat:** R-03 (04-01)
- **Descobert:** 2026-04-06, escaneig extern mensual (C-10) · **Termini:** 2026-04-07
**Descripcio.** El grup de seguretat permet 5432/tcp des de `0.0.0.0/0`. Qualsevol
equip d'Internet pot intentar autenticar-se; l'unica proteccio es la contrasenya
del rol `nimbus_api`, sense limit d'intents.
**Evidencia.**
$ nmap -Pn -p 5432 -sV 203.0.113.47
5432/tcp open postgresql PostgreSQL DB 14.7 - 14.9 (syn-ack)
**Impacte en el negoci.** Acces a les dades de 40 cliniques, inclosos historials
que revelen indirectament informacio de salut. Equival al dia 5 de 02-06. Bretxa
notificable sota RGPD (06-03).
**Correccio.** Restringir la regla d'entrada a `10.30.10.0/24`. Sense finestra de
manteniment: l'API connecta per la ruta interna. **Esforc: 20 minuts.**
**Verificacio.** Nova passada d'escaneig extern del 5432; estat esperat `filtered`,
mes prova de fum de l'API. **Propietari:** Lucia · **Estat:** ObertEls cinc elements que converteixen una troballa en accionable: evidència reproduïble, impacte de negoci i no només tècnic, correcció concreta amb esforç estimat, criteri de verificació explícit i un propietari amb nom. L'error més freqüent és lliurar el bolcat de l'eina: 300 pàgines sense prioritzar que garanteixen que no es corregeixi res, perquè ningú no sap per on començar.
Errors Comuns i Consells
- Escanejar un cop l'any i dir-ne gestió de vulnerabilitats. L'inventari canvia cada setmana; millor mensual, automatitzat i revisat.
- Ordenar per CVSS i començar per dalt. Sense exposició, EPSS/KEV i criticitat de l'actiu dedicaràs el temps al que menys importa. És l'error més car de la lliçó.
- Escanejar sense credencials «per no molestar». Perds entre el 70 i el 85 % de les troballes del sistema; l'escaneig autenticat és la millora individual més rendible.
- Oblidar preproducció. A-22 té avui més ports oberts que producció. L'atacant no distingeix entorns: distingeix portes.
- Bloquejar el CI amb llindars impossibles, o tancar troballes sense verificar. El primer acaba amb el pipeline desactivat; el segon converteix «tancat» en «algú va dir que sí». Vigila la taxa de reobertura.
- Consell: comença pel diferencial. Abans de muntar Greenbone, automatitza un
nmapextern setmanal que compari amb l'anterior i desa sempre la sortida crua amb data (-oA, JSON, SARIF): és la teva sèrie històrica, i sense tendència no hi ha conversa amb direcció. Mitja hora de feina que hauria evitat dues de les quatre troballes d'01-04. - Consell: si només recordes una regla, que sigui aquesta. Una CVE a KEV i exposada es tracta avui.
Exercicis
Exercici 1 — Interpretar un escaneig i decidir l'ordre de treball
La Lucía llança el primer escaneig extern mensual i obté:
Nmap scan report for pruebas-2019.nimbusreservas.example (203.0.113.61)
80/tcp open http Apache httpd 2.4.29 ((Ubuntu))
443/tcp open ssl/http Apache httpd 2.4.29
3306/tcp open mysql MySQL 5.7.33- Què cal esbrinar sobre
pruebas-2019abans fins i tot de mirar les versions? - Ordena les accions de la primera setmana justificant l'ordre amb els criteris de §7.
- Què li falta a aquest escaneig perquè el procés sigui complet?
Exercici 2 — Prioritzar cinc troballes
Ordena i assigna termini segons la política de §7, justificant cada decisió:
| # | Troballa | CVSS | EPSS | KEV | Exposat | Actiu |
|---|---|---|---|---|---|---|
| A | RCE en biblioteca d'imatges del tauler intern | 9.8 | 0.02 | No | No | A-04 (crític) |
| B | Redis sense autenticació a preproducció | 10.0 | 0.90 | Sí | Sí | A-22 (a revisar) |
| C | TLS 1.0 en un subdomini de màrqueting | 5.3 | 0.01 | No | Sí | Web estàtica |
| D | Credencial de PostgreSQL a l'historial de git des del 2024 | — | — | — | — | A-10, A-01 |
| E | Escalada local al kernel dels portàtils | 7.8 | 0.15 | Sí | No | A-14 |
Exercici 3 — Corregir un pipeline
Identifica almenys cinc problemes a la proposta de l'Iván i explica com es corregeix cadascun.
name: seguretat
on: { workflow_dispatch: {} }
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: gitleaks detect --source .
- run: trivy image nimbus/api:latest --exit-code 1
- run: pip-auditSolucions
Exercici 1
(1) La primera pregunta no és tècnica, és d'inventari: què és pruebas-2019, qui el va posar, quines dades conté i encara cal? Aquest nom suggereix un entorn de fa set anys que ningú no manté i que no és a l'inventari d'01-04 ni a l'abast de cap aplicació de pedaços. Si ningú no ho sap, la correcció no és aplicar-hi pedaços: és apagar-lo després de confirmar que res no en depèn, conservant-ne una còpia. Apagar és la correcció més barata, més ràpida i més definitiva que existeix, i la que menys es considera.
(2) Ordre de la primera setmana:
- MySQL 3306 exposat (P0, 24 h). És el patró de R-03 però pitjor: base de dades accessible des d'Internet en un host sense manteniment des del 2019, amb credencials probablement febles. Es tanca al tallafoc avui, abans d'investigar res.
- Determinar si conté dades personals reals (P0, en paral·lel). Si en conté i feia anys que estava exposat, deixa de ser una troballa tècnica: és una possible bretxa amb obligacions del RGPD (06-03) i activació del pla de 04-05.
- Apagar el host (P1, 7 dies) un cop confirmat que res no en depèn. Apache 2.4.29 acumula anys de CVE: aplicar-hi pedaços és invertir en una cosa que ha de desaparèixer.
- Afegir-lo a l'inventari i revisar el DNS cercant més subdominis oblidats: que aparegués en un escaneig i no a l'inventari significa que la cobertura no era del 100 %.
(3) Què falta: l'escaneig només mira els ports habituals de noms que algú recordava. Falten l'enumeració de subdominis des de la zona DNS, un -p- mensual (el http.server del 8000 no surt a --top-ports 1000), escaneig UDP bàsic, escaneig intern des de la VLAN d'usuaris i des de la VPC per mesurar la segmentació, i les capes que nmap no cobreix: escàner autenticat, SCA, SAST i configuració cloud. nmap és el 15 % del procés.
Exercici 2
| Ordre | # | Prioritat | Termini | Justificació |
|---|---|---|---|---|
| 1r | D | P0 | 24 h | No té CVSS perquè no és una CVE, i és el més greu: una credencial vàlida de la base de dades crítica, exposada des del 2024. No cal explotar res, n'hi ha prou amb usar-la. És R-06 i el dia 5 de 02-06. Rotar avui; netejar l'historial pot esperar |
| 2n | B | P0 | 24 h | KEV + EPSS 0,90 + exposat: els tres factors al màxim. La baixa criticitat nominal d'A-22 no el rescata, perquè està «a revisar» i probablement comparteix xarxa o dades amb producció. Tancar el port són minuts |
| 3r | E | P2 | 30 dies | És a KEV, l'explotació és real, però és escalada local: exigeix que l'atacant ja sigui al portàtil. És el segon baula de la cadena, no el primer. S'agrupa amb l'aplicació gestionada de pedaços del parc (05-06) |
| 4t | A | P2 | 30 dies | 9.8 sobre actiu crític, però no exposat i EPSS 0,02. Aquí és on ordenar per CVSS falla: sembla la primera i és la quarta. Convé confirmar l'abastabilitat; si el tauler no processa imatges d'usuari, baixa a P3 i es documenta a VEX |
| 5è | C | P3 | 90 dies | Exposat però de baix impacte: web estàtica, sense dades ni sessions. Una línia d'nginx (03-05) al manteniment següent. Tractar-lo com a urgent «perquè surt en vermell» és justament l'error que la política evita |
Observació transversal: els dos primers no requereixen pedaç, sinó un canvi de configuració i una rotació de credencial, tots dos gratuïts i de minuts. El més urgent gairebé mai no és el més car.
Exercici 3
workflow_dispatchcom a únic disparador: només s'executa a mà, és a dir, gairebé mai. Faltenpull_request,pushamaini unscheduleque capturi CVE noves sense canvis de codi.checkoutsensefetch-depth: 0:gitleaksnomés veu l'últim commit, així que els secrets de l'historial —el cas real de Nimbus— passen desapercebuts indefinidament.trivy image nimbus/api:latest: escaneja una etiqueta que no és la imatge que aquest canvi construeix. Es valida una imatge i se'n desplega una altra; cal construir i escanejar per SHA del commit.--exit-code 1sense--severity: bloqueja amb qualsevol troballa, incloses les informatives i les que no tenen pedaç. Es desactivarà en dues setmanes.pip-auditsense-r requirements.txt: audita l'entorn del runner, no el projecte; pot passar en verd amb dependències vulnerables.- No es publica cap resultat i no hi ha
permissionsexplícites: sense SARIF ni artefactes no hi ha historial, tendència ni evidència per a 04-03, i el token opera amb més permisos dels necessaris, contra el mínim privilegi d'01-03.
La versió corregida és la de l'apartat 9, amb fetch-depth: 0, els tres disparadors, permissions acotades, llindar propi a ci/llindar.py, imatge etiquetada per SHA i publicació SARIF amb if: always().
Conclusió
Has convertit el «verificar» del mòdul 4 en un procés mesurable. Saps que la gestió de vulnerabilitats és un cicle —inventariar, descobrir, prioritzar, esmenar, verificar i informar— i no un PDF anual, i que el pas 0 mana: sense inventari no hi ha cobertura, i sense cobertura la resta de mètriques menteixen. Coneixes el mapa de les nou famílies d'eines i, sobretot, què no veu cap d'elles: l'IDOR de Nimbus no apareix en cap escàner, perquè aquestes eines detecten errors de patró i no errors de raonament.
Manegues nmap opció a opció i saps per què l'escaneig extern i l'intern mesuren coses diferents; amb ell has retrobat amb data i evidència les quatre troballes d'01-04. Saps què fa realment un escàner de vulnerabilitats, per què l'escaneig autenticat en troba entre cinc i deu vegades més, i a llegir un informe començant pel QoD. Amb pip-audit i trivy distingeixes vulnerabilitat present de vulnerabilitat explotable, amb l'abastabilitat i el document VEX com a forma correcta de dir «no ens afecta» sense perdre traçabilitat. Amb semgrep, bandit i gitleaks has tancat el verify=False i has trobat la credencial de PostgreSQL a l'historial, la correcció de la qual comença per rotar-la i no per esborrar el fitxer. I t'endus la part que separa un procés útil d'un full de càlcul inútil: prioritzar amb CVSS base/temporal/ambiental, EPSS com a probabilitat i KEV com a fet observat, la política de terminis P0-P4 i un càlcul que reordena la llista fins a deixar la CVE de 9.1 a l'últim lloc; validar falsos positius en cinc passos; integrar-ho tot en un pipeline que bloqueja el que és accionable i informa de la resta; i redactar una troballa accionable amb evidència, impacte de negoci, correcció estimada, verificació i propietari.
Però fixa't en el límit de tot l'anterior: aquest procés troba portes mal tancades; no veu ningú entrant-hi. Si demà un atacant fa servir la credencial de la consultora a les 22:14, cap escàner d'aquesta lliçó no se n'assabentarà: el port està legítimament obert i la credencial és vàlida. Aquest és el buit que va deixar vint dies de silenci a l'incident de 02-06 i que el catàleg de 04-03 reflecteix amb vuit controls detectius dels quals només dos estan implantats. A Tècniques de Monitoratge i Detecció (05-02) construïm per fi aquests controls: què registrar, on centralitzar-ho, com escriure deteccions que es disparin amb el que importa i callin amb el que no, i com reduir el temps de permanència de l'atacant de vint dies a un matí.
Curs de Fonaments de Seguretat Informàtica
Mòdul 1: Introducció a la Seguretat Informàtica
- Conceptes Bàsics de Seguretat Informàtica
- Tipus d'Amenaces i Vulnerabilitats
- Principis de la Seguretat Informàtica
- Actius, Superfície d'Atac i Actors d'Amenaça
Mòdul 2: Ciberseguretat
- Definició i Abast de la Ciberseguretat
- Tipus d'Atacs Cibernètics
- Enginyeria Social i Pesca de Credencials
- Mesures de Protecció en Ciberseguretat
- Identitat, Autenticació i Control d'Accés
- Casos d'Estudi d'Incidents de Ciberseguretat
Mòdul 3: Criptografia
- Introducció a la Criptografia
- Criptografia Simètrica
- Criptografia Asimètrica
- Funcions Hash, HMAC i Emmagatzematge de Contrasenyes
- Protocols Criptogràfics
- Gestió de Claus, Certificats i PKI
- Aplicacions de la Criptografia
Mòdul 4: Gestió de Riscos i Mesures de Protecció
- Avaluació de Riscos
- Polítiques de Seguretat
- Controls de Seguretat
- Risc de Tercers i Cadena de Subministrament
- Pla de Resposta a Incidents
- Recuperació davant Desastres i Continuïtat de Negoci
Mòdul 5: Eines i Tècniques de Seguretat
- Eines d'Anàlisi de Vulnerabilitats
- Tècniques de Monitoratge i Detecció
- Proves de Penetració
- Seguretat en Xarxes
- Seguretat en Aplicacions
- Enfortiment de Sistemes i Seguretat de l'Endpoint
- Seguretat al Núvol i en Contenidors
Mòdul 6: Bones Pràctiques i Normatives
- Bones Pràctiques en Seguretat Informàtica
- Normatives i Estàndards de Seguretat
- Protecció de Dades Personals i RGPD a la Pràctica
- Compliment i Auditoria
- Formació i Sensibilització
- Ètica, Aspectes Legals i Divulgació Responsable
