{"schema":"threatline.record/2","record":{"id":"CVE-2026-55736","aliases":["EEF-CVE-2026-55736","GHSA-f4hc-ppw9-4hhw"],"summary":"Ash: Private action arguments can be set by user input via string-keyed params and atomic changesets","details":"### Summary\n\nAsh fails to consistently strip private action arguments (those declared with `public?: false`) when a changeset is built from an untrusted parameter map. Private arguments are meant to be set only by trusted server-side code, but a caller who controls the parameters supplied to an action can inject a value for one. Any actor able to submit parameters to an action that defines a private argument can trigger it.\n\n### Details\n\nPrivate arguments (`public?: false`) are meant to be populated internally (e.g. via `Ash.Changeset.set_private_argument/3`) and never accepted from external input. When an action is invoked with a parameter map, Ash should discard keys that name a private argument. The filtering in `lib/ash/changeset/changeset.ex` is incomplete, and the gap differs across the two parameter paths.\n\n**1. Regular path (`for_create`, `for_update`, `for_destroy`).** `cast_params/4` validates keys via `get_action_argument/2`. Its atom-keyed clause filters on `public?`, but the binary-keyed (string) clause does not, so a string key matching a private argument name is accepted and written into `changeset.arguments`. User-supplied parameter maps are string-keyed, making this the reachable case.\n\n**2. Atomic / bulk path (`Ash.Changeset.fully_atomic_changeset/4`).** `atomic_params/4` gates assignment on `has_argument?/2`, whose atom and binary clauses both omit the `public?` check, so private arguments are accepted regardless of key type.\n\n### PoC\n\n1. Define an action with a private argument, e.g. `argument :acting_user_id, :string, public?: false`, and a change that writes it into an attribute.\n2. Build the changeset from a string-keyed map including it, e.g. `Ash.Changeset.for_create(Resource, :place, %{\"item\" => \"book\", \"acting_user_id\" => \"victim-user-id\"})`.\n3. Observe `acting_user_id` is present in `changeset.arguments` and persisted, whereas the same map with atom keys is correctly stripped.\n4. For the atomic path, call `Ash.Changeset.fully_atomic_changeset(Resource, :promote, %{\"acting_user_id\" => \"victim-user-id\"})` (atom or string keys) and observe the private argument is retained either way.\n\n### Impact\n\nAn attacker who can submit parameters to an action that defines a private argument can set that argument to a value of their choosing, overriding data the application intended to control server-side. Where a private argument drives authorization, identity, or record ownership (e.g. `acting_user_id`), this can lead to an integrity violation or privilege escalation.","categories":["Libraries & packages"],"product":"ash","vendor":"ash-project","ecosystem":"erlang","affected_ranges":[{"source":"GitHub Advisory Database","source_url":"https://github.com/advisories/GHSA-f4hc-ppw9-4hhw","source_modified_at":"2026-09-24T19:53:38Z","fetched_at":"2026-10-23T18:42:43.628194Z","package":{"ecosystem":"erlang","name":"ash"},"range":">= 3.0.0, < 3.29.3"},{"source":"CVE List","source_url":"https://www.cve.org/CVERecord?id=CVE-2026-55736","source_modified_at":"2026-07-10T04:34:23.070Z","fetched_at":"2026-10-23T18:45:31.882637Z","product":"ash","vendor":"ash-project","versions":[{"lessThan":"3.29.3","status":"affected","version":"3.0.0","versionType":"semver"}],"defaultStatus":"unaffected"},{"source":"CVE List","source_url":"https://www.cve.org/CVERecord?id=CVE-2026-55736","source_modified_at":"2026-07-10T04:34:23.070Z","fetched_at":"2026-10-23T18:45:31.882637Z","product":"ash","vendor":"ash-project","versions":[{"lessThan":"d9b3100219b3ea86d73202bf7368c03a7688efea","status":"affected","version":"5967ed3a483ab949866e6d7b043b043e61703f17","versionType":"git"}],"defaultStatus":"unaffected"},{"source":"OSV","source_url":"https://osv.dev/vulnerability/GHSA-f4hc-ppw9-4hhw","source_modified_at":"2026-09-24T20:00:05.362554723Z","fetched_at":"2026-10-23T18:42:43.628194Z","package":{"ecosystem":"Hex","name":"ash","purl":"pkg:hex/ash"},"ranges":[{"events":[{"introduced":"3.0.0"},{"fixed":"3.29.3"}],"type":"SEMVER"}],"versions":["3.0.0","3.0.1","3.0.10","3.0.11","3.0.12","3.0.13","3.0.14","3.0.15","3.0.16","3.0.2","3.0.3","3.0.4","3.0.5","3.0.6","3.0.7","3.0.8","3.0.9","3.1.0","3.1.1","3.1.2","3.1.3","3.1.4","3.1.5","3.1.6","3.1.7","3.1.8","3.10.0","3.10.1","3.11.0","3.11.1","3.11.2","3.11.3","3.12.0","3.13.0","3.13.1","3.13.2","3.14.0","3.14.1","3.15.0","3.16.0","3.17.0","3.17.1","3.18.0","3.19.0","3.19.1","3.19.2","3.19.3","3.2.0","3.2.1","3.2.2"]}],"fixed_versions":[{"source":"GitHub Advisory Database","source_url":"https://github.com/advisories/GHSA-f4hc-ppw9-4hhw","source_modified_at":"2026-09-24T19:53:38Z","fetched_at":"2026-10-23T18:42:43.628194Z","package":{"ecosystem":"erlang","name":"ash"},"version":"3.29.3"},{"source":"CVE List","source_url":"https://www.cve.org/CVERecord?id=CVE-2026-55736","source_modified_at":"2026-07-10T04:34:23.070Z","fetched_at":"2026-10-23T18:45:31.882637Z","package":{"name":"ash","ecosystem":null},"version":"3.29.3","basis":"first unaffected version stated in the CVE record"},{"source":"OSV","source_url":"https://osv.dev/vulnerability/GHSA-f4hc-ppw9-4hhw","source_modified_at":"2026-09-24T20:00:05.362554723Z","fetched_at":"2026-10-23T18:42:43.628194Z","package":{"ecosystem":"Hex","name":"ash","purl":"pkg:hex/ash"},"version":"3.29.3"}],"cvss":5.9,"severity":"Medium","kev":{"listed":false},"epss":{"probability":0.00367,"percentile":0.29358,"score_date":"2026-10-23"},"published_at":"2026-06-23T18:21:13.033Z","modified_at":"2026-09-24T20:00:05.362554723Z","provenance":[{"source":"GitHub Advisory Database","url":"https://github.com/advisories/GHSA-f4hc-ppw9-4hhw","fetched_at":"2026-10-23T18:42:43.628194Z","source_modified_at":"2026-09-24T19:53:38Z"},{"source":"CVE List","url":"https://www.cve.org/CVERecord?id=CVE-2026-55736","fetched_at":"2026-10-23T18:45:31.882637Z","source_modified_at":"2026-07-10T04:34:23.070Z"},{"source":"OSV","url":"https://osv.dev/vulnerability/GHSA-f4hc-ppw9-4hhw","fetched_at":"2026-10-23T18:42:43.628194Z","source_modified_at":"2026-09-24T20:00:05.362554723Z"},{"source":"EPSS","url":"https://api.first.org/data/v1/epss?cve=CVE-2026-55736","fetched_at":"2026-10-23T18:42:43.628194Z","source_modified_at":"2026-10-23"}],"sources":["GitHub Advisory Database","CVE List","OSV","EPSS"],"references":[{"source":"CVE List","url":"https://github.com/ash-project/ash/security/advisories/GHSA-f4hc-ppw9-4hhw","tags":["exploit"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-55736","source":"GitHub Advisory Database"},{"source":"CVE List","url":"https://github.com/ash-project/ash/commit/d9b3100219b3ea86d73202bf7368c03a7688efea","tags":["patch"]},{"source":"CVE List","url":"https://cna.erlef.org/cves/CVE-2026-55736.html","tags":["related"]},{"url":"https://github.com/ash-project/ash/releases/tag/v3.29.3","source":"GitHub Advisory Database"},{"source":"CVE List","url":"https://osv.dev/vulnerability/EEF-CVE-2026-55736","tags":["related"]},{"url":"https://github.com/advisories/GHSA-f4hc-ppw9-4hhw","source":"GitHub Advisory Database"}],"locations":[],"motoko_assessment":{"status":"requires_architecture_review","automatic_remediation":false},"cve_state":"PUBLISHED","ssvc":{"exploitation":"poc","automatable":"no","technical_impact":"partial","assessed_at":"2026-07-09T14:53:04.134939Z"},"classification":{"method":"product-first software-layer rules","rules_version":"2.1","matched_on":"ecosystem","confidence":"heuristic","reviewed":false},"change_timestamp":"2026-09-24T20:00:05.362554723Z","content_hash":"7d6b2930ae32327b132de26a9d5b686daee1bad0ef4d035a3b1eb21aa7aec8e9"}}
