| CVE |
Vendors |
Products |
Updated |
CVSS v3.1 |
| Generation of Error Message Containing Sensitive Information vulnerability in ash-project ash_typescript allows an unauthenticated attacker to read internal application data from an HTTP 500 response body.
When a typed-controller route handler returns anything other than a %Plug.Conn{}, dispatch/3 in lib/ash_typescript/typed_controller/request_handler.ex passes the value to unexpected_return/2, which interpolates inspect(value, limit: 50) directly into the response message. The limit option bounds elements per collection rather than the term as a whole, so a handler falling through with a term such as {:error, %User{}} or a changeset serialises its full field set, including hashed passwords, tokens, and tenant identifiers, into the JSON error returned to the caller.
This contradicts the module's own posture elsewhere: the rescue clause gates Exception.message/1 behind AshTypescript.typed_controller_show_raised_errors?/0 and otherwise returns a generic message, while this path is ungated and always echoes.
This issue affects ash_typescript: from 0.15.0 before 0.18.0. |
| Authorization Bypass Through User-Controlled Key vulnerability in ash-project ash_phoenix lets an attacker who controls filter form parameters filter across relationships the resource author marked non-public, turning the returned rows into a boolean oracle over private related data.
AshPhoenix.FilterForm resolved every relationship hop in the user-supplied path with Ash.Resource.Info.related/2, which traverses private relationships, and only checked the terminal field for publicity. parse_path_and_field/2 also rewrote a field naming a relationship into an extra path segment, so field=some_private_rel was accepted too. Both path and field come straight from form params, and the resulting ref went to Ash.Query.do_filter/2 without the public-only enforcement of Ash.Filter.parse_input/2. The fix resolves each hop with Ash.Resource.Info.public_relationship/2, rejecting the first non-public hop, and requires the terminal field to be public.
This issue affects ash_phoenix: from 0.6.0-rc.1 before 2.3.25. |
| Improper Input Validation vulnerability in ash-project ash_typescript allows a remote attacker to submit argument values outside a declared allowlist or bound on typed-controller routes.
AshTypescript.TypedController.RequestHandler in lib/ash_typescript/typed_controller/request_handler.ex calls Ash.Type.cast_input/3 and treats an {:ok, cast} result as fully validated. In Ash these are separate steps: cast_input/3 only coerces the term, while every constraint declared on the argument is applied by Ash.Type.apply_constraints/3, which this path never calls. Constraints such as one_of, max_length, min and max, and match are therefore inert, so a value outside a declared allowlist is accepted and passed to the route handler. Codegen renders the same constraints into the generated TypeScript types, so an allowlist appears enforced to a TypeScript caller while any other HTTP client ignores it. Empty-string to nil normalization also lives in apply_constraints, so the allow_nil?: false check accepts "" for a required argument.
Where a constraint gates a role, a status, or a sort direction, this becomes a privilege or state-machine bypass.
This issue affects ash_typescript: from 0.15.0 before 0.18.0. |
| Incorrect Authorization vulnerability in ash-project ash_typescript allows an unauthorized RPC caller to read attribute values that Ash field policies denied.
When a field policy denies an attribute, Ash substitutes %Ash.ForbiddenField{}, which retains the real value in original_value because embedded resources must remain writable, and hides it from Inspect rather than removing it. AshTypescript.Rpc.ResultProcessor strips these markers to nil on its template-driven paths, but normalize_primitive/1 in lib/ash_typescript/rpc/result_processor.ex had no such clause, so a marker fell through to the generic struct branch which calls Map.from_struct/1 and serializes every key, original_value included. The denied value is returned to the caller inside the marker that represents its own denial.
The simplest trigger is an action returning an embedded resource as a map, which routes through normalize_resource_struct/2 with an empty template. normalize_value_for_json/1 is a public, unguarded entry point to the same path.
This issue affects ash_typescript: from 0.11.0 before 0.18.0. |
| Allocation of Resources Without Limits or Throttling vulnerability in ash-project ash_typescript allows an unauthenticated attacker to exhaust the BEAM atom table and abort the node via client-supplied typed struct field names.
resolve_typed_struct_field/2 in lib/ash_typescript/rpc/field_processing/field_selector.ex looks a client-supplied field name up in the typed struct's reverse map and, when it finds no match, falls back to String.to_atom/1. Because this runs before any field-existence check, an unresolvable name mints a permanent atom rather than being rejected as unknown. Atoms are never garbage collected, so a request carrying many distinct names on a typed struct field grows the atom table until the VM aborts at its limit.
This issue affects ash_typescript: from 0.11.0 before 0.18.0. |
| Uncontrolled Resource Consumption vulnerability in ash-project ash lets a slow asynchronous read spin a scheduler thread at full CPU while the framework waits for it.
Ash.Actions.Read.AsyncLimiter.await_at_least_one/1 (lib/ash/actions/read/async_limiter.ex) waited for concurrent async read tasks by polling each with Task.yield(task, 0) in a tight loop rather than blocking. While every outstanding task is still running (a slow related-data load or calculation), the loop returns immediately and repeats, busy-spinning and holding a BEAM scheduler at full CPU for the whole duration of the slow read; concurrent slow reads tie up further schedulers. The fix waits with Task.yield_many (a non-blocking sweep followed by a blocking wait with timeout: :infinity), so the process sleeps until a task completes instead of spinning.
This issue affects ash: from 2.19.0 before 3.32.2. |
| Uncontrolled Resource Consumption vulnerability in ash-project ash lets an attacker exhaust node memory by matching a filter that spans multiple to-many relationships in memory.
Ash.Filter.Runtime matches a filter against an in-memory record by first expanding the record into combinations of its related rows. flatten_relationships/2 (lib/ash/filter/runtime.ex) eagerly built the full Cartesian product across the filter's to-many relationship paths, so a record with K to-many relationships of M rows each materialized on the order of M^K scenarios before any predicate was checked. A filter or dataset that reaches several sizeable to-many relationships therefore allocates memory combinatorially and can exhaust the node. The fix streams the expansion lazily and short-circuits on the first matching scenario, bounding the work.
This issue affects ash: from 1.29.0-rc0 before 3.32.2. |
| Improper Input Validation vulnerability in ash-project ash fails to enforce the outer array constraints on a doubly-nested {:array, {:array, type}} attribute, letting invalid input pass validation.
Ash.Type.apply_constraints/3 (lib/ash/type/type.ex) handled the {:array, {:array, type}} case by mapping only the inner {:array, type} constraints over each element, so constraints declared on the outer array (such as min_length, max_length, and nil_items?) were never applied. An attacker could submit an outer list that violates those constraints (too many elements, or nil entries where disallowed) and have it accepted and persisted. The fix enforces the outer array constraints and adds explicit handling for nil and non-list inputs.
This issue affects ash: from 2.16.1 before 3.32.2. |
| Generation of Error Message Containing Sensitive Information vulnerability in ash-project ash discloses the stored value of a confirmed field to an actor who fails its confirmation check.
Ash.Resource.Validation.Confirm's atomic implementation (atomic/2 in lib/ash/resource/validation/confirm.ex) built the mismatch error with its value set to the field being confirmed. When the actor supplies only the confirmation argument and not the field itself, value resolves through atomic_ref/2 to the field's current stored value, so the mismatch error echoes that stored value back to the actor. Against a confirmation guarding a sensitive attribute, an actor can submit a deliberately wrong confirmation and read the real value from the returned error. The fix reports the actor-supplied confirmation in the error instead of the stored field value.
This issue affects ash: from 2.17.20 before 3.32.2. |
| Improper Input Validation vulnerability in ash-project ash allows an attacker to persistently deny reads of a record by storing a non-version-7 UUID in an Ash.Type.UUIDv7 attribute.
Ash.Type.UUIDv7.cast_input/2 accepts any well-formed UUID string, including non-version-7 UUIDs, and stores it as a 16-byte binary. On read, cast_stored/2 (lib/ash/type/uuid_v7.ex) routes the stored binary back through cast_input/2, which since an input-validation tightening in v3.6.3 matches only version-7 (and optionally version-4) 16-byte binaries and otherwise expects a 36-character string. A stored non-v7 16-byte binary matches neither clause and returns :error, so every later read of that record fails. An attacker able to set such an attribute poisons the row permanently. The fix decodes any 16-byte stored binary directly in cast_stored/2.
This issue affects ash: from 3.6.3 before 3.32.2. |
| Integer Overflow or Wraparound vulnerability in ash-project ash lets an attacker corrupt a stored vector and crash later reads of it by submitting a vector with more than 65,535 elements.
Ash.Vector.new/1 (lib/ash/vector.ex) encodes a vector as <<dim::unsigned-16, 0::unsigned-16>> followed by the element floats, packing the element count into a 16-bit field without checking its range. A list of more than 65,535 elements wraps the dimension modulo 65,536, so the encoded header records a dimension that disagrees with the number of stored floats. from_binary/1 later reads binary-size(dim)-unit(32) from the wrapped header, so every read of the corrupted value misparses and raises, denying access to the affected record. The fix rejects any vector whose dimension exceeds 65,535.
This issue affects ash: from 2.14.13 before 3.32.2. |
| Incorrect Behavior Order: Validate Before Canonicalize vulnerability in ash-project ash lets an attacker store a case-insensitive string value that violates its length or match constraints.
Ash.Type.CiString.apply_constraints/2 (lib/ash/type/ci_string.ex) validated the max_length, min_length, and match constraints against the value as submitted, while the type case-folds the string (per its casing) for storage and comparison. Because validation ran before folding, an attacker can submit a value whose folded form breaks a constraint but whose original form passes: for example, against a match pattern requiring uppercase, an uppercase value that is stored lowercased persists a value the pattern rejects. The fix case-folds the value at the start of apply_constraints/2, so the constraints are checked against the form that is actually stored.
This issue affects ash: from 1.29.0-rc0 before 3.32.2. |
| Uncontrolled Resource Consumption vulnerability in ash-project ash allows an attacker to force an expensive regular expression to run on input that a length constraint should have already rejected.
Ash.Type.String.apply_constraints/2 (lib/ash/type/string.ex) evaluated the :match regex regardless of the min_length and max_length constraints on the same attribute. Because the length check did not gate the regex, an over-length value that the length constraint rejects still had the pattern applied to it, so the length limit that would otherwise bound the work never constrained the regex input. Against a backtracking pattern this yields catastrophic regex evaluation on attacker-sized input, and even a linear pattern runs on arbitrarily large input, consuming CPU per request. The fix skips the :match regex whenever a length constraint is violated, making the two checks order-independent.
This issue affects ash: from 0.10.0 before 3.32.2. |
| Improper Control of Generation of Code (Code Injection) vulnerability in ash-project ash_ai allows a remote, unauthenticated client to execute arbitrary Elixir code.
AshAi.Actions.Prompt evaluates prompt content through EEx.eval_string/2. The documented prompt: fn input, context -> ... end form lets the prompt content be built from action arguments, so when a prompt action's text incorporates request data, that attacker-controlled text is compiled and run as an EEx template (Elixir source). Content such as <%= System.cmd(...) %> therefore executes on the server before any model request is made, requiring no authentication beyond reaching a prompt action. The fix stops evaluating function-supplied prompt content as EEx; only statically configured templates are evaluated.
This issue affects ash_ai: from 0.1.0 before 1.0.0. |
| Cleartext Storage of Sensitive Information vulnerability in ash-project ash_paper_trail allows an attacker with read access to the generated version resource to recover the plaintext of sensitive? attributes.
AshPaperTrail stores the values of tracked sensitive? attributes in the generated version resource's changes map, which is declared public? true and sensitive? false, so the values are returned by the version resource's default read action and printed in logs, inspect output, and error messages instead of being redacted. AshPaperTrail.Resource.Transformers.CreateVersionResource derives the changes map's sensitivity from the ignore_attributes list (the attributes excluded from changes) rather than from the tracked attributes actually stored in it, and ignore_attributes defaults to empty, so the flag is effectively always false.
This issue affects ash_paper_trail: from 0.1.1 before 0.7.0. |
| Incorrect Authorization vulnerability in ash-project ash_sql allows a caller in a schema-based multitenant application to receive aggregate values computed from another tenant's rows.
When an aggregate is computed over a distinct query, AshSql.AggregateQuery.add_single_aggs/5 rebuilds the outer query from query.from.source alone, which is only the {table, schema} tuple and does not carry query.prefix or query.from.prefix. For strategy(:context) multitenancy those hold the tenant schema, so the rebuilt outer query reads the repo's default schema while the inner correlated subquery still reads the tenant schema, and the two are joined only on primary key. The aggregate, and any relationship join added off the prefix-less binding, is then computed against the wrong tenant's rows. The neighbouring limit and exists branches instead wrap the query with subquery/1, which preserves the prefix.
This issue affects ash_sql: from 0.1.0 before 0.7.1. |
| Allocation of Resources Without Limits or Throttling vulnerability in ash-project ash_admin lets any client that can reach the admin LiveView exhaust the BEAM atom table and crash the entire node.
Two LiveView event handlers interned atoms from unvalidated client input: AshAdmin.PageLive's set_actor built modules from the resource/domain payload with Module.concat/1, and AshAdmin.Components.Resource.Show's calculate converted every submitted form key with String.to_atom/1. Atoms are never garbage collected and the table is capped, so flooding either event with random names mints a new atom per request until the VM aborts, taking down every application on the node. The fix resolves the submitted resource/domain against the known shown resources and maps calculation keys to declared arguments, so no client-supplied string is interned.
This issue affects ash_admin: from 0.1.0 before 1.3.1. |
| Improper Encoding or Escaping of Output vulnerability in ash-project ash_admin lets an attacker who controls a record's string primary key rewrite the target of AshAdmin's row-action links.
The Table, DataTable, and Show components built row-action URLs by raw string interpolation, splicing the primary key (and table, domain, and resource names) into the query string without URL-encoding. Ash resources routinely use user-settable string primary keys (slugs, emails). Because Plug.Conn.Query resolves duplicate parameters last-wins and primary_key is interpolated last, a stored key such as foo&action_type=destroy injects parameters that override the link, so an admin clicking edit is sent to a destroy form or an arbitrary resource; a # truncates the query into a fragment. The fix builds every link with URI.encode_query/1, encoding all interpolated values.
This issue affects ash_admin: from 0.3.0-rc.0 before 1.3.1. |
| Generation of Error Message Containing Sensitive Information vulnerability in ash-project ash_ai discloses internal error text to chat users.
In AshAi.ToolLoop and AshAi.Tools, an exception raised while executing a tool was serialized verbatim with Exception.message/1 into the tool-result content. That content is appended to the conversation, emitted as a {:tool_result, ...} stream event, and sent back to the model, which typically relays it to the user. No filtering happened first, so anything raised inside a tool callback or lifecycle hook (database constraint messages, adapter errors, query fragments, policy or validation internals) was echoed as-is. A chat user who can steer tool arguments into a raising code path receives the raw internal text. The fix routes raised tool errors through the same safe formatter used for other tool errors.
This issue affects ash_ai: from 0.6.0 before 1.0.0. |
| Loop with Unreachable Exit Condition (Infinite Loop) vulnerability in ash-project ash_ai allows an attacker who can influence a model's output to hang the tool loop and drive unbounded, repeated model requests.
AshAi.ToolLoop classifies a model response of :tool_calls, then filters the calls through normalize_tool_calls/2 and unprocessed_tool_calls/2. Both can empty the list: a call missing a valid name, or one reusing a tool_call_id that already has a result in history, is dropped. With an empty list the loop appended nothing and recursed with a byte-identical message list, so the conversation never advanced and the same request was re-sent every iteration. Under the supported max_iterations: :infinity this never terminated; otherwise it exhausted the full budget. Prompt-injected content can make the model re-emit a spent tool_call_id. The fix treats an empty post-filter list as terminal.
This issue affects ash_ai: from 0.6.0 before 1.0.0. |