CVE-2026-82733 Overview
CVE-2026-82733 is an information disclosure vulnerability in the ash_typescript library from the ash-project. The flaw exists in the typed controller request handler, where an unexpected return value from a route handler is inspected and interpolated directly into an HTTP 500 error response body. Unauthenticated attackers can trigger this path to read internal application data, including hashed passwords, tokens, and tenant identifiers, from any handler that falls through without returning a %Plug.Conn{}. The issue affects ash_typescript from version 0.15.0 before 0.18.0 and is categorized under CWE-209: Generation of Error Message Containing Sensitive Information.
Critical Impact
Unauthenticated remote attackers can extract serialized Elixir structs, including credentials and tenant identifiers, from HTTP 500 responses produced by typed controller handlers.
Affected Products
- ash_typescript 0.15.0 through versions prior to 0.18.0
- Elixir/Phoenix applications using AshTypescript typed controllers
- Applications relying on AshTypescript.TypedController.RequestHandler for route dispatch
Discovery Timeline
- 2026-09-01 - CVE-2026-82733 published to NVD
- 2026-09-01 - Last updated in NVD database
Technical Details for CVE-2026-82733
Vulnerability Analysis
The vulnerability resides in dispatch/3 within lib/ash_typescript/typed_controller/request_handler.ex. When a typed-controller route handler returns any value that is not a %Plug.Conn{} struct, dispatch/3 forwards the value to unexpected_return/2. That function calls inspect(value, limit: 50) and interpolates the resulting string directly into the JSON error message returned to the caller.
The limit: 50 option applies per collection element, not to the whole term. As a result, a fall-through return such as {:error, %User{}} or an Ecto changeset serializes its full field set. Sensitive attributes including hashed passwords, session tokens, API keys, and tenant identifiers appear in the HTTP 500 response body.
This behavior contradicts the module's own posture in the sibling rescue clause. The rescue path gates Exception.message/1 behind AshTypescript.typed_controller_show_raised_errors?/0 and otherwise returns a generic message. The unexpected-return path is ungated and always echoes the inspected value.
Root Cause
The root cause is missing configuration gating on the error detail path. unexpected_return/2 unconditionally embedded inspect/2 output in the response body, while raised-exception details were correctly gated behind an application configuration flag. The limit parameter passed to inspect/2 also failed to bound the overall term size, allowing full struct serialization.
Attack Vector
An unauthenticated network attacker sends crafted requests to any typed controller endpoint whose handler may fall through with a non-Plug.Conn term on an error branch. The attacker parses the resulting HTTP 500 JSON body to extract the leaked struct data. No authentication, user interaction, or prior access is required.
// Patch excerpt: lib/ash_typescript.ex
- Gets whether to show actual exception messages in typed controller 500 responses.
+ Gets whether to show actual error detail in typed controller 500 responses.
When `false` (default), 500 responses return "Internal server error".
- When `true`, the actual exception message is included.
+ When `true`, the actual exception message — or the inspected value of an
+ unexpected (non-`%Plug.Conn{}`) handler return — is included.
Source: GitHub Commit dec80e29
The patch extends the existing show_raised_errors? gate to cover the unexpected-return branch, adds require Logger to request_handler.ex for server-side diagnostics, and updates the documentation to reflect the broader semantics of the flag.
Detection Methods for CVE-2026-82733
Indicators of Compromise
- HTTP 500 responses from typed controller routes containing serialized struct fragments such as %User{, %Changeset{, or hashed_password:.
- Unusual JSON error bodies that include Elixir map or struct syntax rather than the generic "Internal server error" message.
- Repeated 5xx responses from /api/* endpoints correlated with client probing of edge cases and error branches.
Detection Strategies
- Inspect application access and error logs for HTTP 500 responses originating from AshTypescript.TypedController routes, and review their response bodies for leaked struct content.
- Add a response-body filter at the reverse proxy or web application firewall layer to flag error responses containing inspect/2 style output (for example %, <<, :__struct__).
- Audit deployed ash_typescript dependency versions across services and flag any environment on 0.15.0 through 0.17.x.
Monitoring Recommendations
- Alert on spikes of HTTP 500 responses from typed controller endpoints, especially with response body sizes above the expected error baseline.
- Correlate 500 responses with unauthenticated source IPs performing parameter fuzzing against JSON APIs.
- Track outbound response payloads containing patterns matching secret formats such as bcrypt or Argon2 hashes and session tokens.
How to Mitigate CVE-2026-82733
Immediate Actions Required
- Upgrade ash_typescript to version 0.18.0 or later in all Elixir applications that expose typed controllers.
- Ensure AshTypescript.typed_controller_show_raised_errors?/0 is set to false in production configuration; this is the default and it now also gates unexpected-return detail.
- Rotate any secrets, session tokens, API keys, and password hashes that may have been logged or transmitted via prior 500 responses.
Patch Information
The fix is delivered in commit dec80e29, released in ash_typescript 0.18.0. The patch places the inspect/2 output of unexpected handler returns behind the same configuration flag that already governed exception messages, and documents the new behavior. Additional context is available in the GitHub Security Advisory GHSA-ghhw-qh7p-55xr, the CNA advisory for CVE-2026-82733, and the OSV record EEF-CVE-2026-82733.
Workarounds
- If upgrading immediately is not possible, audit all typed controller handlers to guarantee they return a %Plug.Conn{} on every code path, including error branches.
- Wrap typed controller pipelines with a plug that rewrites any 500 response body to a generic error message before it reaches the client.
- Explicitly set config :ash_typescript, :show_raised_errors, false and confirm the setting after deployment.
# Configuration example: config/prod.exs
config :ash_typescript,
show_raised_errors: false
# Then upgrade the dependency in mix.exs:
# {:ash_typescript, "~> 0.18.0"}
# and run:
mix deps.update ash_typescript
mix deps.get
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

