Skip to main content
CVE Vulnerability Database
Vulnerability Database/CVE-2021-33026

CVE-2021-33026: Flask-Caching RCE Vulnerability

CVE-2021-33026 is a remote code execution flaw in Flask-Caching through version 1.10.1 caused by unsafe Pickle serialization. Attackers with cache access can execute arbitrary code. This article covers technical details, affected versions, impact assessment, and mitigation strategies.

Updated:

CVE-2021-33026 Overview

CVE-2021-33026 affects the Flask-Caching extension through version 1.10.1 for the Flask web framework. The extension relies on Python's pickle module to serialize and deserialize cached objects. An attacker with write access to the cache backend can plant a crafted payload that executes arbitrary Python code when the application deserializes it. Supported backends include filesystem, Memcached, and Redis. This weakness is classified under CWE-502: Deserialization of Untrusted Data. A third party notes that exploitation typically requires prior access to the cache store, which reduces real-world likelihood but does not eliminate the risk in shared or misconfigured environments.

Critical Impact

Attackers who can write to the cache backend can achieve remote code execution or local privilege escalation in the context of the Flask application process.

Affected Products

  • Flask-Caching (flask-caching) versions up to and including 1.10.1
  • Flask applications using Flask-Caching with any pickle-based backend (filesystem, Memcached, Redis)
  • Deployments that share cache backends across trust boundaries

Discovery Timeline

  • 2021-05-13 - CVE-2021-33026 published to the National Vulnerability Database (NVD)
  • 2024-11-21 - Last updated in NVD database

Technical Details for CVE-2021-33026

Vulnerability Analysis

Flask-Caching uses Python's pickle module to store and retrieve arbitrary Python objects from its configured cache backend. The pickle.loads function reconstructs objects by invoking constructors and __reduce__ methods embedded in the serialized stream. An attacker who can write entries to the cache backend can supply a payload that triggers arbitrary code execution at deserialization time.

The attack runs inside the Flask worker process. Code executes with the privileges of the application user, granting access to environment variables, secrets, database connections, and any local files readable by the process. On shared hosts or containers, this can enable lateral movement or local privilege escalation paths.

Exploitation requires the attacker to control cache entries. Realistic scenarios include shared Redis or Memcached instances without authentication, world-writable filesystem cache directories, and multi-tenant deployments where one tenant can reach another's cache namespace.

Root Cause

The root cause is the use of pickle as the default serializer for cached values. Pickle is not safe for untrusted input, and Flask-Caching did not gate deserialization on any integrity check such as a message authentication code. Any attacker-controlled bytes passed to pickle.loads can become executable instructions.

Attack Vector

The attacker first identifies the cache backend and namespace used by the target Flask application. The attacker then writes a serialized Python object whose __reduce__ method returns a callable such as os.system along with attacker-supplied arguments. When the Flask application next reads the poisoned key, pickle.loads invokes the callable and code execution occurs. No authentication to the Flask application itself is required when the cache backend is reachable.

No verified public exploit code is referenced in the advisory. See the Flask-Caching pull request and the maintainer discussion for technical details on the fix.

Detection Methods for CVE-2021-33026

Indicators of Compromise

  • Unexpected child processes spawned by the Flask application process, such as /bin/sh, python, or outbound network utilities like curl and wget
  • Cache entries containing pickle opcodes (\\x80\\x04, c__builtin__, cos\nsystem) inside Redis, Memcached, or filesystem cache files
  • Modifications to filesystem cache directories from accounts other than the Flask service account
  • Outbound connections from web worker processes to unfamiliar hosts shortly after cache reads

Detection Strategies

  • Monitor process lineage for Flask or gunicorn workers spawning shells, interpreters, or network tools
  • Inspect cache backends for serialized values that contain pickle reduce constructs or references to os, subprocess, or posix modules
  • Log all writes to shared Redis or Memcached keyspaces used by Flask-Caching and alert on writes from unexpected client IPs
  • Enable file integrity monitoring on filesystem cache directories defined by CACHE_DIR

Monitoring Recommendations

  • Forward Flask, WSGI, and cache backend logs to a centralized analytics platform for correlation across web tier and cache tier events
  • Alert on Redis AUTH failures, unauthenticated access from non-application subnets, and CONFIG SET operations
  • Track baseline child-process behavior of the Flask application and alert on deviations

How to Mitigate CVE-2021-33026

Immediate Actions Required

  • Upgrade Flask-Caching to a version that addresses the pickle deserialization issue and review the project's security advisory thread
  • Restrict network access to Redis and Memcached so only the Flask application servers can reach them, and require strong authentication on every backend
  • Tighten filesystem permissions on any directory used by the filesystem cache so only the Flask service account can read or write entries
  • Rotate secrets, session keys, and database credentials reachable from the Flask process if cache poisoning is suspected

Patch Information

Maintainers addressed the issue in the upstream repository. Review the Flask-Caching pull request 209 for the code change and upgrade to a fixed release. Confirm the deployed version with pip show flask-caching after upgrade.

Workarounds

  • Replace pickle-based serialization with a safer format such as JSON for cached values where object types are simple
  • Enforce authentication, TLS, and network segmentation on Redis and Memcached deployments
  • Run the Flask application as a low-privileged user inside a container with read-only root filesystem and seccomp restrictions to limit the impact of successful exploitation
  • Avoid sharing a single cache backend across applications with different trust levels
bash
# Example: enforce Redis authentication and bind to loopback only
# /etc/redis/redis.conf
bind 127.0.0.1
requirepass <strong-random-secret>
protected-mode yes

# Verify the installed Flask-Caching version after upgrade
pip show flask-caching | grep -i version

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Default Legacy - Prefooter | Experience the World’s Most Advanced Cybersecurity Platform

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.