From fb9b9c03e08b9fb8d9c00627a2ffd55e74bc1faa Mon Sep 17 00:00:00 2001 From: tuanaiseo Date: Fri, 22 May 2026 06:03:50 +0700 Subject: [PATCH] fix(security)(art): unsafe pickle usage in filelogger The FileLogger class in src/art/langgraph/logging.py uses pickle.dump and pickle.load to serialize and deserialize log entries. Pickle is unsafe for untrusted data as it can execute arbitrary code during deserialization. An attacker with write access to the pickle file or the ability to control log entries could achieve remote code execution. Affected files: logging.py Signed-off-by: tuanaiseo <221258316+tuanaiseo@users.noreply.github.com> --- src/art/langgraph/logging.py | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/src/art/langgraph/logging.py b/src/art/langgraph/logging.py index 4b50a9530..5df4d54b5 100644 --- a/src/art/langgraph/logging.py +++ b/src/art/langgraph/logging.py @@ -1,30 +1,29 @@ +import json import os -import pickle class FileLogger: def __init__(self, filepath): self.text_path = filepath - self.pickle_path = filepath + ".pkl" + self.jsonl_path = filepath + ".jsonl" def log(self, name, entry): # Log as readable text with open(self.text_path, "a") as f: f.write(f"{name}: {entry}\n") - # Append to pickle log - with open(self.pickle_path, "ab") as pf: - pickle.dump((name, entry), pf) + # Append to jsonl log + with open(self.jsonl_path, "a") as jf: + jf.write(json.dumps([name, entry]) + "\n") def load_logs(self): - """Load all logs from the pickle file.""" - if not os.path.exists(self.pickle_path): + """Load all logs from the jsonl file.""" + if not os.path.exists(self.jsonl_path): return [] logs = [] - with open(self.pickle_path, "rb") as pf: - try: - while True: - logs.append(pickle.load(pf)) - except EOFError: - pass + with open(self.jsonl_path, "r") as jf: + for line in jf: + line = line.strip() + if line: + logs.append(tuple(json.loads(line))) return logs