mirror of
https://github.com/sqlmapproject/sqlmap.git
synced 2026-08-04 06:50:14 +00:00
Minor update for SQLlinter
This commit is contained in:
parent
5f99b283c2
commit
0338c13063
3 changed files with 45 additions and 1 deletions
|
|
@ -20,7 +20,7 @@ from lib.core.enums import OS
|
|||
from thirdparty import six
|
||||
|
||||
# sqlmap version (<major>.<minor>.<month>.<monthly commit>)
|
||||
VERSION = "1.10.7.101"
|
||||
VERSION = "1.10.7.102"
|
||||
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)
|
||||
|
|
|
|||
|
|
@ -75,6 +75,16 @@ _BINARY_SYMBOLS = frozenset(("=", "<>", "!=", "<", ">", "<=", ">=", "/", "%", "|
|
|||
# "a,limit,b" would false-positive.
|
||||
_CLAUSE_KEYWORDS = frozenset(("FROM", "WHERE", "HAVING", "INTO"))
|
||||
|
||||
# single-occurrence clause keywords (at most one per SELECT scope) with no
|
||||
# identifier-collision risk - unlike GROUP/ORDER, which double as column names.
|
||||
# a repeat at the same paren-depth is the 'WHERE x WHERE y' structural bug (e.g.
|
||||
# a schema filter appended onto a base query that already carries a WHERE).
|
||||
_SINGLE_CLAUSE_KEYWORDS = frozenset(("WHERE", "HAVING"))
|
||||
|
||||
# set operators that begin a fresh SELECT, resetting single-occurrence clauses at
|
||||
# the current scope ('a WHERE x UNION b WHERE y' is legal; two WHEREs are not).
|
||||
_SET_OPERATORS = frozenset(("UNION", "EXCEPT", "INTERSECT", "MINUS"))
|
||||
|
||||
# sqlmap's own templating markers. If any survives into a *final* outbound payload
|
||||
# a substitution failed upstream (agent.py / cleanupPayload / queries.xml) - always
|
||||
# a bug. Matched on the raw payload because a marker can leak anywhere (bare, inside
|
||||
|
|
@ -309,6 +319,10 @@ def checkSanity(sql, keywords=None):
|
|||
True
|
||||
>>> bool(checkSanity("1UNION SELECT NULL"))
|
||||
True
|
||||
>>> bool(checkSanity("SELECT a FROM t WHERE x=1 WHERE y=2"))
|
||||
True
|
||||
>>> checkSanity("SELECT a FROM t WHERE x=1 UNION SELECT b FROM u WHERE y=2")
|
||||
[]
|
||||
"""
|
||||
if not sql:
|
||||
return []
|
||||
|
|
@ -419,4 +433,28 @@ def checkSanity(sql, keywords=None):
|
|||
if cur.type == T_OTHER:
|
||||
issues.append("stray character '%s' at offset %d" % (cur.value, cur.start))
|
||||
|
||||
# -- duplicated single-occurrence clause at one scope ('WHERE x WHERE y') --
|
||||
# WHERE/HAVING may appear at most once per SELECT scope; a second one at the
|
||||
# same paren-depth (no set operator or ';' resetting the SELECT in between)
|
||||
# is a structural impossibility no surrounding query can undo - subquery
|
||||
# clauses live at a deeper depth and reset on '(' / ')'.
|
||||
scopeSeen = [set()]
|
||||
for token in sig:
|
||||
if token.type == T_LPAREN:
|
||||
scopeSeen.append(set())
|
||||
elif token.type == T_RPAREN:
|
||||
if len(scopeSeen) > 1:
|
||||
scopeSeen.pop()
|
||||
elif token.type == T_SEMI:
|
||||
scopeSeen = [set()]
|
||||
elif token.type == T_KEYWORD:
|
||||
word = token.value.upper()
|
||||
if word in _SINGLE_CLAUSE_KEYWORDS:
|
||||
if word in scopeSeen[-1]:
|
||||
issues.append("duplicate '%s' clause at offset %d" % (word, token.start))
|
||||
else:
|
||||
scopeSeen[-1].add(word)
|
||||
elif word in _SET_OPERATORS:
|
||||
scopeSeen[-1].clear()
|
||||
|
||||
return issues
|
||||
|
|
|
|||
|
|
@ -66,6 +66,9 @@ DIALECT_GOOD = (
|
|||
"SELECT LIMIT 0 1 DISTINCT(user) FROM INFORMATION_SCHEMA.SYSTEM_USERS", # HSQLDB space-LIMIT
|
||||
"SELECT TOP 1 name FROM master..sysdatabases", # MSSQL TOP + db..table
|
||||
"CONCAT('\\',0x71,(SELECT 1))", # backslash-literal string (ANSI)
|
||||
"SELECT a FROM t WHERE x=1 UNION SELECT b FROM u WHERE y=2", # two WHEREs across UNION (legal)
|
||||
"SELECT a FROM (SELECT b FROM t WHERE c=1) z WHERE d=2", # subquery WHERE + outer WHERE (different scopes)
|
||||
"SELECT a FROM t WHERE x IN (SELECT c FROM d WHERE e=1) AND f=2", # WHERE with a WHERE'd subquery
|
||||
)
|
||||
|
||||
# malformed fragments/statements that MUST flag
|
||||
|
|
@ -92,6 +95,9 @@ BAD = (
|
|||
"1 UNION ALLSELECT NULL", # glued keyword after UNION
|
||||
"1 AND ORD(MID((SELECT COUNT(x FROM t),1,1))>64", # unbalanced parentheses (dropped ')')
|
||||
"1 UNION ALL SELECT ,CONCAT(0x71,a,0x71) FROM t", # comma right after SELECT
|
||||
"SELECT OWNER,OBJECT_NAME FROM SYS.ALL_OBJECTS WHERE OBJECT_TYPE IN ('TABLE','VIEW') WHERE OWNER IN ('APPU')", # double WHERE (mis-appended schema filter)
|
||||
"SELECT tabschema,tabname FROM syscat.tables WHERE type IN ('T','V') WHERE tabschema IN ('DB2INST1')", # double WHERE (DB2)
|
||||
"SELECT a FROM t WHERE x=1 HAVING c>1 HAVING d<2", # duplicate HAVING
|
||||
)
|
||||
|
||||
# cross-dialect valid constructs the near-keyword / comma / digit-glue rules must
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue