Skip to content

DiskCache unpickles whatever is in its index folder (diskcache, CVE-2025-69872) #1

Open

Description

@avgvi

What happens

DiskCache opens its index, <cache_dir>/index, with diskcache's default Disk (cache.py L170-L173). That disk keeps each entry as a pickle and loads it with pickle.load, so the folder's contents decide what runs inside the IceFrame process. The index is read in three places once set_query_cache(DiskCache(...)) is in effect:

  • DiskCache.get (L191-L200), on every QueryBuilder.cache(ttl).execute() (query.py L282)
  • DiskCache.put (L211), which loads the old entry for a query before it writes the new one
  • DiskCache.invalidate (L229-L232), which loads every entry and runs after each IceFrame write to any table, through invalidate_query_cache

Who can plant an entry

Planting an entry takes write access to cache_dir. The default is .iceframe_cache under the working directory, so the folder lands wherever the process happens to start:

  • a project checkout;
  • a notebook folder several people share;
  • a volume mounted into a container;
  • a cached CI workspace.

Write access there already lets someone swap the parquet files under data/ and change results. With a pickle in the index, it becomes code running in a process that holds the catalog's credentials.

What I checked

What I saw on 0.14.0 from PyPI, against a local SQLite catalog with a file:// warehouse and no credentials: I cached one query, then rewrote its index entry as a pickle.

  • A pickle calling a function from my script ran on the next cached execute(), and the result was the rows that function picked.
  • A pickle calling os.system ran on the next cached execute() in a new process, which then raised AttributeError: 'int' object has no attribute 'get'. It also ran on put() for that query and on an append to a different table, where invalidate_query_cache logged the same AttributeError as a warning.
  • A pickled key in the index ran on the next write and on clear().

The dependency

The cause sits in the dependency, and there is nothing to upgrade to: CVE-2025-69872 (GHSA-w8v5-vhqr-4h9v) is open against diskcache as a whole, whose last release, 5.6.3, came out in August 2023. pip-audit on a fresh install of iceframe[cache] 0.14.0 (plus pyiceberg[sql-sqlite] for the local catalog) lists exactly one finding, diskcache 5.6.3 (PYSEC-2026-2447), with no fix version. While the cache extra installs diskcache, every audit of such an environment keeps reporting it, and DiskCache keeps loading its index this way.

Versions

  • IceFrame 0.14.0
  • Python 3.12.13
  • PyIceberg 0.12.0
  • Polars 2.1.0
  • diskcache 5.6.3
  • sql catalog on SQLite
  • local file:// storage
  • macOS arm64

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions