Remove opt-in fields

This commit is contained in:
shamoon 2024-09-01 17:29:26 -07:00
parent f0157a36fb
commit 96546af95f
4 changed files with 1 additions and 60 deletions

View File

@ -319,22 +319,6 @@ including `gt` (>), `gte` (>=), `lt` (<), `lte` (<=), and `range`.
Lastly, document link fields support a `contains` operator that behaves Lastly, document link fields support a `contains` operator that behaves
like a "is superset of" check. like a "is superset of" check.
!!! warning
It is possible to do case-insensitive exact match (i.e., `iexact`) and
case-sensitive substring match (i.e., `contains`, `startswith`,
`endswith`) for string, URL, and monetary fields, but
[they may not work as expected on some database backends](https://docs.djangoproject.com/en/5.1/ref/databases/#substring-matching-and-case-sensitivity).
It is also possible to use regular expressions to match string, URL, and
monetary fields, but the syntax is database-dependent, and accepting
regular expressions from untrusted sources could make your instance
vulnerable to regular expression denial of service attacks.
For these reasons the above expressions are disabled by default.
If you understand the implications, you may enable them by uncommenting
`PAPERLESS_CUSTOM_FIELD_LOOKUP_OPT_IN` in your configuration file.
### `/api/search/autocomplete/` ### `/api/search/autocomplete/`
Get auto completions for a partial search term. Get auto completions for a partial search term.

View File

@ -152,7 +152,7 @@ export class CustomFieldsLookupDropdownComponent {
} }
getOperatorsForField(field: CustomField): string[] { getOperatorsForField(field: CustomField): string[] {
return ['exact', 'in', 'isnull', 'exists'] return ['exact', 'in', 'icontains', 'isnull', 'exists']
// TODO: implement this // TODO: implement this
} }
} }

View File

@ -239,15 +239,9 @@ class CustomFieldLookupParser:
EXPR_BY_CATEGORY = { EXPR_BY_CATEGORY = {
"basic": ["exact", "in", "isnull", "exists"], "basic": ["exact", "in", "isnull", "exists"],
"string": [ "string": [
"iexact",
"contains",
"icontains", "icontains",
"startswith",
"istartswith", "istartswith",
"endswith",
"iendswith", "iendswith",
"regex",
"iregex",
], ],
"arithmetic": [ "arithmetic": [
"gt", "gt",
@ -259,23 +253,6 @@ class CustomFieldLookupParser:
"containment": ["contains"], "containment": ["contains"],
} }
# These string lookup expressions are problematic. We shall disable
# them by default unless the user explicitly opts in.
STR_EXPR_DISABLED_BY_DEFAULT = [
# SQLite: is case-sensitive outside the ASCII range
"iexact",
# SQLite: behaves the same as icontains
"contains",
# SQLite: behaves the same as istartswith
"startswith",
# SQLite: behaves the same as iendswith
"endswith",
# Syntax depends on database backends, can be exploited for ReDoS
"regex",
# Syntax depends on database backends, can be exploited for ReDoS
"iregex",
]
SUPPORTED_EXPR_CATEGORIES = { SUPPORTED_EXPR_CATEGORIES = {
CustomField.FieldDataType.STRING: ("basic", "string"), CustomField.FieldDataType.STRING: ("basic", "string"),
CustomField.FieldDataType.URL: ("basic", "string"), CustomField.FieldDataType.URL: ("basic", "string"),
@ -495,22 +472,6 @@ class CustomFieldLookupParser:
# Check if the operator is supported for the current data_type. # Check if the operator is supported for the current data_type.
supported = False supported = False
for category in self.SUPPORTED_EXPR_CATEGORIES[custom_field.data_type]: for category in self.SUPPORTED_EXPR_CATEGORIES[custom_field.data_type]:
if (
category == "string"
and op in self.STR_EXPR_DISABLED_BY_DEFAULT
and op not in settings.CUSTOM_FIELD_LOOKUP_OPT_IN
):
raise serializers.ValidationError(
[
_(
"{expr!r} is disabled by default because it does not "
"behave consistently across database backends, or can "
"cause security risks. If you understand the implications "
"you may enabled it by adding it to "
"`PAPERLESS_CUSTOM_FIELD_LOOKUP_OPT_IN`.",
).format(expr=op),
],
)
if op in self.EXPR_BY_CATEGORY[category]: if op in self.EXPR_BY_CATEGORY[category]:
supported = True supported = True
break break

View File

@ -1200,10 +1200,6 @@ EMPTY_TRASH_DELAY = max(__get_int("PAPERLESS_EMPTY_TRASH_DELAY", 30), 1)
# custom_field_lookup Filter Settings # # custom_field_lookup Filter Settings #
############################################################################### ###############################################################################
CUSTOM_FIELD_LOOKUP_OPT_IN = __get_list(
"PAPERLESS_CUSTOM_FIELD_LOOKUP_OPT_IN",
default=[],
)
CUSTOM_FIELD_LOOKUP_MAX_DEPTH = __get_int( CUSTOM_FIELD_LOOKUP_MAX_DEPTH = __get_int(
"PAPERLESS_CUSTOM_FIELD_LOOKUP_MAX_DEPTH", "PAPERLESS_CUSTOM_FIELD_LOOKUP_MAX_DEPTH",
default=10, default=10,