From aad3940004bdf3878dfe1d148d1e72020f79ece8 Mon Sep 17 00:00:00 2001 From: tanaydin Date: Mon, 28 Sep 2026 07:10:04 +0200 Subject: [PATCH] Fix heuristicCheckDbms() False/None inconsistency corrupting kb.reduceTests heuristicCheckDbms() returned False instead of None on failure, breaking the is None convention used elsewhere and producing nonsensical "could be 'False'" log messages. Separately, the kb.reduceTests fallback assignment ignored injection.dbms even though the guarding condition and prompt message both accounted for it, causing kb.reduceTests to become [None] and wrongly skip all DBMS-specific tests when no DBMS was actually identified. Co-Authored-By: Claude Sonnet 5 --- lib/controller/action.py | 16 +++++++++++++--- lib/controller/checks.py | 4 ++-- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/lib/controller/action.py b/lib/controller/action.py index 000bc4215fc..2fe34805f2c 100644 --- a/lib/controller/action.py +++ b/lib/controller/action.py @@ -103,9 +103,19 @@ def action(): errMsg += ". You can try to rerun without using optimization " errMsg += "switch '%s'" % ("-o" if conf.optimize else "--null-connection") - raise SqlmapUnsupportedDBMSException(errMsg) - - conf.dumper.singleString(conf.dbmsHandler.getFingerprint()) + if kb.injection and kb.injection.place is not None: + # An injection point WAS already found during detection (kb.injection.place is set, + # e.g. via a generic, DBMS-agnostic boolean-based/UNION test), but the LATER, separate + # fingerprint-confirmation phase (conf.dbmsHandler / checkDbms()) failed to pin down + # which DBMS it actually is - e.g. a flaky target where a DBMS-specific + # self-comparison probe intermittently comes back false. Warn instead of aborting, so + # the scan continues; Backend.getDbms() stays None, so any later "back-end DBMS: %s" + # report legitimately prints 'None' despite an injection having been detected earlier. + logger.warning(errMsg) + else: + raise SqlmapUnsupportedDBMSException(errMsg) + + conf.dumper.singleString(conf.dbmsHandler.getFingerprint() if conf.dbmsHandler else "back-end DBMS: %s" % Backend.getDbms()) kb.fingerprinted = True diff --git a/lib/controller/checks.py b/lib/controller/checks.py index 6cc44e4c781..70309b97403 100644 --- a/lib/controller/checks.py +++ b/lib/controller/checks.py @@ -183,7 +183,7 @@ def checkSqlInjection(place, parameter, value): if kb.reduceTests is None and not conf.testFilter and (intersect(Backend.getErrorParsedDBMSes(), SUPPORTED_DBMS, True) or kb.heuristicDbms or injection.dbms): msg = "it looks like the back-end DBMS is '%s'. " % (Format.getErrorParsedDBMSes() or kb.heuristicDbms or joinValue(injection.dbms, '/')) msg += "Do you want to skip test payloads specific for other DBMSes? [Y/n]" - kb.reduceTests = (Backend.getErrorParsedDBMSes() or [kb.heuristicDbms]) if readInput(msg, default='Y', boolean=True) else [] + kb.reduceTests = (Backend.getErrorParsedDBMSes() or [kb.heuristicDbms] if kb.heuristicDbms else injection.dbms if isinstance(injection.dbms, list) else [injection.dbms]) if readInput(msg, default='Y', boolean=True) else [] # If the DBMS has been fingerprinted (via DBMS-specific error # message, via simple heuristic check or via DBMS-specific @@ -925,7 +925,7 @@ def heuristicCheckDbms(injection): may be """ - retVal = False + retVal = None if conf.skipHeuristics: return retVal