Full Report
Flask is a very popular Python based web framework. The author was poking around their tech stack and noticed a library called Flask_Session, which was used for server-side session application management. This can be Redis or Memcached as the backend for it. In previous talk at Black hat 2014 by Ivan Novikov they used a Memcache injection to get RCE via bad data deseralization. Even more recently, a SSRF in vBulletin got RCE by arbitrarily serialized data injection into Memcached. Memcached is a newline based protocol when communicating with it. So, being able to add unescaped CRLF to the keys or values would allow for adding in extra commands. The two main commands are set and get. When calling save_session() to store the information in memcached the set() call doesn't escape CSRF. As a result, a controlled session can be used to get control over arbitrary commands. Since \r\n can't be used in an HTTP call, we have to escape them in the header. According to the HTTP spec (which I didn't know) this can be done by octal encoding them with a slash. For instance, \015\012 works for this. I think they add in a pickle payload, which will then be processed by memcache, in order to get RCE. Overall, a super interesting bug class that I hadn't considered!
Analysis Summary
# Vulnerability: Remote Code Execution via Memcached Command Injection in Flask-Session
## CVE Details
- **CVE ID**: Not explicitly assigned in the article (matches patterns similar to CVE-2020-17526, but specific to `Flask-Session` + `pylibmc` integration).
- **CVSS Score**: Estimated 9.8 (Critical)
- **CWE**: CWE-94 (Code Injection), CWE-159 (Failure to Sanitize Special Characters), CWE-502 (Deserialization of Untrusted Data)
## Affected Systems
- **Products**: Flask-Session (extension for the Flask web framework).
- **Versions**: Current versions as of Feb 2023 using `pylibmc` or `python-memcached` backends.
- **Configurations**:
- Application must use `Flask_Session` with a **Memcached** backend.
- Application must use the default **serialization (Python Pickle)**.
- Use of the `pylibmc` client (which does not escape keys) or similar clients vulnerable to CRLF injection.
## Vulnerability Description
The flaw exists in how `Flask-Session` handles session identifiers when storing data in Memcached. The `save_session` function concatenates a prefix with the `session.sid` (session ID) to create a Memcached key. Because the `session.sid` is taken from an HTTP cookie and is not sanitized for carriage return/line feed (CRLF) characters, an attacker can inject arbitrary Memcached commands into the protocol stream.
By leveraging RFC2109/RFC2068 octal encoding (e.g., `\015\012`), an attacker can bypass standard HTTP header restrictions to deliver a CRLF payload. This allows the attacker to "break out" of the intended `set` command and issue a new `set` command containing a malicious Python **Pickle** payload. When the application later attempts to retrieve and deserialize this session data, the Pickle payload executes arbitrary code.
## Exploitation
- **Status**: PoC available.
- **Complexity**: Medium (Requires understanding of Memcached protocol and Pickle serialization).
- **Attack Vector**: Network (Remote via HTTP Cookie header).
## Impact
- **Confidentiality**: Critical (Full access to server environment and data).
- **Integrity**: Critical (Ability to modify application logic and data).
- **Availability**: Critical (Ability to crash the service or delete data).
## Remediation
### Patches
- No specific patch version was cited in the article; however, users should update `Flask-Session` and ensure their Memcached client (like `pylibmc`) is the latest version.
- **Note**: The primary fix involves the library or application sanitizing the `session.sid` to strip control characters before passing it to the backend.
### Workarounds
- **Switch Serializers**: Change the Flask-Session serializer from `pickle` to a safer format like `json`.
- **Backend Validation**: Implement a custom session interface that validates that `session.sid` contains only alphanumeric characters.
- **WAF Rules**: Configure Web Application Firewalls to block octal-encoded control characters (`\015`, `\012`) in the `Cookie` header.
## Detection
- **Indicators of compromise**:
- Unexpected entries in Memcached logs containing `set` or `get` commands within unexpected key names.
- Large or unusual binary blobs stored in Memcached keys.
- **Detection methods**:
- Monitor for octal-encoded sequences in HTTP `Cookie` headers (e.g., `\015\012` or `\15\12`).
- Use network security monitoring (NSM) to inspect traffic between the web server and the Memcached instance for multiple commands in a single packet.
## References
- [D4D Blog Original Article](https://d4dblog.org/memcached-command-injections-at-pylibmc/)
- [Black Hat 2014: Memcached Injections - Ivan Novikov](https://www[.]blackhat[.]com/docs/us-14/materials/us-14-Novikov-The-New-Page-Of-Injections-Book-Memcached-Injections-WP.pdf)
- [Flask-Session Documentation](https://flask-session[.]readthedocs[.]io/en/latest/)
- [Exploiting Python Pickles](https://davidhamann[.]de/2020/04/05/exploiting-python-pickle/)