CVE-2026-57579
Alchemy: Unauthenticated nested page API leaks restricted & unpublished content
Alchemy is an open source content management system engine written in Ruby on Rails. Prior to 7.4.15, 8.0.15, 8.1.14, and 8.2.6, the unauthenticated GET /api/pages/nested endpoint implemented by Api::PagesController#nested in app/controllers/alchemy/api/pages_controller.rb returns an unfiltered page tree because it performs no authorization and does not scope descendants by the caller's ability. Anonymous callers can retrieve restricted and unpublished page metadata that the sibling show action denies. When elements=true is supplied, PageTreeSerializer also returns element and ingredient content from restricted pages because PageTreePreloader and the serializer do not apply an ability check to those records. This issue is fixed in versions 7.4.15, 8.0.15, 8.1.14, and 8.2.6.
Attack profile
How easy it is to exploit
- Attack vector
- Network
- Complexity
- Low
- Privileges needed
- None
- User interaction
- None
What an attacker can affect
- Confidentiality
- High
- Integrity
- None
- Availability
- None
Exploit likelihood
What each source reports
CVE List Score used
7.5
Alchemy: Unauthenticated nested page API leaks restricted & unpublished content
Alchemy is an open source content management system engine written in Ruby on Rails. Prior to 7.4.15, 8.0.15, 8.1.14, and 8.2.6, the unauthenticated GET /api/pages/nested endpoint implemented by Api::PagesController#nested in app/controllers/alchemy/api/pages_controller.rb returns an unfiltered page tree because it performs no authorization and does not scope descendants by the caller's ability. Anonymous callers can retrieve restricted and unpublished page metadata that the sibling show action denies. When elements=true is supplied, PageTreeSerializer also returns element and ingredient content from restricted pages because PageTreePreloader and the serializer do not apply an ability check to those records. This issue is fixed in versions 7.4.15, 8.0.15, 8.1.14, and 8.2.6.
- Record
CVE-2026-57579- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N - Weakness
- CWE-862
- Updated
- 2026-11-02
EUVDEUVD-2026-77637
7.5
Alchemy is an open source content management system engine written in Ruby on Rails. Prior to 7.4.15, 8.0.15, 8.1.14, and 8.2.6, the unauthenticated GET /api/pages/nested endpoint implemented by Api::PagesController#nested in app/controllers/alchemy/api/pages_controller.rb returns an unfiltered page tree because it performs no authorization and does not scope descendants by the caller's ability. Anonymous callers can retrieve restricted and unpublished page metadata that the sibling show action denies. When elements=true is supplied, PageTreeSerializer also returns element and ingredient content from restricted pages because PageTreePreloader and the serializer do not apply an ability check to those records. This issue is fixed in versions 7.4.15, 8.0.15, 8.1.14, and 8.2.6.
- Record
EUVD-2026-77637- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N - Updated
- 2026-11-02
GitHub AdvisoriesGHSA-mqq5-j7w8-2hgh
7.5
AlchemyCMS: Unauthenticated nested page API leaks restricted & unpublished content
Unauthenticated nested page API leaks restricted & unpublished content
- Location:
app/controllers/alchemy/api/pages_controller.rb:28(Api::PagesController#nested) - Affected version: Alchemy CMS 8.3.0.dev (Rails 8.1.3)
Description
The unauthenticated GET /api/pages/nested endpoint returns the full page tree to any anonymous caller, including restricted (member-only) pages and unpublished/draft pages that should be hidden.
Appending ?elements=true additionally dumps the element/ingredient content of restricted pages, fully bypassing the access control the sibling show and index actions enforce.
Root cause
Api::PagesController#nested calls no authorize! and applies no published/restricted scoping, unlike show (authorize! :show) and index (accessible_by(current_ability, :index)).
PageTreePreloader loads page.self_and_descendants unfiltered, and PageTreeSerializer emits every page's metadata (and, with elements, public_version.elements) with no ability check.
Evidence
An unauthenticated GET /api/pages/nested returns HTTP 200 with the restricted page ("restricted":true) and an unpublished draft ("public":false); ?elements=true leaks its content (e.g. TOPSECRET_RESTRICTED_BODY_proof123).
The same guest hitting GET /api/pages/3 (show) gets HTTP 403 {"error":"Not authorized"}, proving nested returns what show correctly denies.
Reproduction
# 1) Metadata leak (guest, no auth)
curl -s http://localhost:3000/api/pages/nested | python3 -m json.tool | grep -E '"name"|"restricted"|"public"'
# 2) Content leak of restricted page
curl -s "http://localhost:3000/api/pages/nested?elements=true" | grep -oE 'TOPSECRET_RESTRICTED_BODY_[A-Za-z0-9]+|RESTRICTED_RICHTEXT_[A-Za-z0-9]+'
# 3) Contrast — show denies the same guest
curl -s -o /dev/null -w "show /api/pages/3 -> HTTP %{http_code}\n" http://localhost:3000/api/pages/3
Suggested fix
def nested
@page = Page.find_by(id: params[:page_id]) || Language.current_root_page
authorize! :show, @page
preloaded_page = PageTreePreloader.new(page: @page, user: current_alchemy_user, ability: current_ability).call
render json: PageTreeSerializer.new(preloaded_page, ability: current_ability,
user: current_alchemy_user, elements: params[:elements])
end
Additionally scope PageTreePreloader's self_and_descendants via accessible_by(current_ability) and gate element emission in PageTreeSerializer#page_elements behind opts[:ability].can?(:show, page).
- Record
GHSA-mqq5-j7w8-2hgh- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N - Weakness
- CWE-862
- Updated
- 2026-11-02
NVD
7.5
Alchemy is an open source content management system engine written in Ruby on Rails. Prior to 7.4.15, 8.0.15, 8.1.14, and 8.2.6, the unauthenticated GET /api/pages/nested endpoint implemented by Api::PagesController#nested in app/controllers/alchemy/api/pages_controller.rb returns an unfiltered page tree because it performs no authorization and does not scope descendants by the caller's ability. Anonymous callers can retrieve restricted and unpublished page metadata that the sibling show action denies. When elements=true is supplied, PageTreeSerializer also returns element and ingredient content from restricted pages because PageTreePreloader and the serializer do not apply an ability check to those records. This issue is fixed in versions 7.4.15, 8.0.15, 8.1.14, and 8.2.6.
- Record
CVE-2026-57579- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N - Weakness
- CWE-862
- Updated
- 2026-11-02
OSV
7.5
Alchemy: Unauthenticated nested page API leaks restricted & unpublished content
Alchemy is an open source content management system engine written in Ruby on Rails. Prior to 7.4.15, 8.0.15, 8.1.14, and 8.2.6, the unauthenticated GET /api/pages/nested endpoint implemented by Api::PagesController#nested in app/controllers/alchemy/api/pages_controller.rb returns an unfiltered page tree because it performs no authorization and does not scope descendants by the caller's ability. Anonymous callers can retrieve restricted and unpublished page metadata that the sibling show action denies. When elements=true is supplied, PageTreeSerializer also returns element and ingredient content from restricted pages because PageTreePreloader and the serializer do not apply an ability check to those records. This issue is fixed in versions 7.4.15, 8.0.15, 8.1.14, and 8.2.6.
- Record
CVE-2026-57579- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N - Weakness
- CWE-862
- Updated
- 2026-11-02
OSVGHSA-mqq5-j7w8-2hgh
7.5
AlchemyCMS: Unauthenticated nested page API leaks restricted & unpublished content
Unauthenticated nested page API leaks restricted & unpublished content
- Location:
app/controllers/alchemy/api/pages_controller.rb:28(Api::PagesController#nested) - Affected version: Alchemy CMS 8.3.0.dev (Rails 8.1.3)
Description
The unauthenticated GET /api/pages/nested endpoint returns the full page tree to any anonymous caller, including restricted (member-only) pages and unpublished/draft pages that should be hidden.
Appending ?elements=true additionally dumps the element/ingredient content of restricted pages, fully bypassing the access control the sibling show and index actions enforce.
Root cause
Api::PagesController#nested calls no authorize! and applies no published/restricted scoping, unlike show (authorize! :show) and index (accessible_by(current_ability, :index)).
PageTreePreloader loads page.self_and_descendants unfiltered, and PageTreeSerializer emits every page's metadata (and, with elements, public_version.elements) with no ability check.
Evidence
An unauthenticated GET /api/pages/nested returns HTTP 200 with the restricted page ("restricted":true) and an unpublished draft ("public":false); ?elements=true leaks its content (e.g. TOPSECRET_RESTRICTED_BODY_proof123).
The same guest hitting GET /api/pages/3 (show) gets HTTP 403 {"error":"Not authorized"}, proving nested returns what show correctly denies.
Reproduction
# 1) Metadata leak (guest, no auth)
curl -s http://localhost:3000/api/pages/nested | python3 -m json.tool | grep -E '"name"|"restricted"|"public"'
# 2) Content leak of restricted page
curl -s "http://localhost:3000/api/pages/nested?elements=true" | grep -oE 'TOPSECRET_RESTRICTED_BODY_[A-Za-z0-9]+|RESTRICTED_RICHTEXT_[A-Za-z0-9]+'
# 3) Contrast — show denies the same guest
curl -s -o /dev/null -w "show /api/pages/3 -> HTTP %{http_code}\n" http://localhost:3000/api/pages/3
Suggested fix
def nested
@page = Page.find_by(id: params[:page_id]) || Language.current_root_page
authorize! :show, @page
preloaded_page = PageTreePreloader.new(page: @page, user: current_alchemy_user, ability: current_ability).call
render json: PageTreeSerializer.new(preloaded_page, ability: current_ability,
user: current_alchemy_user, elements: params[:elements])
end
Additionally scope PageTreePreloader's self_and_descendants via accessible_by(current_ability) and gate element emission in PageTreeSerializer#page_elements behind opts[:ability].can?(:show, page).
- Record
GHSA-mqq5-j7w8-2hgh- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N - Weakness
- CWE-862
- Updated
- 2026-11-02
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
alchemy_cmsRubyGems |
8.2.0 to 8.2.5 | 8.2.6 |
alchemy_cmsRubyGems |
8.1.0 to 8.1.13 | 8.1.14 |
alchemy_cmsRubyGems |
8.0.0.a to 8.0.14 | 8.0.15 |
alchemy_cmsRubyGems |
through 7.4.14 | 7.4.15 |
alchemy_cmsRubyGems |
8.2.0 up to 8.2.6, plus listed versions 8.2.18.2.28.2.38.2.48.2.5 |
8.2.6 |
alchemy_cmsRubyGems |
8.1.0 up to 8.1.14, plus listed versions 8.1.18.1.108.1.118.1.128.1.13 Show 8 moreShow less8.1.28.1.38.1.48.1.58.1.68.1.78.1.88.1.9 |
8.1.14 |
alchemy_cmsRubyGems |
8.0.0.a up to 8.0.15, plus listed versions 8.0.08.0.0.b8.0.0.c8.0.18.0.10 Show 12 moreShow less8.0.118.0.128.0.138.0.148.0.28.0.38.0.48.0.58.0.68.0.78.0.88.0.9 |
8.0.15 |
alchemy_cmsRubyGems |
before 7.4.15, plus listed versions 2.02.0.12.0.22.0.32.0.3.1 Show 45 moreShow less2.0.42.0.52.0.6.12.0.72.0.pre22.0.pre32.0.pre42.0.pre52.0.rc12.0.rc22.0.rc32.0.rc42.0.rc52.0.rc62.12.1.12.1.112.1.122.1.22.1.32.1.42.1.52.1.62.1.72.1.82.1.8.12.1.92.1.9.12.1.beta12.1.beta52.1.beta62.1.rc22.1.rc32.1.rc42.1.rc52.1.rc62.2.02.2.12.2.22.2.3.12.2.3.22.2.42.2.rc12.2.rc112.2.rc13 |
7.4.15 |
History
| Recorded | Changed | Sources |
|---|---|---|
| first indexed | CVE List, EUVD, GitHub Advisories, NVD, OSV |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2026-57579 is a high vulnerability (CVSS 7.5) in Alchemycms Alchemy Cms, published June 19, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.65%, the 51st percentile. Fixed in alchemy_cms 8.2.6.
References
github.com/AlchemyCMS/alchemy_cms/security/advisories/GHSA-mqq5-j7w8-2hgh
github.com/AlchemyCMS/alchemy_cms/pull/3982
github.com/AlchemyCMS/alchemy_cms/commit/30888fb41d8b71fdfb3b116a7efccd851d73e1f3
github.com/AlchemyCMS/alchemy_cms/commit/5620e76f0d274d6f69f34281b7e46d01879f6b99
github.com/AlchemyCMS/alchemy_cms/commit/8417a2e9dcb00653c8b238f8a040b09532dd4c0f
github.com/AlchemyCMS/alchemy_cms/commit/85702d9fe4e247649b1358900c5af853e83b4a3a
Show 9 moreShow less
github.com/AlchemyCMS/alchemy_cms/commit/a082dd0afe188d199f386a5e1db01987d0de807f
github.com/AlchemyCMS/alchemy_cms/releases/tag/v7.4.15
github.com/AlchemyCMS/alchemy_cms/releases/tag/v8.0.15
github.com/AlchemyCMS/alchemy_cms/releases/tag/v8.1.14
github.com/AlchemyCMS/alchemy_cms/releases/tag/v8.2.6
github.com/advisories/GHSA-mqq5-j7w8-2hgh
github.com/CVEProject/cvelistV5/tree/main/cves/2026/57xxx/CVE-2026-57579.json
nvd.nist.gov/vuln/detail/CVE-2026-57579
github.com/AlchemyCMS/alchemy_cms
Left out here: 293 versions. The JSON record has them.