mpfaffenberger / mpfaffenberger/code_puppy

Session pickles loaded without any integrity check after signature verification was removed

Open
#404 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
814
Forks
278
Avg merge
2d 5h
Merged PRs (30d)
76

Description

Problem

code_puppy/session_storage.py:18-21 deserializes session history with bare pickle.loads, and the legacy HMAC signature path was deliberately gutted:

def _safe_loads(data: bytes) -> Any:
    """Deserialize pickle data."""
    return pickle.loads(data)  # noqa: S301

and lines 59-69:

def _extract_pickle_payload(raw: bytes) -> bytes:
    ...
    We no longer verify or generate signatures.
    """
    if raw.startswith(_LEGACY_SIGNED_HEADER):
        offset = len(_LEGACY_SIGNED_HEADER) + _LEGACY_SIGNATURE_SIZE
        return raw[offset:]
    return raw

The function is named _safe_loads but is not safe: pickle.loads executes arbitrary code on load. Session files live in ~/.code_puppy/ and project-level contexts dirs, and /load_context plus the startup autosave restore prompt (restore_autosave_interactively) load them. A malicious repo that ships a crafted pickle in its contexts directory gets code execution the moment a user loads it. The previous design at least had a 32-byte signature; the parsing shim remains but verification is gone.

Why it matters

  • Arbitrary code execution from a file the user is encouraged to load interactively (the autosave restore prompt lists all *.pkl files at startup).
  • The misleading _safe_loads name violates "explicit is better than implicit" — it tells future maintainers the danger is handled when it isn't.

Suggested fix

Either restore HMAC verification (keyed off a per-user secret in ~/.code_puppy/), or migrate session persistence to a non-executable format — pydantic-ai ships ModelMessagesTypeAdapter with dump_json / validate_json precisely for serializing message history. Minimal interim step: rename _safe_loads to something honest like _unsafe_pickle_loads, and refuse to load pickles from CWD-relative directories without confirmation.

Filed by Zen Reviewer C (code-puppy-60635a)

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in code_puppy/session_storage.py at _safe_loads and _extract_pickle_payload, then trace their callers in /load_context and restore_autosave_interactively. Compare the proposed HMAC restoration and non-executable serialization paths, and confirm that session files from the listed locations can no longer trigger arbitrary code during loading.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
security
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.