Skip to content
KitploitKITPLOIT
StrumentiExploitsBlog
Log in
Invia
StrumentiExploitsBlog
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.

FeedContattoPrivacy© 2026 Kitploit

Directory degli strumenti

Categorie

Vedi tutte le categorie
Loading categories
work1-secure-api — HDU IS Work 1 - API REST sicura (Flask) con CI/CD (pytest + bandit + pip-audit) e analisi di CVE-2018-17246 | Kitploit
Strumenti/GitHubGitHub/ght657/work1-secure-api
Autenticazione e AutorizzazioneAnalisi StaticaAnalisi delle VulnerabilitàSicurezza WebDevSecOpsSicurezza della Supply ChainPaper e RicercaApprendimento e FormazioneSicurezza delle APILab e Pratica
GitHub
16h 47m 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
ght657/work1-secure-api

work1-secure-api

HDU IS Work 1 - API REST sicura (Flask) con CI/CD (pytest + bandit + pip-audit) e analisi di CVE-2018-17246

Vedi Repository

Lavoro 1 — Sviluppo di API REST sicure con CI/CD e analisi reale di vulnerabilità CVE

API REST sicura in Python/Flask, CI/CD tramite GitHub Actions (SAST + SCA + test automatizzati), e un'analisi completa di una CVE reale riprodotta in un ambiente Docker (Kibana LFI, CVE-2018-17246).

Nome: Guhaotian Numero HDU: 23320209


1. Progetto e team

  • Repository: https://github.com/ght657/work1-secure-api (pubblico)
  • Stack: Python 3.9 / Flask 3.1.3, PyJWT (token HS256), hashing delle password con bcrypt, SQLite tramite SQLAlchemy 2, pytest.
  • L'API espone tre endpoint:
    • POST /auth/login — rilascia un JWT firmato dopo aver verificato l'hash della password.
    • GET /api/data — protetto da JWT (Bearer token); restituisce i record dell'utente corrente.
    • GET /api/users/search?q= — endpoint di lettura protetto con query SQL a parametri vincolati.
  • Endpoint di scrittura aggiuntivo POST /api/posts (protetto da JWT) che dimostra la protezione contro XSS memorizzato / escaping dell'output.

2. Pipeline CI/CD

File del workflow: .github/workflows/ci.yml, attivato a ogni push su main.

JobStrumentiCosa faEvidenza
testpytest 8esegue la suite di 11 testevidence/07_pytest_run.png
sastBandit 1.8.0analisi statica di app/, tests/ (report JSON caricato come artifact)evidence/08_bandit_report.png
scapip-audit 2.8.0audit delle dipendenze (report JSON caricato come artifact)evidence/09_pip_audit_report.png

La pipeline fallisce se un test fallisce o se rimane qualsiasi risultato SAST/SCA, quindi una pipeline rossa significa che è necessario effettuare il push di una correzione prima del merge.

3. Evidenze — SAST, SCA, test

3.1 Test automatizzati

11 test, tutti superati (pytest -q):

tests/test_api.py::test_login_success_issues_token PASSED
tests/test_api.py::test_login_wrong_password_rejected PASSED
tests/test_api.py::test_login_unknown_user_same_error_as_wrong_password PASSED
tests/test_api.py::test_passwords_stored_as_bcrypt_hashes PASSED
tests/test_api.py::test_data_endpoint_denied_without_token PASSED
tests/test_api.py::test_data_endpoint_denied_with_invalid_token PASSED
tests/test_api.py::test_data_endpoint_works_with_valid_token PASSED
tests/test_api.py::test_create_post_requires_token PASSED
tests/test_api.py::test_sqli_payload_treated_as_data PASSED
tests/test_api.py::test_sqli_union_payload_does_not_dump_table PASSED
tests/test_api.py::test_xss_payload_is_escaped_in_response PASSED

11 passed in 2.20s

3.2 SAST — Bandit

Il codice dell'applicazione è nostro, quindi una prima esecuzione non contiene naturalmente rumore di terze parti. Risultato: 0 problemi:

Run started:...
Test results:
	No issues identified.
Code scanned:
	Total lines of code: 228
	Total lines skipped (#nosec): 0
	Total potential issues skipped due to specifically being disabled (e.g., #nosec BXXX): 0

3.3 SCA — pip-audit (audit delle dipendenze)

pip-audit elenca tutte le dipendenze con CVE note; l'esecuzione iniziale ha rilevato:

Found 19 known vulnerabilities in 3 packages
Name          Version ID                Fix Versions
------------- ------- ----------------- ------------
flask         3.0.3   PYSEC-2026-2151    3.1.3
pyjwt         2.9.0   PYSEC-2026-120     2.12.0
pyjwt         2.9.0   PYSEC-2025-183      ...
pyjwt         2.9.0   ...                up to 2.15.0
python-dotenv 1.0.1   PYSEC-2026-2270    1.2.2

19 voci in totale (Flask, PyJWT ×17, python-dotenv). Ho aggiornato alle versioni corrette: Flask 3.1.3, PyJWT 2.15.0 e rimosso python-dotenv (solo helper di configurazione opzionale — la versione corretta 1.2.2 richiede Python ≥ 3.10 mentre il venv di audit è 3.9). Dopo la correzione:

No known vulnerabilities found

(evidence/08b_bandit_after_fix.png, evidence/09b_pip_audit_after_fix.png)

4. Test di vulnerabilità — sicurezza delle API

L'API è stata testata contro gli attacchi classici con curl. Gli screenshot sono in evidence/:

4.1 Tentativo di SQL injection sul login

POST /auth/login con username: "admin'--" restituisce 401 Invalid credentials — la ricerca utilizza una query ORM parametrizzata sulle credenziali hashate, il payload iniettato rimane un dato e non diventa mai SQL.

4.2 Tentativo di SQL injection sulla ricerca

GET /api/users/search?q=%' OR '1'='1 → la stringa viene associata come parametro a SELECT ... WHERE username LIKE ? (caratteri jolly sottoposti a escape), quindi non corrisponde a nulla e l'API restituisce una lista vuota — nessun errore e nessun dump dell'intera tabella.

4.3 Tentativo di XSS (contenuto memorizzato)

POST /api/posts con title: "<script>alert('xss')</script>"; il server memorizza la stringa grezza ma la sottopone a escape in output (markupsafe.escape + jsonify), quindi il payload restituito è <script>alert(&#39;xss&#39;)</script> — un browser visualizza il testo, non lo esegue. (La riproduzione con il rendering nel browser è mostrata in evidence/06_xss_readback.png.)

4.4 Gestione del JWT

  • Nessun token → 401 {"error": "Missing or malformed Authorization header"} (evidence/03_data_denied.png)
  • Token valido → 200 + dati protetti (evidence/04_data_with_token.png)
  • Token con payload manomesso → 401 (verifica della firma con HS256)
  • Token scaduto → 401 (scadenza di 60 minuti)
  • Il JWT viene restituito nella risposta e utilizzato tramite Authorization: Bearer <token> (evidence/10_jwt_structure.png mostra la struttura in 3 parti).

4.5 Hashing

Le password sono memorizzate come hash bcrypt (12 round) e non vengono mai restituite da alcun endpoint (test test_passwords_stored_as_bcrypt_hashes).

5. Analisi CVE — CVE-2018-17246 (Kibana 5.6.12 / 6.4.2 — local file inclusion + esecuzione di codice)

5.1 Panoramica della vulnerabilità

  • Prodotto / versione: Kibana 5.6.12 (vulnerabile), 5.6.13 (corretta); 6.4.2 / 6.4.3.
  • Tipo: Path traversal / lettura arbitraria di file non autenticata tramite l'API Console, che si escala a esecuzione di codice remoto caricando un file JavaScript locale.
  • Impatto: lettura non autenticata di qualsiasi file leggibile dal processo Kibana (ad es. /etc/passwd) e — poiché la route vulnerabile richiede il file come modulo JS — se è raggiungibile un percorso scrivibile (ad es. tramite un'altra falla o un file temporaneo generato), il JS controllato dall'attaccante può essere eseguito dal processo Kibana.
  • Causa: GET /api/console/api_server?apis=../../../../../../etc/passwd — il parametro apis viene passato a require() dopo un solo semplice controllo del percorso, consentendo a sequenze .. di uscire dalla directory api lato server e leggere/eseguire file arbitrari.

5.2 Riproduzione della CVE (Docker locale)

Utilizzo l'immagine pubblica vulhub (già pubblicata, verificata come vulnerabile):

vulhub/kibana:5.6.12 + vulhub/elasticsearch:5.6.16 — vedi CVE-2018-17246/docker-compose.yml (cartella con lo stesso nome in questo repo).

cd CVE-2018-17246
docker compose up -d          # kibana 5.6.12 + elasticsearch 5.6.16, UI on :5601

Passo 1 — attivare l'LFI (l'API Console accetta un percorso apis che viene risolto come file):

curl -i "http://localhost:5601/api/console/api_server?sense_version=%40%40SENSE_VERSION&apis=../../../../../../../../../../../etc/passwd"

La risposta è 500 (il file non è un modulo JS valido) ma il contenuto del file appare nel log del server — Kibana legge il file e tenta di eseguire require() su di esso:

docker compose logs kibana | grep -i "passwd\|root:x"

Passo 2 — escalatione all'esecuzione di codice. Un file JS locale viene caricato come modulo dalla stessa route: /tmp/vulhub.js contenente una piccola "webshell" che esegue un comando di shell quando la sua funzione esportata viene invocata dall'API Console:

Scarica lo strumento