Authenticated Remote Code Execution in qwed via Unsafe SymPy Parsing
The qwed package (version 5.1.1) fails to sanitize input in math verification endpoints, allowing authenticated attackers to achieve remote code execution via unsafe SymPy expression evaluation.
The qwed package, specifically version 5.1.1, contains an authenticated remote code execution (RCE) vulnerability stemming from the unsafe use of sympy.parsing.sympy_parser.parse_expr(). The application exposes two primary endpoints, POST /verify/math and POST /verify/batch, which accept user-supplied mathematical expressions. These inputs are passed directly to parse_expr() without configuring a restricted namespace for the underlying eval() call. Any user, including those creating new accounts via the default-enabled /auth/signup endpoint, can supply arbitrary Python code within these expressions. This allows for full server-side command execution under the context of the running application process. The lack of sandbox parameters (global_dict and local_dict) in the SymPy calls effectively disables Python's built-in security boundaries, enabling attackers to read files, modify the local database, or execute OS-level commands.
Attack Chain
- Attacker interacts with the
POST /auth/signupendpoint to create a standard, unprivileged tenant account. - Attacker uses the returned JWT to authenticate requests to the
POST /auth/api-keysendpoint to generate a persistent API key. - Attacker identifies the
POST /verify/mathorPOST /verify/batchendpoints as injection sinks for user-supplied math queries. - Attacker constructs a malicious Python expression payload using
pathliborosmodules to interact with the host filesystem. - Attacker submits the payload within the JSON
expressionfield (for/verify/math) orqueryfield (for/verify/batch) using the previously generated API key. - The server application receives the request and passes the unvalidated input string directly to the vulnerable
parse_expr()function. - The SymPy library evaluates the injected Python code string via
eval()within the process memory space. - Final objective reached: arbitrary command execution, leading to complete server compromise or data exfiltration.
Impact
Successful exploitation results in full remote code execution, granting the attacker the same permissions as the system user running the qwed API server. This permits unauthorized read/write access to the host filesystem, exfiltration of environment variables containing sensitive secrets (e.g., QWED_JWT_SECRET_KEY), modification of persistent data, and potential lateral movement within the container or host environment.
Recommendation
Prioritize patching the qwed package to a version that sanitizes all input passed to SymPy's parse_expr() function. If upgrading is not immediately possible, implement strict input validation to ensure math expressions only contain alphanumeric characters and expected mathematical operators, preventing the injection of Python syntax. Additionally, utilize the provided Sigma detection rule to monitor for suspicious POST requests to verification endpoints containing Python built-ins or module import syntax.
Immediate actions
Monitor logs for POST requests to /verify/math and /verify/batch containing import or subprocess strings
Mitigations
Upgrade qwed to a version containing fixed input sanitization
qwed 5.1.1
Detection coverage 1
Detect qwed Authenticated RCE Attempt via Malicious Math Expression
highDetects exploitation attempts against qwed where the math expression field contains suspicious Python-like syntax or module imports.
Detection queries are available on the platform. Get full rules →