load_task_from_directory parses the fail_to_pass / pass_to_pass fields out of instance_info.txt with eval() (src/anvil/wizard/converters.py):
fail_str = instance_info.get("fail_to_pass", "[]")
pass_str = instance_info.get("pass_to_pass", "[]")
fail_to_pass = eval(fail_str) if fail_str else [] # line 77
...
pass_to_pass = eval(pass_str) if pass_str else [] # line 84
These strings come straight from files inside a task directory, so anyone who can get you to run anvil against a dataset they prepared can execute arbitrary Python at load time. For example an instance_info.txt containing:
fail_to_pass: __import__("os").system("id")
runs that command while the task is being loaded. Since these fields are only ever meant to be lists of test-id strings, ast.literal_eval is a safe drop-in that still parses the existing single-quoted list format and rejects anything that isn't a literal:
import ast
fail_to_pass = ast.literal_eval(fail_str) if fail_str else []
The existing except Exception around the parse already handles the ValueError ast.literal_eval raises on malformed input, so the change is contained.
load_task_from_directoryparses thefail_to_pass/pass_to_passfields out ofinstance_info.txtwitheval()(src/anvil/wizard/converters.py):These strings come straight from files inside a task directory, so anyone who can get you to run
anvilagainst a dataset they prepared can execute arbitrary Python at load time. For example aninstance_info.txtcontaining:runs that command while the task is being loaded. Since these fields are only ever meant to be lists of test-id strings,
ast.literal_evalis a safe drop-in that still parses the existing single-quoted list format and rejects anything that isn't a literal:The existing
except Exceptionaround the parse already handles theValueErrorast.literal_evalraises on malformed input, so the change is contained.