From 4df83fe7375ef00ea56238c8ef00efd5e5c4467d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20=C5=A0tampar?= Date: Thu, 12 Nov 2026 14:53:41 +0100 Subject: [PATCH] Fix for user's LIMIT being ignored by UNION JSON aggregation (e.g. --sql-query) --- lib/core/settings.py | 2 +- lib/techniques/union/use.py | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/core/settings.py b/lib/core/settings.py index 01a3a060c..f870b537f 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.43" +VERSION = "1.10.11.44" 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/techniques/union/use.py b/lib/techniques/union/use.py index bbdbe681d..0a413884a 100644 --- a/lib/techniques/union/use.py +++ b/lib/techniques/union/use.py @@ -353,8 +353,11 @@ def unionUse(expression, unpack=True, dump=False): debugMsg += "it does not play well with UNION query SQL injection" singleTimeDebugMessage(debugMsg) + # Note: (outer) LIMIT/OFFSET/FETCH would apply to the single aggregated row (i.e. being ignored), while Microsoft SQL Server's FOR JSON wraps the whole statement + limited = not Backend.isDbms(DBMS.MSSQL) and any(zeroDepthSearch(expression.upper(), _) for _ in (" LIMIT ", " OFFSET ", " FETCH ")) + # Note: Oracle, PostgreSQL, Microsoft SQL Server and SQLite aggregate the raw (not hex-converted) fields, while parseUnionPage() decodes them all in case of '--hex' - if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.ORACLE, DBMS.PGSQL, DBMS.MSSQL, DBMS.SQLITE, DBMS.H2, DBMS.HSQLDB, DBMS.FIREBIRD) and expressionFields and not any((conf.binaryFields, conf.limitStart, conf.limitStop, conf.disableJson)) and not (conf.hexConvert and Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.PGSQL, DBMS.MSSQL, DBMS.SQLITE)): + if not limited and Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.ORACLE, DBMS.PGSQL, DBMS.MSSQL, DBMS.SQLITE, DBMS.H2, DBMS.HSQLDB, DBMS.FIREBIRD) and expressionFields and not any((conf.binaryFields, conf.limitStart, conf.limitStop, conf.disableJson)) and not (conf.hexConvert and Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.PGSQL, DBMS.MSSQL, DBMS.SQLITE)): match = re.search(r"SELECT\s*(.+?)\bFROM", expression, re.I) if match and not (Backend.isDbms(DBMS.ORACLE) and FROM_DUMMY_TABLE[DBMS.ORACLE] in expression) and not re.search(r"\b(MIN|MAX|COUNT|EXISTS)\(", expression): kb.jsonAggMode = True