Skip to content
KitploitKITPLOIT
OutilsExploitsBlog
Log in
Soumettre
OutilsExploitsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

FluxContactConfidentialité© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
work1-secure-api — HDU IS Work 1 - API REST sécurisée (Flask) avec CI/CD (pytest + bandit + pip-audit) et analyse de CVE-2018-17246 | Kitploit
Outils/GitHubGitHub/ght657/work1-secure-api
Authentification et AutorisationAnalyse StatiqueAnalyse des VulnérabilitésSécurité WebDevSecOpsSécurité de la Chaîne LogistiqueArticles et RechercheApprentissage et ÉducationSécurité des APILabs et Pratique
GitHub
il y a 17h 59mPas encore vérifié

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →
ght657/work1-secure-api

work1-secure-api

HDU IS Work 1 - API REST sécurisée (Flask) avec CI/CD (pytest + bandit + pip-audit) et analyse de CVE-2018-17246

Voir le dépôt
Partager

Travail 1 — Développement d'une API REST sécurisée avec CI/CD et analyse de vulnérabilités CVE réelles

API REST sécurisée en Python/Flask, CI/CD via GitHub Actions (SAST + SCA + tests automatisés), et une analyse complète d'une CVE réelle reproduite dans un environnement Docker (LFI Kibana, CVE-2018-17246).

Nom : Guhaotian Numéro HDU : 23320209


1. Projet et équipe

  • Dépôt : https://github.com/ght657/work1-secure-api (public)
  • Stack : Python 3.9 / Flask 3.1.3, PyJWT (jetons HS256), hachage de mots de passe bcrypt, SQLite via SQLAlchemy 2, pytest.
  • L'API expose trois points de terminaison :
    • POST /auth/login — émet un JWT signé après vérification du hachage du mot de passe.
    • GET /api/data — protégé par JWT (jeton Bearer) ; renvoie les enregistrements de l'utilisateur courant.
    • GET /api/users/search?q= — point de terminaison de lecture protégé avec requête SQL à paramètres liés.
  • Point de terminaison d'écriture supplémentaire POST /api/posts (protégé par JWT) démontrant la protection contre les XSS stockées / l'échappement des sorties.

2. Pipeline CI/CD

Fichier de workflow : .github/workflows/ci.yml, déclenché à chaque push sur main.

JobOutillageCe qu'il faitPreuve
testpytest 8exécute la suite de 11 testsevidence/07_pytest_run.png
sastBandit 1.8.0analyse statique de app/, tests/ (rapport JSON téléversé comme artefact)evidence/08_bandit_report.png
scapip-audit 2.8.0audit des dépendances (rapport JSON téléversé comme artefact)evidence/09_pip_audit_report.png

Le pipeline échoue si un test échoue ou si une anomalie SAST/SCA subsiste, donc un pipeline en échec signifie qu'un correctif doit être poussé avant la fusion.

3. Preuves — SAST, SCA, tests

3.1 Tests automatisés

11 tests, tous réussis (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

Le code de l'application est le nôtre, donc une première exécution ne contient naturellement aucun bruit provenant de tiers. Résultat : 0 problème :

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 des dépendances)

pip-audit liste toutes les dépendances présentant des CVE connues ; l'exécution initiale a révélé :

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 entrées au total (Flask, PyJWT ×17, python-dotenv). J'ai mis à niveau vers les versions corrigées : Flask 3.1.3, PyJWT 2.15.0 et supprimé python-dotenv (assistant de configuration optionnel uniquement — la version corrigée 1.2.2 exige Python ≥ 3.10 alors que le venv d'audit est en 3.9). Après la correction :

No known vulnerabilities found

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

4. Tests de vulnérabilité — sécurité de l'API

L'API a été testée face aux attaques classiques avec curl. Captures d'écran dans evidence/ :

4.1 Tentative d'injection SQL sur le login

POST /auth/login avec username: "admin'--" renvoie 401 Invalid credentials — la recherche utilise une requête paramétrée ORM sur les identifiants hachés, la charge injectée reste une donnée et ne devient jamais du SQL.

4.2 Tentative d'injection SQL sur la recherche

GET /api/users/search?q=%' OR '1'='1 → la chaîne est liée comme paramètre à SELECT ... WHERE username LIKE ? (caractères génériques échappés), elle ne correspond donc à rien et l'API renvoie une liste vide — aucune erreur et aucun vidage complet de la table.

4.3 Tentative XSS (contenu stocké)

POST /api/posts avec title: "<script>alert('xss')</script>" ; le serveur stocke la chaîne brute mais l'échappe en sortie (markupsafe.escape + jsonify), la charge renvoyée est donc <script>alert(&#39;xss&#39;)</script> — un navigateur affiche le texte, il ne l'exécute pas. (La reproduction avec un rendu navigateur est montrée dans evidence/06_xss_readback.png.)

4.4 Gestion des JWT

  • Pas de jeton → 401 {"error": "Missing or malformed Authorization header"} (evidence/03_data_denied.png)
  • Jeton valide → 200 + données protégées (evidence/04_data_with_token.png)
  • Jeton avec charge altérée → 401 (vérification de signature avec HS256)
  • Jeton expiré → 401 (expiration à 60 minutes)
  • Le JWT est renvoyé dans la réponse et utilisé via Authorization: Bearer <token> (evidence/10_jwt_structure.png montre la structure en 3 parties).

4.5 Hachage

Les mots de passe sont stockés sous forme de hachages bcrypt (12 rounds) et ne sont jamais renvoyés par aucun endpoint (test test_passwords_stored_as_bcrypt_hashes).

5. Analyse de CVE — CVE-2018-17246 (Kibana 5.6.12 / 6.4.2 — inclusion de fichier local + exécution de code)

5.1 Aperçu de la vulnérabilité

  • Produit / version : Kibana 5.6.12 (vulnérable), 5.6.13 (corrigé) ; 6.4.2 / 6.4.3.
  • Type : Traversée de répertoire / lecture arbitraire de fichier non authentifiée via l'API Console, qui s'élève en exécution de code à distance en chargeant un fichier JavaScript local.
  • Impact : lecture non authentifiée de tout fichier lisible par le processus Kibana (par ex. /etc/passwd), et — parce que la route vulnérable exige le fichier comme module JS — si un chemin inscriptible est atteignable (par ex. via une autre faille ou un fichier temporaire généré), du JS contrôlé par l'attaquant peut être exécuté par le processus Kibana.
  • Cause : GET /api/console/api_server?apis=../../../../../../etc/passwd — le paramètre apis est passé à require() après seulement une simple vérification de chemin, permettant aux séquences .. de s'échapper du répertoire api côté serveur et de lire/exécuter des fichiers arbitraires.

5.2 Reproduction de la CVE (Docker local)

J'utilise l'image publique vulhub (déjà publiée, vérifiée vulnérable) :

vulhub/kibana:5.6.12 + vulhub/elasticsearch:5.6.16 — voir CVE-2018-17246/docker-compose.yml (dossier du même nom dans ce dépôt).

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

Étape 1 — déclencher le LFI (l'API Console accepte un chemin apis qui est résolu comme un fichier) :

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

La réponse est 500 (le fichier n'est pas un module JS valide) mais le contenu du fichier apparaît dans le journal du serveur — Kibana lit le fichier et tente de le require() :

docker compose logs kibana | grep -i "passwd\|root:x"
Télécharger l’outil