From the Fable security review. obdcore/formula.py runs UNTRUSTED community-profile scaling formulas through an AST evaluator, but _BIN whitelists ast.Pow and ast.LShift/RShift with no magnitude bound. A profile formula like 9**9**9 or 1<<10**9 passes _validate at load and detonates on first decode() — computing a multi-hundred-MB integer that pins a CPU core and OOM-kills the process. It runs on the background scheduler thread; the except Exception in scheduler does NOT catch a runaway/OOM (not a raised exception). A derived PID with empty deps and formula 9**9**9 fires every tick on connect.
Fix: bound eval-time result magnitude (raise FormulaError if an int result .bit_length() > ~512); replace <</>>/** with checked wrappers (cap shift/exponent); cap expression length + AST depth at compile to avoid RecursionError. Add tests with malicious formulas.
From the Fable security review. `obdcore/formula.py` runs UNTRUSTED community-profile scaling formulas through an AST evaluator, but `_BIN` whitelists `ast.Pow` and `ast.LShift`/`RShift` with no magnitude bound. A profile formula like `9**9**9` or `1<<10**9` passes `_validate` at load and detonates on first `decode()` — computing a multi-hundred-MB integer that pins a CPU core and OOM-kills the process. It runs on the **background scheduler thread**; the `except Exception` in scheduler does NOT catch a runaway/OOM (not a raised exception). A derived PID with empty `deps` and formula `9**9**9` fires every tick on connect.
**Fix:** bound eval-time result magnitude (raise `FormulaError` if an int result `.bit_length() > ~512`); replace `<<`/`>>`/`**` with checked wrappers (cap shift/exponent); cap expression length + AST depth at compile to avoid RecursionError. Add tests with malicious formulas.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
From the Fable security review.
obdcore/formula.pyruns UNTRUSTED community-profile scaling formulas through an AST evaluator, but_BINwhitelistsast.Powandast.LShift/RShiftwith no magnitude bound. A profile formula like9**9**9or1<<10**9passes_validateat load and detonates on firstdecode()— computing a multi-hundred-MB integer that pins a CPU core and OOM-kills the process. It runs on the background scheduler thread; theexcept Exceptionin scheduler does NOT catch a runaway/OOM (not a raised exception). A derived PID with emptydepsand formula9**9**9fires every tick on connect.Fix: bound eval-time result magnitude (raise
FormulaErrorif an int result.bit_length() > ~512); replace<</>>/**with checked wrappers (cap shift/exponent); cap expression length + AST depth at compile to avoid RecursionError. Add tests with malicious formulas.