CVE-2026-49249 Overview
CVE-2026-49249 is a resource exhaustion vulnerability in Boruta, a standalone OAuth 2.0 and OpenID Connect authorization server. Versions prior to 0.10.0 atomize every key of a user-supplied request body via Elixir's String.to_atom/1 before validation. Because the BEAM virtual machine permanently interns atoms in a fixed-size table, an authenticated user can send crafted PUT /users/settings requests to exhaust the global atom table. Once the table fills, the BEAM aborts with no more index entries in atom_tab and the entire OIDC server crashes, taking the auth, admin, and gateway umbrella applications offline. The issue is fixed in version 0.10.0.
Critical Impact
Any authenticated end user can crash the entire Boruta OIDC deployment by submitting requests with fresh JSON keys, exhausting the BEAM atom table and terminating all umbrella applications.
Affected Products
- Boruta authorization server versions prior to 0.10.0
- BorutaIdentityWeb.UserSettingsController component
- Umbrella deployments including auth, admin, and gateway applications
Discovery Timeline
- 2026-09-02 - CVE-2026-49249 published to NVD
- 2026-09-02 - Last updated in NVD database
Technical Details for CVE-2026-49249
Vulnerability Analysis
The vulnerability resides in BorutaIdentityWeb.UserSettingsController.update/2. The controller passes every key from the request body through String.to_atom/1 before any schema validation runs. In the BEAM runtime, atoms are permanently interned and never garbage collected. The default atom table caps at 1,048,576 entries, configurable via the ERL_MAX_ATOMS environment variable.
An attacker sends PUT /users/settings requests containing user parameters with fresh key names on every request. Each unique key creates a new atom that persists for the lifetime of the VM. Failing validations still trigger atom creation because atomization occurs before the downstream Accounts.update_user/6 call. This vulnerability is classified under [CWE-400: Uncontrolled Resource Consumption].
Root Cause
The root cause is unsafe use of String.to_atom/1 on untrusted input. Elixir provides String.to_existing_atom/1 for exactly this scenario, which only converts strings that already correspond to known atoms. The controller should either use existing-atom conversion or rely on Ecto.Changeset casting, which safely maps string keys to schema fields without creating new atoms.
Attack Vector
Exploitation requires only a valid end-user session. The vulnerable route is protected by require_authenticated_user and a per-IP rate limit of 10 requests per second. A single authenticated attacker sending 10 requests per second, each with 100 unique keys, generates roughly 1,000 new atoms per second and can exhaust a default atom table in under 20 minutes. Distributed accounts or IP rotation accelerate exhaustion further. Once atom_tab is full, the BEAM aborts the entire node.
Detection Methods for CVE-2026-49249
Indicators of Compromise
- Elevated atom counts reported by :erlang.system_info(:atom_count) approaching the ERL_MAX_ATOMS ceiling
- BEAM crash logs containing the fatal error message no more index entries in atom_tab
- Repeated PUT /users/settings requests from a single authenticated principal with high-cardinality JSON keys
Detection Strategies
- Instrument the Phoenix endpoint to log request body key names and alert on unusual key cardinality per user session
- Monitor BEAM VM telemetry for atom table growth rate that exceeds baseline organic growth
- Correlate authentication logs with process supervisor restarts of the auth, admin, or gateway applications
Monitoring Recommendations
- Export :erlang.system_info(:atom_count) to Prometheus or your metrics backend and alert at 70% of ERL_MAX_ATOMS
- Enable structured access logging on /users/settings and track distinct parameter keys per authenticated user over rolling windows
- Forward BEAM crash dumps and Phoenix error logs to a centralized SIEM for correlation with user activity
How to Mitigate CVE-2026-49249
Immediate Actions Required
- Upgrade Boruta to version 0.10.0 or later, which replaces unsafe atomization with validated parameter handling
- Restrict access to /users/settings at the reverse proxy layer to trusted networks until patching completes
- Rotate any long-lived end-user sessions after patching if abuse is suspected
Patch Information
The fix is available in Boruta 0.10.0. Review the GitHub Release 0.10.0 notes and the GitHub Security Advisory GHSA-q428-ch8m-94gg for the complete remediation details and code changes.
Workarounds
- Increase ERL_MAX_ATOMS to delay exhaustion while planning the upgrade, understanding this only raises the bar and does not eliminate the flaw
- Tighten the per-IP rate limit on /users/settings and add per-user rate limits to reduce the request budget available to a single account
- Deploy a Web Application Firewall rule that rejects PUT /users/settings bodies exceeding a small maximum number of user[*] keys per request
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.