8000 fix: use stricter regex for `sanitize_searchfield` (backport #19277) by mergify[bot] · Pull Request #19303 · frappe/frappe · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

fix: use stricter regex for sanitize_searchfield (backport #19277) #19303

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Dec 15, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 4 additions & 31 deletions frappe/desk/search.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,45 +7,18 @@

import frappe
from frappe import _, is_whitelisted
from frappe.database.schema import SPECIAL_CHAR_PATTERN
from frappe.permissions import has_permission
from frappe.utils import cint, cstr, unique


def sanitize_searchfield(searchfield):
blacklisted_keywords = ["select", "delete", "drop", "update", "case", "and", "or", "like"]
if not searchfield:
return

def _raise_exception(searchfield):
if SPECIAL_CHAR_PATTERN.search(searchfield):
frappe.throw(_("Invalid Search Field {0}").format(searchfield), frappe.DataError)

if len(searchfield) == 1:
# do not allow special characters to pass as searchfields
regex = re.compile(r'^.*[=;*,\'"$\-+%#@()_].*')
if regex.match(searchfield):
_raise_exception(searchfield)

if len(searchfield) >= 3:

# to avoid 1=1
if "=" in searchfield:
_raise_exception(searchfield)

# in mysql -- is used for commenting the query
elif " --" in searchfield:
_raise_exception(searchfield)

# to avoid and, or and like
elif any(f" {keyword} " in searchfield.split() for keyword in blacklisted_keywords):
_raise_exception(searchfield)

# to avoid select, delete, drop, update and case
elif any(keyword in searchfield.split() for keyword in blacklisted_keywords):
_raise_exception(searchfield)

else:
regex = re.compile(r'^.*[=;*,\'"$\-+%#@()].*')
if any(regex.match(f) for f in searchfield.split()):
_raise_exception(searchfield)


# this is called by the Link Field
@frappe.whitelist()
Expand Down
19 changes: 18 additions & 1 deletion frappe/tests/test_search.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and Contributors
# License: MIT. See LICENSE

import re

import frappe
from frappe.app import make_form_dict
from frappe.desk.search import get_names_for_mentions, search_link, search_widget
from frappe.desk.search import (
get_names_for_mentions,
sanitize_searchfield,
search_link,
search_widget,
)
from frappe.tests.utils import FrappeTestCase
from frappe.utils import set_request
from frappe.website.serve import get_response
Expand Down Expand Up @@ -179,6 +185,17 @@ def test_validate_and_sanitize_search_inputs(self):
search_link("User", "user@random", searchfield="name")
self.assertListEqual(frappe.response["results"], [])

def test_sanitize_searchfield(self):
for searchfield in ("1=1", "name or (select * from tabSessions)", ";", "`tabSessions`"):
self.assertRaisesRegex(
frappe.DataError,
re.compile(r"^(Invalid Search Field .*)$"),
sanitize_searchfield,
searchfield,
)

sanitize_searchfield("name")


@frappe.validate_and_sanitize_search_inputs
def get_data(doctype, txt, searchfield, start, page_len, filters):
Expand Down
0