---
title: "GHSA-mxwv-x5qm-mrmf"
description: "Compute-cost limits can be bypassed in the math parser and are absent in logic/DSL engines (denial of service). Affected and fixed versions of qwed."
url: https://qwedai.com/security/advisories/ghsa-mxwv-x5qm-mrmf
---

# GHSA-mxwv-x5qm-mrmf

Compute-cost limits can be bypassed in the math parser and are absent in logic/DSL engines (denial of service)

## Summary

### Part 1 — gate skipped for non-Python-parseable input (`safe_parse_expr`)

`src/qwed_new/core/safe_parser.py` L285-288 (`_check_ast_safety`):

```python
try:
    tree = ast.parse(expression, mode="eval")
except SyntaxError:
    return          # every cost check below is skipped
```

Expressions using implicit multiplication are not valid Python, so they skip the exponent, caret-chain, factorial and literal-magnitude gates. SymPy's `implicit_multiplication_application` transformation then makes them valid, and SymPy evaluates the exact integer power eagerly.

| Input | Result |
| --- | --- |
| `9^9^9` (control) | rejected by caret-chain gate in ~1 s |
| `9^9^9 x` | **still computing after 6 s** (killed by harness) |

### Part 2 — no exponent bound in logic engines

-   `SafeEvaluator` (`LogicVerifier`) allows `ast.Pow`. Python computes `int ** int` in full before Z3 sees it. `verify_logic({"x":"Int"}, ["x == 9**9**9"])` was still running after 6 s.
-   DSL `POW` (`src/qwed_new/core/dsl/compiler.py` L184) does the same. `(EQ x (POW 9 (POW 9 9)))` via `DSLLogicVerifier.verify_from_dsl` was still running after 6 s. Reachable from `/verify/logic` through the DSL produced by the LLM translation.

Measurements: local, Windows, Python 3.11, each case in a child process with a 6 s kill timeout.

## Impact

An authenticated tenant (or LLM output via the translation path) can pin a worker CPU and grow memory with a short request. This degrades service for all tenants on that worker.

## Patches

1.  In `safe_parse_expr`, run the cost gates on the **transformed** source: apply `stringify_expr(stripped, local_dict, global_dict, transformations)` and then `ast.parse` + the existing gate walk. Or reject input that fails `ast.parse` once the transformations have been applied.
2.  Move `_static_pow` / `_check_pow_cost` into a shared helper and call it from `SafeEvaluator._validate_ast` and from `Z3Compiler` for `POW` with static operands.
3.  Regression tests: the two parts above must be rejected in under 1 s.

## Workarounds

Enforce a per-request worker timeout / process isolation for `/verify/math` and `/verify/logic`.

## Notes

This is a bypass of a previously shipped cost-limit fix. Coordinate with the related public DoS issue only after this advisory is published.
