Skip to main content
Vulnerability Database/CVE-2026-105283

CVE-2026-105283: ash_typescript Information Disclosure Flaw

CVE-2026-105283 is an information disclosure vulnerability in ash_typescript that exposes internal Elixir terms through error responses. Attackers can read sensitive data by triggering unhandled errors. This article covers technical details, affected versions, impact assessment, and mitigation strategies.

Published:

CVE-2026-105283 Overview

CVE-2026-105283 is an information disclosure vulnerability in the ash_typescript Elixir library maintained by the ash-project. The flaw resides in AshTypescript.Rpc.ErrorBuilder.build_error_response/1, which renders unhandled pipeline error terms through inspect/1 and places the result in the client-facing details.error field. Unauthenticated attackers can provoke errors with no dedicated builder clause and read internal Elixir terms from the Remote Procedure Call (RPC) error response. The issue affects ash_typescript versions from 0.1.0 before 0.19.1 and is classified under [CWE-209] Generation of Error Message Containing Sensitive Information.

Critical Impact

Remote, unauthenticated attackers can extract internal Elixir terms, including raw Ash.Type cast errors and Ash.Info.Manifest.Type struct contents, by crafting malformed RPC requests.

Affected Products

  • ash_typescript 0.1.0 through 0.19.0
  • Elixir applications exposing Ash RPC endpoints via HTTP or Phoenix channels
  • Any ash-project deployment relying on the vulnerable error builder path

Discovery Timeline

  • 2026-10-12 - CVE CVE-2026-105283 published to NVD
  • 2026-10-16 - Last updated in NVD database

Technical Details for CVE-2026-105283

Vulnerability Analysis

The ash_typescript library bridges Ash resources to TypeScript clients over an RPC transport. When the RPC pipeline fails, AshTypescript.Rpc.ErrorBuilder.build_error_response/1 in lib/ash_typescript/rpc/error_builder.ex maps known error shapes to sanitized client responses. Terms that match no specific clause fall through to a generic branch that calls inspect/1 and places the output in details.error of the response.

Ash exceptions take a different path through AshTypescript.Rpc.Errors, where unhandled cases are redacted behind an errorId. The error builder fallback has no equivalent redaction, so any term reaching the generic branch is serialized verbatim into the HTTP or channel response. Note that resource module names in vars.resource are considered non-sensitive and remain in scope.

Root Cause

The root cause is an unsafe default clause that trusts inspect/1 output to be safe for client consumption. Two concrete request paths deliver unhandled terms into this branch:

  • A struct-typed action argument containing an invalid nested value causes cast_map_to_struct/2 in lib/ash_typescript/rpc/input_formatter.ex to throw the raw Ash.Type cast error into the builder.
  • Field selection on a generic action that returns a primitive triggers format_field_type/1, which inspects the full Ash.Info.Manifest.Type struct into vars.returnType.

Attack Vector

An unauthenticated remote attacker sends a crafted RPC request to a vulnerable endpoint. The request supplies an invalid nested value for a struct-typed argument or requests field selection on a generic action returning a primitive. The server returns an error response containing inspected internal Elixir terms, exposing implementation details that aid further reconnaissance.

elixir
# Security patch excerpt from lib/ash_typescript/rpc/error.ex
# Adds a dedicated clause for Ash.Error.Action.InvalidArgument so the
# generic inspect/1 fallback no longer handles this case.
defimpl AshTypescript.Rpc.Error, for: Ash.Error.Action.InvalidArgument do
  def to_error(error) do
    %{
      message: Map.get(error, :message) || Exception.message(error),
      short_message: "Invalid argument",
      vars: Map.new(error.vars || []) |> Map.put(:field, Map.get(error, :field)),
      type: "invalid_argument",
      fields: List.wrap(Map.get(error, :field)),
      path: error.path || []
    }
  end
end

Source: GitHub Commit 4b3c652

Detection Methods for CVE-2026-105283

Indicators of Compromise

  • RPC error responses containing a details.error field with inspected Elixir term syntax, such as %Ash.Error... or #Function<...> fragments.
  • Repeated 4xx or 5xx RPC responses from the same client that include varying vars.returnType struct dumps.
  • Request patterns that submit malformed nested struct arguments to Ash RPC actions.

Detection Strategies

  • Inspect outbound RPC error payloads for serialized Elixir term signatures leaking from details.error or vars.returnType.
  • Correlate crafted RPC inputs targeting generic actions returning primitives with subsequent anomalous error responses.
  • Review application logs for cast_map_to_struct/2 and format_field_type/1 call sites emitting unexpected inspect output.

Monitoring Recommendations

  • Instrument the RPC layer to count unhandled error-builder fallbacks and alert when the rate increases.
  • Capture full request and response bodies for RPC endpoints during incident response to validate exposure.
  • Monitor dependency manifests (mix.exs, mix.lock) for ash_typescript versions below 0.19.1.

How to Mitigate CVE-2026-105283

Immediate Actions Required

  • Upgrade ash_typescript to version 0.19.1 or later across all Elixir applications.
  • Audit RPC error-handling middleware to ensure no unsanitized term is forwarded to clients.
  • Review access logs for prior requests that produced inspect-formatted error details.

Patch Information

The fix is distributed in ash_typescript 0.19.1. Upstream commits 4b3c652 and 8e204ce add dedicated error clauses, remove the leaky inspect fallback, and begin migrating to a new RPC pipeline. See the GitHub Security Advisory GHSA-7gxc-w225-f7f3 and the CNA advisory for full details.

Workarounds

  • Wrap the RPC handler to strip or redact the details.error field before responding to clients.
  • Add defensive clauses in a local fork of build_error_response/1 that replace inspected terms with a static identifier.
  • Restrict exposure of generic Ash actions returning primitives until the upgrade is deployed.
bash
# Pin the fixed version in mix.exs and refresh the lockfile
# {:ash_typescript, "~> 0.19.1"}
mix deps.update ash_typescript
mix deps.get
mix compile --warnings-as-errors

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.