Merge pull request #18996 from gavindsouza/spaces-db_query

fix(db_query): Space resilient sanitization
This commit is contained in:
Ankush Menat 2022-11-25 13:12:20 +05:30 committed by GitHub
commit 763bdb5d3c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 50 additions and 6 deletions

View file

@ -384,14 +384,21 @@ class DatabaseQuery:
_raise_exception()
for field in self.fields:
lower_field = field.lower().strip()
if SUB_QUERY_PATTERN.match(field):
if any(f"({keyword}" in field.lower() for keyword in blacklisted_keywords):
_raise_exception()
if lower_field[0] == "(":
subquery_token = lower_field[1:].lstrip().split(" ", 1)[0]
if subquery_token in blacklisted_keywords:
_raise_exception()
if any(f"{keyword}(" in field.lower() for keyword in blacklisted_functions):
_raise_exception()
function = lower_field.split("(", 1)[0].rstrip()
if function in blacklisted_functions:
frappe.throw(
_("Use of function {0} in field is restricted").format(function), exc=frappe.DataError
)
if "@" in field.lower():
if "@" in lower_field:
# prevent access to global variables
_raise_exception()
@ -407,7 +414,7 @@ class DatabaseQuery:
if STRICT_FIELD_PATTERN.match(field):
frappe.throw(_("Illegal SQL Query"))
if STRICT_UNION_PATTERN.match(field.lower()):
if STRICT_UNION_PATTERN.match(lower_field):
frappe.throw(_("Illegal SQL Query"))
def extract_tables(self):

View file

@ -418,6 +418,43 @@ class TestReportview(FrappeTestCase):
)
self.assertTrue("date_diff" in data[0])
with self.assertRaises(frappe.DataError):
DatabaseQuery("DocType").execute(
fields=["name", "issingle", "if (issingle=1, (select name from tabUser), count(name))"],
limit_start=0,
limit_page_length=1,
)
with self.assertRaises(frappe.DataError):
DatabaseQuery("DocType").execute(
fields=["name", "issingle", "if(issingle=1, (select name from tabUser), count(name))"],
limit_start=0,
limit_page_length=1,
)
with self.assertRaises(frappe.DataError):
DatabaseQuery("DocType").execute(
fields=[
"name",
"issingle",
"( select name from `tabUser` where `tabDocType`.owner = `tabUser`.name )",
],
limit_start=0,
limit_page_length=1,
ignore_permissions=True,
)
with self.assertRaises(frappe.DataError):
DatabaseQuery("DocType").execute(
fields=[
"name",
"issingle",
"(select name from `tabUser` where `tabDocType`.owner = `tabUser`.name )",
],
limit_start=0,
limit_page_length=1,
)
def test_nested_permission(self):
frappe.set_user("Administrator")
create_nested_doctype()