mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-05-30 06:41:51 +00:00
fix(skill): guard pickle.loads in darwinian-evolver show_snapshot with explicit flag (#29276)
show_snapshot.py unpickled a user-supplied path unconditionally. pickle.loads is equivalent to arbitrary code execution, so a snapshot from an untrusted source = RCE. Require an explicit --i-trust-this-file acknowledgement before calling pickle.loads, and emit a stderr warning when proceeding. Co-authored-by: Jiahui-Gu <jiahuigu@users.noreply.github.com>
This commit is contained in:
parent
93660643a6
commit
0a2ee71ccc
1 changed files with 25 additions and 2 deletions
|
|
@ -25,18 +25,41 @@ def main() -> int:
|
|||
help="Organism attribute to display. Defaults to the first str field found.",
|
||||
)
|
||||
ap.add_argument("--top", type=int, default=None, help="Show only top N by score.")
|
||||
ap.add_argument(
|
||||
"--i-trust-this-file",
|
||||
action="store_true",
|
||||
help=(
|
||||
"Required acknowledgement that the snapshot is from a trusted source. "
|
||||
"pickle.loads executes arbitrary code embedded in the file (RCE) and "
|
||||
"must NEVER be run on snapshots received from untrusted parties."
|
||||
),
|
||||
)
|
||||
args = ap.parse_args()
|
||||
|
||||
if not args.snapshot.exists():
|
||||
sys.exit(f"snapshot not found: {args.snapshot}")
|
||||
|
||||
if not args.i_trust_this_file:
|
||||
sys.exit(
|
||||
"refusing to unpickle: pickle.loads is equivalent to executing arbitrary "
|
||||
"code from the snapshot file. Only proceed if you created/control this "
|
||||
"file, then re-run with --i-trust-this-file.\n"
|
||||
f" file: {args.snapshot}"
|
||||
)
|
||||
|
||||
print(
|
||||
f"WARNING: unpickling {args.snapshot} — this executes code embedded in the "
|
||||
"file. Only safe for snapshots you produced yourself.",
|
||||
file=sys.stderr,
|
||||
)
|
||||
|
||||
# The outer pickle wraps a dict; the inner pickle contains the actual organism
|
||||
# objects, which must be importable under their original dotted path. If you
|
||||
# ran a custom driver, make sure its module is on sys.path before calling this.
|
||||
outer = pickle.loads(args.snapshot.read_bytes())
|
||||
outer = pickle.loads(args.snapshot.read_bytes()) # noqa: S301 — gated by --i-trust-this-file
|
||||
if not isinstance(outer, dict) or "population_snapshot" not in outer:
|
||||
sys.exit("not a darwinian-evolver snapshot (no population_snapshot key)")
|
||||
inner = pickle.loads(outer["population_snapshot"])
|
||||
inner = pickle.loads(outer["population_snapshot"]) # noqa: S301 — gated by --i-trust-this-file
|
||||
pairs = inner["organisms"] # list of (Organism, EvaluationResult)
|
||||
|
||||
print(f"# organisms: {len(pairs)}\n")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue