From 1bad243f5ec18db6e21f7de848ad1baa0f56dbe0 Mon Sep 17 00:00:00 2001 From: Admin MPCZ Date: Tue, 5 May 2026 18:28:13 +0200 Subject: [PATCH] fix(qualys): strip() defensif sur credentials + extraction enrichie de l erreur Qualys (responseCode + errorMessage + errorResolution + RAW fallback si format inconnu) --- app/services/qualys_service.py | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/app/services/qualys_service.py b/app/services/qualys_service.py index c0f3a8b..94a7534 100644 --- a/app/services/qualys_service.py +++ b/app/services/qualys_service.py @@ -17,11 +17,12 @@ CACHE_TTL = 600 # 10 minutes def _get_qualys_creds(db): - """Recupere les credentials Qualys depuis les secrets chiffres""" - url = get_secret(db, "qualys_url") or "https://qualysapi.qualys.eu" - user = get_secret(db, "qualys_user") or "" - pwd = get_secret(db, "qualys_pass") or "" - proxy = get_secret(db, "qualys_proxy") or "" + """Recupere les credentials Qualys depuis les secrets chiffres. + .strip() defensif : un copier-coller peut ajouter newline/CR.""" + url = (get_secret(db, "qualys_url") or "https://qualysapi.qualys.eu").strip() + user = (get_secret(db, "qualys_user") or "").strip() + pwd = (get_secret(db, "qualys_pass") or "").strip() + proxy = (get_secret(db, "qualys_proxy") or "").strip() bypass = (get_secret(db, "qualys_bypass_proxy") or "").lower() == "true" if bypass: proxy = "" @@ -87,15 +88,22 @@ def search_assets_api(db, query, field="name", operator="CONTAINS", force_refres return {"ok": False, "msg": f"Erreur API: {e}", "assets": []} if r.status_code != 200 or "SUCCESS" not in r.text: - # Inclure le détail Qualys (errorMessage / errorResolution sont dans le XML) + # Extraire un max d'info Qualys pour debug import re as _re err_msg = "" + m = _re.search(r"([^<]+)", r.text or "") + if m: err_msg += " [" + m.group(1).strip() + "]" m = _re.search(r"([^<]+)", r.text or "") if m: err_msg += " | errorMessage: " + m.group(1).strip() m = _re.search(r"([^<]+)", r.text or "") if m: err_msg += " | errorResolution: " + m.group(1).strip() - m = _re.search(r"([^<]+)", r.text or "") - if m: err_msg = " [" + m.group(1).strip() + "]" + err_msg + # Si Qualys retourne message (legacy /api/2.0/fo) + m = _re.search(r']*status="FAILED"[^>]*>\s*([^<]+?)\s*', + r.text or "", _re.DOTALL) + if m: err_msg += " | RETURN: " + m.group(1).strip() + # Fallback : dump brut tronqué (utile si XML non standard) + if not err_msg and r.text: + err_msg = " | RAW: " + r.text[:500].replace("\n", " ") return {"ok": False, "msg": f"API HTTP {r.status_code}{err_msg}", "assets": []}