Unrestricted Resource Consumption

Unrestricted Resource Consumption in Flask: CVE-2021-33026 [CVE-2021-33026]

[Fixed 2021-08] Updated CVE-2021-33026

Overview

CVE-2021-33026 describes a deserialization risk in Flask-Caching up to version 1.10.1 where the extension relies on Pickle for serialization. If an attacker gains access to the cache storage (filesystem, Memcached, Redis, etc.), they can inject a crafted payload that, when deserialized by the application, can execute arbitrary Python code. This aligns with CWE-502 (Deserialization of untrusted data) and can lead to remote code execution and potential local privilege escalation. In real deployments, the risk is most acute when cache backends are writable by untrusted users or exposed to attackers; otherwise, exploitation is unlikely but remains possible if they can poison the cache. In practice, a poisoned cache entry is written by an attacker to the cache store; later, when the application retrieves that key, the deserialization step via Pickle executes the attacker’s payload, potentially running system commands or other harmful actions under the application's privileges. This is not limited to remote execution-the attacker could cause resource-heavy operations or trigger privilege escalation depending on the payload and the host’s configuration. The vulnerability is mitigated by upgrading Flask-Caching to a patched version and/or switching to a safe serializer that does not execute code during deserialization. To mitigate the issue in Flask apps, upgrade Flask-Caching to a patched release (1.10.2 or later) and consider configuring a non-Pickle serializer (for example, JSON) to avoid arbitrary code execution during deserialization. Additionally, tightly secure cache backends (restrict access, enable authentication, and place caches behind proper network controls), avoid caching untrusted data, and implement input validation and TTL controls. After patching, purge or rotate cache contents as needed and monitor for unexpected cache writes or access patterns. This guide focuses on the Unrestricted Resource Consumption angle by describing how unsafe deserialization can lead to abuse of cached resources and how to mitigate by safe serialization and proper access controls in Flask applications.

Affected Versions

Flask-Caching <= 1.10.1

Code Fix Example

Flask API Security Remediation
Vulnerable pattern (untrusted objects serialized with pickle in Flask-Caching):

from flask import Flask
from flask_caching import Cache

app = Flask(__name__)
app.config['CACHE_TYPE'] = 'filesystem'
app.config['CACHE_DIR'] = '/tmp/flask_cache'
cache = Cache(app)

class MaliciousPayload:
    def __reduce__(self):
        import os
        return (os.system, ('echo vulnerable cache payload',))

# Attacker-controlled payload written to cache (poisoning risk)
cache.set('payload', MaliciousPayload())

@app.route('/')
def index():
    # Deserialization occurs on get; if attacker poisoned cache, code may execute
    v = cache.get('payload')
    return f'payload_loaded={bool(v)}'

# Fix (safe serialization):
from flask import Flask
from flask_caching import Cache as CacheSafe

app = Flask(__name__)
app.config['CACHE_TYPE'] = 'filesystem'
app.config['CACHE_DIR'] = '/tmp/flask_cache'
# Use a safe serializer to avoid pickle-based deserialization
app.config['CACHE_SERIALIZER'] = 'json'
cache_safe = CacheSafe(app)

# Store only safe, JSON-serializable data
cache_safe.set('payload', {'status': 'ok'})

@app.route('/')
def index_safe():
    v = cache_safe.get('payload')
    return f'payload_loaded={bool(v)}'

CVE References

Choose which optional cookies to allow. You can change this any time.