From c0183e4302d657f2b8746c3bdc5636c5537a8a90 Mon Sep 17 00:00:00 2001 From: clearml <> Date: Wed, 4 Jun 2025 11:44:24 +0300 Subject: [PATCH] Fix CSV export vulnerability by escaping cell text if it matches a macro or formula prefix --- apiserver/services/organization.py | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/apiserver/services/organization.py b/apiserver/services/organization.py index 8c3e809..793c613 100644 --- a/apiserver/services/organization.py +++ b/apiserver/services/organization.py @@ -225,6 +225,18 @@ def prepare_download_for_get_all( call.result.data = dict(prepare_id=call.id) +_dangerous_chars = ("=", "+", "-", "@", "\t", "\r") + +def _sanitize_csv(value: str) -> str: + """ + Prevent csv injection: + If the string starts with any of the chars that Excel + interpret as a special char then prepend it with a single quote + """ + if value and value.startswith(_dangerous_chars): + return f"'{value}" + return value + @endpoint("organization.download_for_get_all") def download_for_get_all(call: APICall, company, request: DownloadForGetAllRequest): request_data = redis.get(f"get_all_download_{request.prepare_id}") @@ -275,7 +287,7 @@ def download_for_get_all(call: APICall, company, request: DownloadForGetAllReque if values and isinstance(val, Hashable): val = values.get(val, val) - return str(val) + return _sanitize_csv(str(val)) def get_projected_fields(data: dict) -> Sequence[str]: return [