IMGIITRoorkee / IMGIITRoorkee/chakra-docker

Replace python-memcached with pymemcache to remove the pickle path and unblock the Django upgrade

Open
#35 1 comment 0 reactions 0 assignees View on GitHub
audit effort:S security sev:medium
Dominant language
HTML
Stars
1
Forks
0
PR merge metrics
No merged PRs in 30d

Description

Two facts that are individually tolerable and jointly an RCE:

1. `network_mode: host` with no `command:` override, so memcached binds **`0.0.0.0:11211` with no authentication** (SASL is off by default).
2. `settings.py:131-136` uses `MemcachedCache`, backed by `python-memcached==1.59`, which **pickles** any non-`str` value it stores and `pickle.loads()` it on read.

So anyone who can `set` a key that Django later reads gets **arbitrary code execution inside the Gunicorn and Celery workers**:

```
echo -e 'set 1 0 \r\n\r' | nc 192.168.121.230 11211
```

The container has `network_mode: host` and read-write bind mounts of `/website`, `/media_files` and **`/reverse_proxy_configurations`** — and that last one is an lsyncd source. So RCE here writes nginx config onto the public server directly. **This is a shorter path to root2 than the confman authorization hole.**

Also plain data disclosure via `stats items` / `stats cachedump`.

**Correction to a common assumption:** UDP amplification is *not* applicable — memcached has shipped with UDP disabled by default since 1.5.6.

**Fix, do both:**
1. `command: memcached -l 127.0.0.1 -U 0`, or move off `network_mode: host` onto the bridge network already commented out at `docker-compose.yml:236-239`.
2. Switch to `pymemcache` + `PyMemcacheCache`, which kills the pickle path — and is a hard prerequisite for the Django upgrade anyway, since `MemcachedCache` was removed in 4.1.

---

**Evidence**

```
docker-compose.yml:138-162; chakra-backend/chakra_backend/settings.py:131-136; chakra-backend/requirements.txt:81,190
```

- Verified against: `origin/master 44ca47e (2026-07-25)`
- Verdict: **CONFIRMED**
- Reachable: Yes from the LAN (192.168.121.0/24). Not from the internet unless NAT-forwarded.
- Preconditions: Network position on the LAN, or any SSRF pivot — note parse_csv.py:19 reaches localhost from inside the host-networked container.

Contributor guide

No contributing guide indexed for this repository

Research direction

Start with docker-compose.yml:138-162, chakra-backend/chakra_backend/settings.py:131-136, and chakra-backend/requirements.txt:81,190. Review parse_csv.py:19 and the commented bridge-network configuration as entry points for understanding reachability. Done means memcached is no longer exposed unauthenticated and the Django cache uses pymemcache-compatible configuration without the pickle path, while preserving the required cache behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
django, docker, memcached, python
Domain
backend, infrastructure, security
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
52/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.