Skip to content

Fix heuristicCheckDbms() False/None inconsistency corrupting kb.reduceTests, wrongly skipping DBMS-specific tests - #6132

Closed
tanaydin wants to merge 1 commit into
sqlmapproject:masterfrom
tanaydin:fix/heuristic-check-dbms-reduce-tests
Closed

tanaydin wants to merge 1 commit into
sqlmapproject:masterfrom
tanaydin:fix/heuristic-check-dbms-reduce-tests

Conversation

@tanaydin

Copy link
Copy Markdown
Contributor

Summary

Two related bugs in lib/controller/checks.py combine to make sqlmap skip legitimate
DBMS-specific test payloads (logged as "...the heuristic tests showed that the back-end DBMS could be 'False'" or '...None'), even though no DBMS was actually determined.

Bug 1 — heuristicCheckDbms() returns False instead of None on failure

heuristicCheckDbms() (lib/controller/checks.py:920) initializes:

retVal = False

and returns this unchanged when no candidate DBMS matches. Every other consumer of
kb.heuristicDbms in the file checks it with is None (e.g. lines 166, 175, 183), not
falsiness. Since False is None evaluates to False, a prior failed heuristic call leaves
kb.heuristicDbms = False, which then:

  • incorrectly satisfies later falsy-style checks (kb.heuristicDbms or ...) as "no value", while
    simultaneously failing the is None guards that gate re-running the heuristic for a
    different parameter later in the same scan,
  • gets embedded directly into debug/info messages via "could be '%s'" % kb.heuristicDbms,
    producing the nonsensical could be 'False' log line.

Fix

Change the initial/failure value to None:

retVal = None

This matches the is None convention used by every caller.

Bug 2 — kb.reduceTests fallback ignores which value actually triggered the branch

At lib/controller/checks.py:183-186:

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 []

The guarding if can be satisfied by any of three truthy signals:
Backend.getErrorParsedDBMSes(), kb.heuristicDbms, or injection.dbms. The prompt message
(msg = ...) correctly falls back through all three. But the actual assignment on the next line
only falls back through the first two — Backend.getErrorParsedDBMSes() or [kb.heuristicDbms] —
ignoring injection.dbms entirely.

Concretely: when the branch is entered because injection.dbms is truthy while
Backend.getErrorParsedDBMSes() is empty and kb.heuristicDbms is None (a real scenario: a
generic/DBMS-agnostic test confirmed the injection, and the heuristic separately failed), the
assignment becomes:

kb.reduceTests = [None]

kb.reduceTests is then a truthy list ([None]), so later at line 323:

elif kb.reduceTests and not intersect(payloadDbms, kb.reduceTests, True):
    debugMsg = "skipping test '%s' because the heuristic tests showed that the back-end DBMS could be '%s'" % (title, unArrayizeValue(kb.reduceTests))
    ...
    continue

every DBMS-specific test gets skipped ("could be 'None'"), even though no DBMS was actually
determined — the opposite of the intended behavior (only skip once a DBMS is known).

Fix

Make the assignment mirror the message's fallback order, deriving from whichever signal actually
satisfied the guard:

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 []

After lines 873. it's starting to printing 'False' which is causing detected database name lost and not executing injections on the server. If verbosity level is 1 or 2 it's not visible to user.

Here is my scan output on vulnserver
out.txt

To reproduce I need to make some changes on vulnserver, which is returning "Network Error" random, that make sqlmap to fail. Which happened me before... here is changed file, I didn't want to put in the changes...
vulnserver.py

…eTests

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 <noreply@anthropic.com>
@stamparm

Copy link
Copy Markdown
Member

this whole process doesn't work this way. there is not original issue, there is no "grace period" for ME to actually fix something, and i am here presented with something that i just have to merge because of "fixes". nope

@stamparm stamparm closed this Sep 28, 2026
stamparm added a commit that referenced this pull request Sep 28, 2026
@tanaydin

Copy link
Copy Markdown
Contributor Author

Well actually it is happening in real life, servers can crash and sqlmap thinks databases name is "None" or "False".
I've seen this behaviour in some. old applications already..

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants