CVE-2025-48042
Description
Incorrect Authorization vulnerability in ash-project ash allows Exploiting Incorrectly Configured Access Control Security Levels. This vulnerability is associated with program files lib/ash/actions/create/bulk.ex, lib/ash/actions/destroy/bulk.ex, lib/ash/actions/update/bulk.ex and program routines 'Elixir.Ash.Actions.Create.Bulk':run/5, 'Elixir.Ash.Actions.Destroy.Bulk':run/6, 'Elixir.Ash.Actions.Update.Bulk:run'/6.
This issue affects ash: from pkg:hex/ash before pkg:hex/ash@3.5.39, before 3.5.39, before 5d1b6a5d00771fd468a509778637527b5218be9a.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
ashHex | < 3.5.39 | 3.5.39 |
Affected products
1- Range: 3.0.3, 3.4.56, v0.1.1, …
Patches
25d1b6a5d0077fix: authorize before before_transaction hooks in bulk actions
4 files changed · +106 −10
lib/ash/actions/create/bulk.ex+3 −3 modified@@ -501,6 +501,7 @@ defmodule Ash.Actions.Create.Bulk do changeset.action.require_attributes ) end) + |> authorize(opts) |> Ash.Actions.Helpers.split_and_run_simple( action, opts, @@ -645,9 +646,8 @@ defmodule Ash.Actions.Create.Bulk do end) batch = - batch - |> authorize(opts) - |> Ash.Actions.Update.Bulk.run_bulk_before_batches( + Ash.Actions.Update.Bulk.run_bulk_before_batches( + batch, changes, all_changes, opts,
lib/ash/actions/destroy/bulk.ex+4 −4 modified@@ -1433,6 +1433,8 @@ defmodule Ash.Actions.Destroy.Bulk do :bulk_destroy ) + batch = authorize(batch, opts) + batch = if re_sort? do Enum.sort_by(batch, & &1.context.bulk_destroy.index) @@ -1611,10 +1613,8 @@ defmodule Ash.Actions.Destroy.Bulk do end) batch = - batch - |> authorize(opts) - |> Enum.to_list() - |> Ash.Actions.Update.Bulk.run_bulk_before_batches( + Ash.Actions.Update.Bulk.run_bulk_before_batches( + batch, changes, all_changes, opts,
lib/ash/actions/update/bulk.ex+4 −3 modified@@ -1751,6 +1751,8 @@ defmodule Ash.Actions.Update.Bulk do context_key ) + batch = authorize(batch, opts) + batch = if re_sort? do Enum.sort_by(batch, & &1.context[context_key].index) @@ -1920,9 +1922,8 @@ defmodule Ash.Actions.Update.Bulk do end) batch = - batch - |> authorize(opts) - |> run_bulk_before_batches( + run_bulk_before_batches( + batch, changes, all_changes, opts,
test/policy/simple_test.exs+95 −0 modified@@ -654,4 +654,99 @@ defmodule Ash.Test.Policy.SimpleTest do assert user2_got_thing.id == user2_thing.id end + + defmodule ResourceWithBeforeTransactionHook do + use Ash.Resource, + domain: Ash.Test.Domain, + authorizers: [Ash.Policy.Authorizer] + + attributes do + uuid_primary_key :id + attribute :name, :string, public?: true + end + + actions do + defaults [:read] + + create :create do + primary? true + accept [:name] + end + + update :test_action_with_after_transaction do + accept [:name] + + change before_transaction(fn changeset, _context -> + raise "running before transaction" + end) + + change after_transaction(fn _changeset, res, _context -> + res + end) + + require_atomic? false + end + + update :test_action_without_after_transaction do + accept [:name] + + change before_transaction(fn changeset, _context -> + raise "running before transaction" + end) + + require_atomic? false + end + end + + policies do + policy action_type(:read) do + authorize_if always() + end + + policy action_type(:create) do + authorize_if always() + end + end + end + + test "before_transaction hook should not run when action is not authorized via bulk_update" do + record = Ash.create!(ResourceWithBeforeTransactionHook, %{name: "test"}, authorize?: false) + + query = + ResourceWithBeforeTransactionHook + |> Ash.DataLayer.Simple.set_data([record]) + |> Ash.Query.limit(1) + + assert_raise Ash.Error.Forbidden, fn -> + Ash.bulk_update!(query, :test_action_with_after_transaction, %{}, + return_errors?: true, + notify?: true, + strategy: [:atomic, :stream, :atomic_batches], + allow_stream_with: :full_read, + authorize_changeset_with: :filter, + return_records?: true, + authorize?: true, + read_action: :read, + domain: Ash.Test.Domain, + select: [], + load: [] + ) + end + + assert_raise Ash.Error.Forbidden, fn -> + Ash.bulk_update!(query, :test_action_without_after_transaction, %{}, + return_errors?: true, + notify?: true, + strategy: [:atomic, :stream, :atomic_batches], + allow_stream_with: :full_read, + authorize_changeset_with: :filter, + return_records?: true, + authorize?: true, + read_action: :read, + domain: Ash.Test.Domain, + select: [], + load: [] + ) + end + end end
c035b53b309dVulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
6- github.com/advisories/GHSA-jj4j-x5ww-cwh9ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2025-48042ghsaADVISORY
- cna.erlef.org/cves/CVE-2025-48042.htmlnvdWEB
- github.com/ash-project/ash/commit/5d1b6a5d00771fd468a509778637527b5218be9anvdWEB
- github.com/ash-project/ash/security/advisories/GHSA-jj4j-x5ww-cwh9nvdWEB
- osv.dev/vulnerability/EEF-CVE-2025-48042nvdWEB
News mentions
0No linked articles in our index yet.