sqlmap/tests/test_dbms_enum.py
Miroslav Štampar cb20a446ae
Some checks are pending
/ build (macos-latest, 3.8) (push) Waiting to run
/ build (ubuntu-latest, pypy-2.7) (push) Waiting to run
/ build (windows-latest, 3.14) (push) Waiting to run
Update of unit tests
2026-06-28 14:28:42 +02:00

98 lines
3.7 KiB
Python

#!/usr/bin/env python
"""
Copyright (c) 2006-2026 sqlmap developers (https://sqlmap.org)
See the file 'LICENSE' for copying permission
DBMS-specific enumeration overrides (plugins/dbms/<dbms>/enumeration.py),
driven through each full DBMS handler with the injection layer mocked, so the
dialect-specific table/column discovery paths run without a live target. The
in-band (UNION/error/direct) branch is taken via conf.direct=True and
inject.getValue is stubbed with canned result rows.
"""
import os
import sys
import unittest
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
from _testutils import bootstrap, set_dbms
bootstrap()
from lib.core.data import conf, kb
from lib.core.enums import EXPECTED
class _EnumBase(unittest.TestCase):
"""Snapshot/restore the global state these enumerators mutate."""
module = None # the enumeration module whose inject.getValue we patch
def setUp(self):
self._direct = conf.direct
self._db = conf.db
self._gv = self.module.inject.getValue
self._cachedTables = kb.data.get("cachedTables")
self._cachedColumns = kb.data.get("cachedColumns")
conf.direct = True
kb.data.cachedTables = {}
kb.data.cachedColumns = {}
def tearDown(self):
conf.direct = self._direct
conf.db = self._db
self.module.inject.getValue = self._gv
kb.data.cachedTables = self._cachedTables
kb.data.cachedColumns = self._cachedColumns
class TestMSSQLServerEnum(_EnumBase):
import plugins.dbms.mssqlserver.enumeration as module
def _handler(self):
from plugins.dbms.mssqlserver import MSSQLServerMap
set_dbms("Microsoft SQL Server")
return MSSQLServerMap()
def test_get_tables(self):
# one database (conf.db), single-column rows: getTables keys the cache by
# the db loop variable and stores the rows run through
# arrayize -> unArrayize -> safeSQLIdentificatorNaming -> sorted().
conf.db = "appdb"
self.module.inject.getValue = lambda q, *a, **k: (
3 if k.get("expected") == EXPECTED.INT else [["users"], ["products"], ["customers"]]
)
self._handler().getTables()
tables = kb.data.cachedTables
self.assertEqual(list(tables.keys()), ["appdb"])
stored = tables["appdb"]
# value is a real sorted list (the final sort step), not an echo of input
self.assertEqual(stored, sorted(stored))
# MSSQL qualifies bare names with the dbo schema; assert exact membership
self.assertIn("dbo.users", stored)
self.assertEqual(stored, ["dbo.customers", "dbo.products", "dbo.users"])
def test_get_tables_multiple_dbs(self):
# exercise the per-database keying with two DBs (conf.db = "a,b"): each db
# in the loop gets its OWN sorted table list. Rows are single-column;
# unArrayizeValue collapses each 1-tuple row to the scalar table name.
conf.db = "appdb,salesdb"
def getValue(q, *a, **k):
if k.get("expected") == EXPECTED.INT:
return 3
# the query carries the db name (%s substituted); route per database
if "appdb" in q:
return [["users"], ["sessions"], ["accounts"]]
return [["orders"], ["invoices"]]
self.module.inject.getValue = getValue
self._handler().getTables()
tables = kb.data.cachedTables
# exactly the two requested databases, each mapped to its own sorted list
self.assertEqual(sorted(tables.keys()), ["appdb", "salesdb"])
self.assertEqual(tables["appdb"], ["dbo.accounts", "dbo.sessions", "dbo.users"])
self.assertEqual(tables["salesdb"], ["dbo.invoices", "dbo.orders"])
if __name__ == "__main__":
unittest.main()