QWED
v7.2.2 GitHub 60

Type to search pages, engines and advisories.

    Looking for API details?Search the docs

    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):

    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.