GHSA-mqq5-j7w8-2hgh

Suggest an improvement
Source
https://github.com/advisories/GHSA-mqq5-j7w8-2hgh
Import Source
https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/06/GHSA-mqq5-j7w8-2hgh/GHSA-mqq5-j7w8-2hgh.json
JSON Data
https://api.osv.dev/v1/vulns/GHSA-mqq5-j7w8-2hgh
Aliases
Published
2026-06-19T17:47:13Z
Modified
2026-09-15T03:56:01Z
Severity
  • 7.5 (High) CVSS_V3 - CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N CVSS Calculator
Summary
AlchemyCMS: Unauthenticated nested page API leaks restricted & unpublished content
Details

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).

Database specific
{
    "cwe_ids":  [
        "CWE-862"
    ],
    "github_reviewed":  true,
    "github_reviewed_at":  "2026-06-19T17:47:13Z",
    "nvd_published_at":  null,
    "severity":  "HIGH"
}
References

Affected packages

RubyGems / alchemy_cms

Package

Name
alchemy_cms
Purl
pkg:gem/alchemy_cms

Affected ranges

Type
ECOSYSTEM
Events
Introduced
8.2.0
Fixed
8.2.6

Affected versions

8.*
8.2.0
8.2.1
8.2.2
8.2.3
8.2.4
8.2.5

Database specific

last_known_affected_version_range
"<= 8.2.5"
source
"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/06/GHSA-mqq5-j7w8-2hgh/GHSA-mqq5-j7w8-2hgh.json"

RubyGems / alchemy_cms

Package

Name
alchemy_cms
Purl
pkg:gem/alchemy_cms

Affected ranges

Type
ECOSYSTEM
Events
Introduced
8.1.0
Fixed
8.1.14

Affected versions

8.*
8.1.0
8.1.1
8.1.2
8.1.3
8.1.4
8.1.5
8.1.6
8.1.7
8.1.8
8.1.9
8.1.10
8.1.11
8.1.12
8.1.13

Database specific

last_known_affected_version_range
"<= 8.1.13"
source
"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/06/GHSA-mqq5-j7w8-2hgh/GHSA-mqq5-j7w8-2hgh.json"

RubyGems / alchemy_cms

Package

Name
alchemy_cms
Purl
pkg:gem/alchemy_cms

Affected ranges

Type
ECOSYSTEM
Events
Introduced
8.0.0.a
Fixed
8.0.15

Affected versions

8.*
8.0.0.a
8.0.0.b
8.0.0.c
8.0.0
8.0.1
8.0.2
8.0.3
8.0.4
8.0.5
8.0.6
8.0.7
8.0.8
8.0.9
8.0.10
8.0.11
8.0.12
8.0.13
8.0.14

Database specific

last_known_affected_version_range
"<= 8.0.14"
source
"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/06/GHSA-mqq5-j7w8-2hgh/GHSA-mqq5-j7w8-2hgh.json"

RubyGems / alchemy_cms

Package

Name
alchemy_cms
Purl
pkg:gem/alchemy_cms

Affected ranges

Type
ECOSYSTEM
Events
Introduced
0 Unknown introduced version / All previous versions are affected
Fixed
7.4.15

Affected versions

2.*
2.0.pre2
2.0.pre3
2.0.pre4
2.0.pre5
2.0.rc1
2.0.rc2
2.0.rc3
2.0.rc4
2.0.rc5
2.0.rc6
2.0
2.0.1
2.0.2
2.0.3
2.0.3.1
2.0.4
2.0.5
2.0.6.1
2.0.7
2.1.beta1
2.1.beta5
2.1.beta6
2.1.rc2
2.1.rc3
2.1.rc4
2.1.rc5
2.1.rc6
2.1
2.1.1
2.1.2
2.1.3
2.1.4
2.1.5
2.1.6
2.1.7
2.1.8
2.1.8.1
2.1.9
2.1.9.1
2.1.11
2.1.12
2.2.rc1
2.2.rc2
2.2.rc3
2.2.rc6
2.2.rc7
2.2.rc8
2.2.rc11
2.2.rc13
2.2.rc14
2.2.rc15
2.2.0
2.2.1
2.2.2
2.2.3.1
2.2.3.2
2.2.4
2.3.rc5
2.3.0
2.3.1
2.3.2
2.4.beta2
2.4.rc1
2.4.rc2
2.4.rc4
2.4.0
2.4.1
2.5.0.b2
2.5.0.b5
2.5.0.b9
2.5.0.rc3
2.5.0
2.5.1
2.5.2
2.5.2.1
2.5.2.2
2.5.3
2.5.3.1
2.6.0.rc5
2.6.0
2.6.1
2.6.2
2.6.2.1
2.6.3
2.7.0
2.7.1
2.7.2
2.7.3
2.7.4
2.7.5
2.8.1
2.8.2
2.8.3
2.9.0
2.9.1
3.*
3.0.0.rc5
3.0.0.rc6
3.0.0.rc7
3.0.0.rc8
3.0.0
3.0.1
3.0.2
3.0.3
3.0.4
3.1.0.beta1
3.1.0.beta2
3.1.0.beta3
3.1.0.beta4
3.1.0.beta5
3.1.0.beta6
3.1.0.rc1
3.1.0.rc2
3.1.0.rc3
3.1.0
3.1.1
3.1.3
3.2.0.beta
3.2.0.rc1
3.2.0
3.2.1
3.3.0.rc1
3.3.0.rc2
3.3.0
3.3.1
3.3.2
3.3.3
3.4.0.rc1
3.4.0
3.4.1
3.4.2
3.5.0.rc1
3.5.0.rc2
3.5.0
3.6.0
3.6.1
3.6.2
3.6.3
3.6.4
3.6.5
3.6.6
3.6.7
4.*
4.0.0.beta
4.0.0.rc1
4.0.0.rc2
4.0.0
4.0.1
4.0.2
4.0.3
4.0.4
4.0.5
4.0.6
4.1.0.beta
4.1.0.rc1
4.1.0
4.1.1
4.1.2
4.2.0.rc1
4.2.0
4.2.1
4.2.2
4.2.3
4.2.4
4.3.0
4.3.1
4.3.2
4.4.0
4.4.1
4.4.2
4.4.3
4.4.4
4.4.5
4.5.0
4.5.1
4.6.0
4.6.1
4.6.2
4.6.3
4.6.4
4.6.5
4.6.6
4.6.7
5.*
5.0.0.beta1
5.0.0.beta2
5.0.0.rc1
5.0.0.rc2
5.0.0
5.0.1
5.0.2
5.0.3
5.0.4
5.0.5
5.0.6
5.0.7
5.0.8
5.0.9
5.0.10
5.1.0.beta1
5.1.0.beta2
5.1.0.rc1
5.1.0
5.1.1
5.1.2
5.1.3
5.1.4
5.1.5
5.1.6
5.1.7
5.1.8
5.1.9
5.1.10
5.2.0.b1
5.2.0.rc1
5.2.0
5.2.1
5.2.2
5.2.3
5.2.4
5.2.5
5.2.6
5.2.7
5.3.0
5.3.1
5.3.2
5.3.3
5.3.4
5.3.5
5.3.6
5.3.7
5.3.8
6.*
6.0.0.b1
6.0.0.b2
6.0.0.b3
6.0.0.pre.b4
6.0.0.pre.b5
6.0.0.pre.b6
6.0.0.pre.rc1
6.0.0.pre.rc2
6.0.0.pre.rc3
6.0.0.pre.rc4
6.0.0.pre.rc5
6.0.0.pre.rc6
6.0.0.pre.rc7
6.0.0
6.0.1
6.0.2
6.0.3
6.0.4
6.0.5
6.0.6
6.0.7
6.0.8
6.0.9
6.0.10
6.0.11
6.0.12
6.0.13
6.0.14
6.1.0
6.1.1
6.1.2
6.1.3
6.1.4
6.1.5
6.1.6
6.1.7
6.1.8
6.1.9
6.1.10
7.*
7.0.0.pre.a
7.0.0.pre.b
7.0.0.pre.c
7.0.0.pre.rc1
7.0.0
7.0.1
7.0.2
7.0.3
7.0.4
7.0.5
7.0.6
7.0.7
7.0.8
7.0.9
7.0.10
7.0.11
7.0.12
7.0.13
7.0.14
7.0.15
7.0.16
7.1.0.pre.b1
7.1.0.pre.b2
7.1.0.pre.rc1
7.1.0
7.1.1
7.1.2
7.1.3
7.1.4
7.1.5
7.1.6
7.1.7
7.1.8
7.1.9
7.1.10
7.1.11
7.1.12
7.1.13
7.2.0.b
7.2.0.rc1
7.2.0.rc2
7.2.0
7.2.1
7.2.2
7.2.3
7.2.4
7.2.5
7.2.6
7.2.7
7.2.8
7.2.9
7.3.0
7.3.1
7.3.2
7.3.3
7.3.4
7.3.5
7.3.6
7.3.7
7.3.8
7.4.0
7.4.1
7.4.2
7.4.3
7.4.4
7.4.5
7.4.6
7.4.7
7.4.8
7.4.9
7.4.10
7.4.11
7.4.12
7.4.13
7.4.14

Database specific

last_known_affected_version_range
"<= 7.4.14"
source
"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/06/GHSA-mqq5-j7w8-2hgh/GHSA-mqq5-j7w8-2hgh.json"