From ca698bb7ec51f7e4f682323d4e34eb7590c091f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20=C5=A0tampar?= Date: Thu, 12 Nov 2026 16:14:55 +0100 Subject: [PATCH] Implementing -T for --graphql dumps (and using it in vuln-test to prevent CI timeouts) --- lib/core/settings.py | 2 +- lib/core/testing.py | 2 +- lib/techniques/graphql/inject.py | 4 ++++ 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/core/settings.py b/lib/core/settings.py index b714be69f..62352e48a 100644 --- a/lib/core/settings.py +++ b/lib/core/settings.py @@ -19,7 +19,7 @@ from lib.core.enums import OS from thirdparty import six # sqlmap version (...) -VERSION = "1.10.11.48" +VERSION = "1.10.11.49" TYPE = "dev" if VERSION.count('.') > 2 and VERSION.split('.')[-1] != '0' else "stable" TYPE_COLORS = {"dev": 33, "stable": 90, "pip": 34} VERSION_STRING = "sqlmap/%s#%s" % ('.'.join(VERSION.split('.')[:-1]) if VERSION.count('.') > 2 and VERSION.split('.')[-1] == '0' else VERSION, TYPE) diff --git a/lib/core/testing.py b/lib/core/testing.py index 2923314c8..b919605bc 100644 --- a/lib/core/testing.py +++ b/lib/core/testing.py @@ -95,7 +95,7 @@ def vulnTest(tests=None, label="vuln"): ("-u -z \"tec=B\" --hex --fresh-queries --threads=4 --sql-query=\"SELECT * FROM users\"", ("SELECT * FROM users [30]", "nameisnull")), ("-u \"&echo=foobar*\" --flush-session", ("might be vulnerable to cross-site scripting",)), ("-u \"nosql?name=luther&password=x\" -p password --nosql --flush-session", ("is vulnerable to NoSQL injection", "back-end: 'MongoDB'", "NoSQL: GET parameter 'password'", "s3cr3t")), # NoSQL (MongoDB) operator-injection detection + blind regexp extraction - ("-u \"graphql\" --graphql --flush-session --disable-hashing", ("found GraphQL endpoint", "introspection returned", "enumerated 6 injectable argument slot(s): 4 query, 2 mutation", "SQL injection via GraphQL (boolean-based)", "in-band data exposure", "back-end DBMS: 'SQLite'", "banner: '3.", "GraphQL database tables", "fetched 30 entries from table 'creds'", "db3a16990a0008a3b04707fdef6584a0", "GraphQL scan complete")), # GraphQL: endpoint detection + introspection + query-slots-first (mutations only as fallback) + boolean-blind/in-band + back-end fingerprint + batched blind dump of an injection-only table (SQLite-backed) + ("-u \"graphql\" --graphql -T creds --flush-session --disable-hashing", ("found GraphQL endpoint", "introspection returned", "enumerated 6 injectable argument slot(s): 4 query, 2 mutation", "SQL injection via GraphQL (boolean-based)", "in-band data exposure", "back-end DBMS: 'SQLite'", "banner: '3.", "GraphQL database tables", "fetched 30 entries from table 'creds'", "db3a16990a0008a3b04707fdef6584a0", "GraphQL scan complete")), # GraphQL: endpoint detection + introspection + query-slots-first (mutations only as fallback) + boolean-blind/in-band + back-end fingerprint + batched blind dump of an injection-only table (SQLite-backed) ("-u \"ldap/search?q=x\" --ldap --flush-session --disable-hashing", ("is vulnerable to LDAP injection", "Title: LDAP in-band data exposure", "LDAP: GET parameter 'q' in-band entries", "in-band data exposure", "LDAP scan complete")), # LDAP: error-based detection (unbalanced paren) + boolean oracle + directory attribute extraction via blind substring probing ("-u \"echo?q=x\" --xslt --flush-session --disable-hashing", ("no parameter appears to be injectable", "~is vulnerable to")), # reflection is not evaluation: a pure echo endpoint must not satisfy any non-SQL engine's oracle ("-u \"echo?q=x\" --xpath --flush-session --disable-hashing", ("no parameter appears to be injectable", "~is vulnerable to")), # same gate for --xpath (it used to confirm XPath injection from reflected text alone) diff --git a/lib/techniques/graphql/inject.py b/lib/techniques/graphql/inject.py index a4576f03c..288ffa0eb 100644 --- a/lib/techniques/graphql/inject.py +++ b/lib/techniques/graphql/inject.py @@ -1651,6 +1651,10 @@ def _enumerate(oracle): conf.dumper.singleString("GraphQL database tables [%d]:\n%s" % ( len(tables), _grid(["table"], [[_] for _ in tables]))) + # Note: honoring -T (as in case of regular SQL enumeration) + if conf.tbl: + tables = [_ for _ in tables if _.lower() in set(__.lower() for __ in conf.tbl.split(','))] + for table in tables: parsed = _dumpTable(infer, dialect, table) if not parsed: