Skip to content

Commit af3ffa0

Browse files
ujjwaltwrigradio-pr-botfreddyaboulton
authored
Fix: avoid corrupting JSON-like values in CSV sanitization (#12499)
* Fix: avoid corrupting JSON-like values in CSV sanitization * Refine CSV sanitization for JSON-like values * add changeset * Refactor CSV sanitization with JSON normalization and clean prefix check * format --------- Co-authored-by: gradio-pr-bot <[email protected]> Co-authored-by: Freddy Boulton <[email protected]>
1 parent 0c5cec1 commit af3ffa0

File tree

2 files changed

+26
-3
lines changed

2 files changed

+26
-3
lines changed

.changeset/puny-lions-follow.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"gradio": patch
3+
---
4+
5+
fix:Fix: avoid corrupting JSON-like values in CSV sanitization

gradio/utils.py

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,8 @@
1010
import importlib
1111
import importlib.metadata
1212
import importlib.resources
13-
import importlib.util
1413
import inspect
1514
import json
16-
import json.decoder
1715
import os
1816
import pkgutil
1917
import posixpath
@@ -918,14 +916,34 @@ def sanitize_value_for_csv(value: str | float) -> str | float:
918916
Sanitizes a value that is being written to a CSV file to prevent CSV injection attacks.
919917
Reference: https://owasp.org/www-community/attacks/CSV_Injection
920918
"""
919+
# Numbers are always safe in CSV context
921920
if isinstance(value, (float, int)):
922921
return value
922+
923+
# Coerce non-strings (e.g. tuples) to string defensively
924+
if not isinstance(value, str):
925+
value = str(value)
926+
927+
# Special handling for JSON-like values
928+
if value.startswith(("{", "[")):
929+
try:
930+
parsed = json.loads(value)
931+
# Return normalized, safe JSON
932+
return json.dumps(parsed)
933+
except (json.JSONDecodeError, ValueError, TypeError):
934+
# Not valid JSON → treat as normal string
935+
pass
936+
937+
# Typical CSV injection protection
923938
unsafe_prefixes = ["=", "+", "-", "@", "\t", "\n"]
924939
unsafe_sequences = [",=", ",+", ",-", ",@", ",\t", ",\n"]
940+
941+
# If starts with any unsafe prefix or contains an unsafe sequence
925942
if any(value.startswith(prefix) for prefix in unsafe_prefixes) or any(
926943
sequence in value for sequence in unsafe_sequences
927944
):
928-
value = f"'{value}"
945+
return f"'{value}"
946+
929947
return value
930948

931949

0 commit comments

Comments
 (0)