Skip to content

Read the local task cache through diskcache-community's SafeDisk - #3482

Open
avgvi wants to merge 1 commit into
flyteorg:masterfrom
avgvi:local-cache-safedisk
Open

avgvi wants to merge 1 commit into
flyteorg:masterfrom
avgvi:local-cache-safedisk

Conversation

@avgvi

@avgvi avgvi commented Nov 2, 2026

Copy link
Copy Markdown

Tracking issue

Closes flyteorg/flyte#8289 flyteorg/flyte#8289

Why are the changes needed?

LocalTaskCache.initialize() opens the cache with diskcache's default Disk, which reads values back with pickle.load. An entry written into ~/.flyte/local-cache by someone else runs code in the flytekit process on the next cache hit. This is CVE-2025-69872 (GHSA-w8v5-vhqr-4h9v).

The main point is that diskcache 5.6.3 is unmaintained (last release August 2023) and flagged by scanners with no fixed version. #3475 made the import lazy, but diskcache is still a required dependency, so every install still has the finding.

What changes were proposed in this pull request?

  • Depend on diskcache-community>=5.8.1 instead of diskcache. It is a maintained fork with the same API, the same files on disk as diskcache 5.6.3 and the same license (Apache-2.0). Disclosure: I maintain it.
  • Open the cache with SafeDisk.with_types(...).with_options(on_error="miss"):
    • Allowlist. New entries are protobuf bytes, which need no pickle. Older entries are pickled LiteralMaps, so reads still allow flytekit.models.literals, flytekit.models.types, flytekit.models.core.types and protobuf's Struct. test_cache_old_version_of_literal_map passes unchanged.
    • Miss on error. An entry the reader refuses is deleted and treated as a miss, so the task runs again.
  • Keep the import lazy, so import flytekit still doesn't load the cache package.

How was this patch tested?

  • Pointed the two lazy-import tests at diskcache_community.
  • pytest tests/flytekit/unit/core/test_local_cache.py: 25 passed on Python 3.13, with diskcache not installed.
  • pytest tests/flytekit/unit/core -m 767 passed and 17 skipped. The result on master` in the same environment is identical.
  • ruff check passes on the changed files.
  • A normal entry, then a tampered entry written into the same directory (the planted entry only prints a line):
try:
    import diskcache_community as writer_package
except ModuleNotFoundError:
    import diskcache as writer_package

from flytekit import task
from flytekit.core.local_cache import LocalTaskCache
from flytekit.models.literals import LiteralMap


def planted():
    print("  code from the cache directory ran in this process")
    return LiteralMap(literals={})


class Planted:
    def __reduce__(self):
        return (planted, ())


@task(cache=True, cache_version="1")
def double(x: int) -> int:
    print("  task body ran")
    return x * 2


LocalTaskCache.initialize()
LocalTaskCache.clear()

print("1. first call")
print("  result:", double(x=2))

print("2. second call, served from the cache")
print("  result:", double(x=2))

print("3. tampered entry")
with writer_package.Cache(LocalTaskCache._cache.directory) as other_writer:
    (key,) = list(other_writer)
    other_writer.set(key, Planted())
try:
    print("  result:", double(x=2))
except Exception as error:
    print("  raised", type(error).__name__)

On master (diskcache 5.6.3):

1. first call
  task body ran
  result: 4
2. second call, served from the cache
  result: 4
3. tampered entry
  code from the cache directory ran in this process
  raised AssertionError

With this change:

1. first call
  task body ran
  result: 4
2. second call, served from the cache
  result: 4
3. tampered entry
  task body ran
  result: 4

Steps 1 and 2 are the same before and after this change: a normal entry is still served from the cache. Only step 3 differs. On master, reading the tampered entry unpickles it, so its code runs in the flytekit process. With this change, SafeDisk refuses the entry without running it

Setup process

none required

Screenshots

non applicable

Check all the applicable boxes

  • I updated the documentation accordingly.
  • All new and existing tests passed.
  • All commits are signed-off.

Related PRs

#3475

Docs link

https://diskcache-community.readthedocs.io/en/latest/fix-cve-2025-69872.html

Signed-off-by: August Vi <augustvilakia@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] flytekit: local task cache reads entries with pickle.load (CVE-2025-69872)

1 participant