CVE-2026-87874: Community.general: community.general: memcached cache plugin deserializes untrusted pickle data from memcached, enabling cache-poisoning remote code execution on the ansible controller
A flaw was found in the memcached cache plugin of the community.general Ansible collection. Although its documentation states that records are stored in JSON format, the plugin performs no explicit serialization and relies on python-memcached, which pickles values on write and unpickles them on read. Because memcached is unauthenticated and cache keys are predictable, an attacker able to reach a network-exposed or shared memcached instance can write a crafted pickle payload that is deserialized and executed on the Ansible controller when the poisoned fact cache is next read, leading to remote code execution.
Other sources
plugins/cache/memcached.py documents "JSON formatted" records (line 13) but imports neither json nor pickle and does no explicit (de)serialization. set() passes the Ansible facts dict directly to python-memcached with mincompresslen=1 (lines 214-217); get() returns the client result unchanged (lines 201-212). python-memcached auto-pickles non-str/int values (FLAGPICKLE) and, with mincompresslen set, compresses them (FLAGCOMPRESSED) -> stored flags 9, and calls pickle.loads() on read. The sibling plugins/cache/redis.py uses explicit AnsibleJSONEncoder/Decoder (lines 189, 194). memcached has no authentication and the key is "ansiblefacts<host>" (default prefix, lines 31/193-194), so an attacker with network reach to the memcached instance can poison a fact-cache entry that the controller unpickles on the next read, yielding code execution as the ansible user. Upstream: https://github.com/ansible-collections/community.general plugins/cache/memcached.py — UNFIXED (no PR; no public CVE) Affected file: plugins/cache/memcached.py (:13 docstring, :201-217 get/set)
— Red Hat
Affected Software
Event History
Frequently Asked Questions
Which deployments are exposed to exploitation?
Deployments using the community.general memcached cache plugin are exposed when their memcached instance is network-accessible to an attacker or shared with an untrusted party. The issue affects the Ansible controller that reads facts from the poisoned cache.
What access does an attacker need?
An attacker does not need Ansible privileges or user interaction. They need network access sufficient to write a crafted value to the relevant unauthenticated memcached instance; predictable cache keys make targeting the fact-cache entry feasible.
What can be done while a fix is not available?
Prevent untrusted systems from reaching the memcached service and avoid sharing that cache instance with untrusted tenants or workloads. This removes the ability to inject the crafted cache value that is later deserialized by the controller.
When does code execution occur after cache poisoning?
Execution occurs when the Ansible controller next reads the poisoned fact-cache record. The plugin returns the python-memcached result unchanged, causing python-memcached to unpickle stored non-string values.