From 8bc0f4794ccd4f35d949829d682956f886b7eb42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20=C5=A0tampar?= Date: Sat, 11 Jul 2026 12:54:33 +0200 Subject: [PATCH] Fixes #5933 --- lib/core/settings.py | 2 +- lib/core/target.py | 16 ++++++++++++++++ tests/test_payload_marking.py | 9 ++++++++- 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/lib/core/settings.py b/lib/core/settings.py index f4ca3fd09..e396b3782 100644 --- a/lib/core/settings.py +++ b/lib/core/settings.py @@ -20,7 +20,7 @@ from lib.core.enums import OS from thirdparty import six # sqlmap version (...) -VERSION = "1.10.7.76" +VERSION = "1.10.7.77" 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/target.py b/lib/core/target.py index 0aff96161..dd1fd34ae 100644 --- a/lib/core/target.py +++ b/lib/core/target.py @@ -214,6 +214,22 @@ def _setRequestParams(): conf.data = conf.data.replace(kb.customInjectionMark, ASTERISK_MARKER) conf.data = re.sub(r"(<(?P[^>]+)( [^<]*)?>)([^<]+)(\g<4>%s\g<5>" % kb.customInjectionMark), conf.data) + # Also expose XML attribute values (e.g. ) as injection points, not just + # element text (Reference: https://github.com/sqlmapproject/sqlmap/issues/5993). Done per + # opening tag (skipping declarations, and closing tags) so every attribute + # is covered while the XML declaration/namespaces are left intact. + def processAttributes(match): + def _attr(m): + name = m.group("name") + if name == "xmlns" or name.startswith("xmlns:"): # namespace declarations are not injection points + return m.group(0) + if conf.testParameter and name not in (removePostHintPrefix(_) for _ in conf.testParameter): + return m.group(0) + hintNames.append(("%s%s%s" % (m.group(1), m.group(3), m.group(4)), name)) + return "%s%s%s%s%s" % (m.group(1), m.group(3), m.group(4), kb.customInjectionMark, m.group(5)) + return re.sub(r'(\s(?P[\w:.-]+)\s*=\s*)(["\'])([^"\'<>]*)(["\'])', _attr, match.group(0)) + conf.data = re.sub(r"(?s)<[^>?!/][^>]*>", processAttributes, conf.data) + elif re.search(MULTIPART_RECOGNITION_REGEX, conf.data): message = "Multipart-like data found in %s body. " % conf.method message += "Do you want to process it? [Y/n/q] " diff --git a/tests/test_payload_marking.py b/tests/test_payload_marking.py index f0271bf9c..5b014e829 100644 --- a/tests/test_payload_marking.py +++ b/tests/test_payload_marking.py @@ -175,10 +175,17 @@ class TestXmlMarking(unittest.TestCase): CASES = [ ("x", "x*"), - ('x', 'x*'), + # attribute values are now marked too, not just element text (issue #5993) + ('x', 'x*'), ("bob5", "bob*5*"), ("v", "v*"), ("1", "1*"), + # multiple attributes and single-quoted attribute values + ('y', 'y*'), + ("y", "y*"), + # XML declaration and namespace declarations are left intact (not injection points) + ('y', 'y*'), + ('y', 'y*'), ] def test_cases(self):