Skip to content

Critical: Unsafe pickle deserialization without validation #3

@tanbro

Description

@tanbro

Severity

Critical

Location

File: src/redis_func_cache/cache.py
Lines: 300-328

Description

While the README has warnings about pickle (lines 556-558), the code allows "pickle" serializer by default in some contexts and doesn't implement any safety restrictions. The default serializer is "json" (line 140), but pickle is easily accessible and widely used in examples.

The code doesn't implement:

  • HMAC signing for pickle-serialized data
  • Allowlist validation for pickle usage
  • Any validation mechanism to detect tampered pickle data

Impact

If an attacker can write to Redis (e.g., through another compromised service), they could execute arbitrary code through pickle deserialization.

Reproduction Steps

from redis_func_cache import RedisFuncCache, LruTPolicy
import redis

# Using pickle serializer (common in examples)
cache = RedisFuncCache("test", LruTPolicy(), factory=lambda: redis.from_url("redis://"), serializer="pickle")

@cache
def process_data(data):
    return data

# If attacker can write to Redis directly:
redis_client.set("func-cache:test:lru_t:1", malicious_pickle_data)
# Next cache hit will execute arbitrary code

Proposed Solution

  1. Add HMAC signing for pickle-serialized data:
import hmac
import hashlib

def sign_pickle_data(data: bytes, secret: str) -> bytes:
    return hmac.new(secret.encode(), data, hashlib.sha256).digest()

def verify_pickle_data(data: bytes, signature: bytes, secret: str) -> bool:
    return hmac.compare_digest(hmac.new(secret.encode(), data, hashlib.sha256).digest(), signature)
  1. Add configuration option to require allowlist for pickle usage
  2. Consider using jsonpickle or dill with restricted globals as safer alternatives

Additional Context

  • CVE-2019-5010: Similar vulnerabilities in pickle deserialization
  • OWASP recommends avoiding pickle for untrusted data
  • Document security policy for serializer selection

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions