GHSA-r3hx-x5rh-p9vv: django-haystack: Remote Code Execution via `eval()` in Elasticsearch Result Deserialization
Remote Code Execution via eval() in Elasticsearch Result Deserialization
Summary
The Elasticsearch backend in django-haystack calls eval() on raw field values returned from Elasticsearch when a SearchField is declared with an index_fieldname alias that differs from the logical field name. During result processing, the backend looks up fields by logical name but Elasticsearch stores them under the alias key; the lookup fails and the value falls through to _to_python() → eval(). An attacker who can control content that is indexed into Elasticsearch—and can trigger or wait for a search that returns it—achieves arbitrary code execution in the Django application process. CVSS 3.1 Base Score: 8.5 (High).
Details
**Sink — haystack/backends/elasticsearch_backend.py:865:**
converted_value = eval(value)
_to_python() (line ~850) attempts to parse a string value by calling eval() before performing any type-safety check. If the value is an attacker-controlled Python expression such as import('os').system(...), the expression is executed unconditionally.
**Root cause — haystack/backends/elasticsearch_backend.py:727–737:**
for key, value in source.items():
string_key = str(key)
if string_key in index.fields and hasattr(index.fields[string_key], "convert"):
additional_fields[string_key] = index.fields[string_key].convert(value)
else:
additional_fields[string_key] = self._to_python(value)
index.fields is keyed by the *logical* field name (e.g. "name"), but Elasticsearch stores the document under the index_fieldname alias (e.g. "name_s"). Because "name_s" not in index.fields, the branch falls through to self._to_python(value).
Data flow (source → sink):
1. haystack/indexes.py:226 — self.prepared_data[field.index_fieldname] = field.prepare(obj) stores data under the alias.
2. haystack/backends/elasticsearch_backend.py:218 — prepared data copied into final_data.
3. haystack/backends/elasticsearch_backend.py:236 — bulk(...) writes the document to Elasticsearch under the alia
Details
Original advisory: https://github.com/advisories/GHSA-r3hx-x5rh-p9vv
More from GitHub Security Advisories
- mediumGHSA-jr6p-8pjj-mfx6: Capsule has an incomplete fix of CVE-2026-22872: TenantResource RawItems and Generators s…2026-07-31
- mediumGHSA-68cj-mvg9-rgm2: Capsule: CapsuleConfiguration NodeMetadata regex fields lack webhook validation, allowing…2026-07-31
- mediumGHSA-ff84-5f28-78qj: re2: Out-of-bounds heap read in `exec`/`test`/`match` via attacker-influenced `lastIndex`…2026-07-31
- mediumGHSA-6hxr-mr5r-9836: re2: Global `String.prototype.match` with an empty-matchable pattern never advances → inf…2026-07-31
- mediumGHSA-x83g-979r-f5fh: Sylius Mollie Plugin has unauthenticated IDOR that leaks order token and customer PII2026-07-31