From 159b2ddfdfd0a071e6e2c9ae52ef381d858d6bb7 Mon Sep 17 00:00:00 2001 From: Om Patel Date: Tue, 7 Oct 2025 13:15:16 -0400 Subject: [PATCH 1/3] Added malicious input validation Added input validation for Trees and Tables in our set payload methods using bleach. --- pyproject.toml | 1 + .../core/utils/report_objects.py | 23 +++++++++++++++---- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 451dd79f9..78e77c49f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -47,6 +47,7 @@ dependencies = [ "qtpy>=2.4.3,<2.5.0", "lark>=1.2.2,<1.3.0", "docutils>=0.21", + "bleach>=6.2.0", ] [tool.setuptools.packages.find] diff --git a/src/ansys/dynamicreporting/core/utils/report_objects.py b/src/ansys/dynamicreporting/core/utils/report_objects.py index a68fa5ebb..1f9fc079e 100755 --- a/src/ansys/dynamicreporting/core/utils/report_objects.py +++ b/src/ansys/dynamicreporting/core/utils/report_objects.py @@ -16,6 +16,7 @@ import uuid import weakref +import bleach import dateutil import dateutil.parser import pytz @@ -1080,7 +1081,8 @@ def set_payload_none(self): self.type = ItemREST.type_none self._payloaddata = "" - def validate_string(self, input_string, description): + @staticmethod + def validate_string(self, input_string, description, sanitize_html): if not isinstance(input_string, str): raise TypeError("Payload must be a string.") @@ -1092,13 +1094,19 @@ def validate_string(self, input_string, description): except UnicodeEncodeError: raise ValueError(f"Payload {description} must be a valid UTF-8 string.") + if os.getenv("ADR_VALIDATION_BETAFLAG_ANSYS") == "1": + if sanitize_html: + cleaned_string = bleach.clean(input_string, strip=True) + if cleaned_string != input_string: + raise ValueError(f"Payload {description} contains HTML content.") + def set_payload_string(self, s): - self.validate_string(s, "string") + self.validate_string(s, "string", sanitize_html=False) self.type = ItemREST.type_str self._payloaddata = s def set_payload_html(self, s): - self.validate_string(s, "HTML") + self.validate_string(s, "HTML", sanitize_html=False) self.type = ItemREST.type_html self._payloaddata = s @@ -1125,6 +1133,8 @@ def validate_tree_value(value): else: if type_ not in [float, int, datetime.datetime, str, bool, uuid.UUID, type(None)]: raise ValueError(f"{str(type_)} is not a valid Tree payload 'value' type") + if type_ == str: + ItemREST.validate_string(value, "Tree node value", sanitize_html=True) @staticmethod def validate_tree(t): @@ -1233,6 +1243,12 @@ def validate_and_clean_table(self, value): if kind not in ("S", "f"): raise ValueError("Table array must be a bytes or float type.") + if kind == "S": # Check if the array contains strings + for i in range(array.shape[0]): + for j in range(array.shape[1]): + if isinstance(array[i, j], str): + self.validate_string(array[i, j], "Table array element", sanitize_html=True) + shape = array.shape size = array.size @@ -1256,7 +1272,6 @@ def validate_and_clean_table(self, value): array.shape = shape elif len(shape) != 2: raise ValueError("Table array must be 2D.") - if rowlbls and not isinstance(rowlbls, (str, list)): raise TypeError("Row labels must be a string or a list.") if collbls and not isinstance(collbls, (str, list)): From 699f86d345e1bce5e57e5e59927339231ec15865 Mon Sep 17 00:00:00 2001 From: Om Patel Date: Wed, 8 Oct 2025 09:43:20 -0400 Subject: [PATCH 2/3] function declaration fix --- src/ansys/dynamicreporting/core/utils/report_objects.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ansys/dynamicreporting/core/utils/report_objects.py b/src/ansys/dynamicreporting/core/utils/report_objects.py index 1f9fc079e..8a3e1b84a 100755 --- a/src/ansys/dynamicreporting/core/utils/report_objects.py +++ b/src/ansys/dynamicreporting/core/utils/report_objects.py @@ -1082,7 +1082,7 @@ def set_payload_none(self): self._payloaddata = "" @staticmethod - def validate_string(self, input_string, description, sanitize_html): + def validate_string(input_string, description, sanitize_html): if not isinstance(input_string, str): raise TypeError("Payload must be a string.") From ead9c1f20a83419e01b0dde6aca7060ec68bf83c Mon Sep 17 00:00:00 2001 From: Om Patel Date: Wed, 15 Oct 2025 10:42:48 -0400 Subject: [PATCH 3/3] code style improvements --- src/ansys/dynamicreporting/core/utils/report_objects.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/ansys/dynamicreporting/core/utils/report_objects.py b/src/ansys/dynamicreporting/core/utils/report_objects.py index 8a3e1b84a..b1d9f83be 100755 --- a/src/ansys/dynamicreporting/core/utils/report_objects.py +++ b/src/ansys/dynamicreporting/core/utils/report_objects.py @@ -1082,7 +1082,7 @@ def set_payload_none(self): self._payloaddata = "" @staticmethod - def validate_string(input_string, description, sanitize_html): + def validate_string(input_string, description, sanitize_html=False): if not isinstance(input_string, str): raise TypeError("Payload must be a string.") @@ -1101,12 +1101,12 @@ def validate_string(input_string, description, sanitize_html): raise ValueError(f"Payload {description} contains HTML content.") def set_payload_string(self, s): - self.validate_string(s, "string", sanitize_html=False) + self.validate_string(s, "string") self.type = ItemREST.type_str self._payloaddata = s def set_payload_html(self, s): - self.validate_string(s, "HTML", sanitize_html=False) + self.validate_string(s, "HTML") self.type = ItemREST.type_html self._payloaddata = s @@ -1133,7 +1133,7 @@ def validate_tree_value(value): else: if type_ not in [float, int, datetime.datetime, str, bool, uuid.UUID, type(None)]: raise ValueError(f"{str(type_)} is not a valid Tree payload 'value' type") - if type_ == str: + if isinstance(value, str): ItemREST.validate_string(value, "Tree node value", sanitize_html=True) @staticmethod