{
  "affected": [
    {
      "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"
      },
      "package": {
        "ecosystem": "RubyGems",
        "name": "alchemy_cms",
        "purl": "pkg:gem/alchemy_cms"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "8.2.0"
            },
            {
              "fixed": "8.2.6"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ],
      "versions": [
        "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.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"
      },
      "package": {
        "ecosystem": "RubyGems",
        "name": "alchemy_cms",
        "purl": "pkg:gem/alchemy_cms"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "8.1.0"
            },
            {
              "fixed": "8.1.14"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ],
      "versions": [
        "8.1.0",
        "8.1.1",
        "8.1.10",
        "8.1.11",
        "8.1.12",
        "8.1.13",
        "8.1.2",
        "8.1.3",
        "8.1.4",
        "8.1.5",
        "8.1.6",
        "8.1.7",
        "8.1.8",
        "8.1.9"
      ]
    },
    {
      "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"
      },
      "package": {
        "ecosystem": "RubyGems",
        "name": "alchemy_cms",
        "purl": "pkg:gem/alchemy_cms"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "8.0.0.a"
            },
            {
              "fixed": "8.0.15"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ],
      "versions": [
        "8.0.0",
        "8.0.0.a",
        "8.0.0.b",
        "8.0.0.c",
        "8.0.1",
        "8.0.10",
        "8.0.11",
        "8.0.12",
        "8.0.13",
        "8.0.14",
        "8.0.2",
        "8.0.3",
        "8.0.4",
        "8.0.5",
        "8.0.6",
        "8.0.7",
        "8.0.8",
        "8.0.9"
      ]
    },
    {
      "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"
      },
      "package": {
        "ecosystem": "RubyGems",
        "name": "alchemy_cms",
        "purl": "pkg:gem/alchemy_cms"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "7.4.15"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ],
      "versions": [
        "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.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.1",
        "2.1.1",
        "2.1.11",
        "2.1.12",
        "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.beta1",
        "2.1.beta5",
        "2.1.beta6",
        "2.1.rc2",
        "2.1.rc3",
        "2.1.rc4",
        "2.1.rc5",
        "2.1.rc6",
        "2.2.0",
        "2.2.1",
        "2.2.2",
        "2.2.3.1",
        "2.2.3.2",
        "2.2.4",
        "2.2.rc1",
        "2.2.rc11",
        "2.2.rc13",
        "2.2.rc14",
        "2.2.rc15",
        "2.2.rc2",
        "2.2.rc3",
        "2.2.rc6",
        "2.2.rc7",
        "2.2.rc8",
        "2.3.0",
        "2.3.1",
        "2.3.2",
        "2.3.rc5",
        "2.4.0",
        "2.4.1",
        "2.4.beta2",
        "2.4.rc1",
        "2.4.rc2",
        "2.4.rc4",
        "2.5.0",
        "2.5.0.b2",
        "2.5.0.b5",
        "2.5.0.b9",
        "2.5.0.rc3",
        "2.5.1",
        "2.5.2",
        "2.5.2.1",
        "2.5.2.2",
        "2.5.3",
        "2.5.3.1",
        "2.6.0",
        "2.6.0.rc5",
        "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.0.0",
        "3.0.0.rc5",
        "3.0.0.rc6",
        "3.0.0.rc7",
        "3.0.0.rc8",
        "3.0.1",
        "3.0.2",
        "3.0.3",
        "3.0.4",
        "3.1.0",
        "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.1",
        "3.1.3",
        "3.2.0",
        "3.2.0.beta",
        "3.2.0.rc1",
        "3.2.1",
        "3.3.0",
        "3.3.0.rc1",
        "3.3.0.rc2",
        "3.3.1",
        "3.3.2",
        "3.3.3",
        "3.4.0",
        "3.4.0.rc1",
        "3.4.1",
        "3.4.2",
        "3.5.0",
        "3.5.0.rc1",
        "3.5.0.rc2",
        "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.0.0",
        "4.0.0.beta",
        "4.0.0.rc1",
        "4.0.0.rc2",
        "4.0.1",
        "4.0.2",
        "4.0.3",
        "4.0.4",
        "4.0.5",
        "4.0.6",
        "4.1.0",
        "4.1.0.beta",
        "4.1.0.rc1",
        "4.1.1",
        "4.1.2",
        "4.2.0",
        "4.2.0.rc1",
        "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.0.0",
        "5.0.0.beta1",
        "5.0.0.beta2",
        "5.0.0.rc1",
        "5.0.0.rc2",
        "5.0.1",
        "5.0.10",
        "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.1.0",
        "5.1.0.beta1",
        "5.1.0.beta2",
        "5.1.0.rc1",
        "5.1.1",
        "5.1.10",
        "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.2.0",
        "5.2.0.b1",
        "5.2.0.rc1",
        "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.0.0",
        "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.1",
        "6.0.10",
        "6.0.11",
        "6.0.12",
        "6.0.13",
        "6.0.14",
        "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.1.0",
        "6.1.1",
        "6.1.10",
        "6.1.2",
        "6.1.3",
        "6.1.4",
        "6.1.5",
        "6.1.6",
        "6.1.7",
        "6.1.8",
        "6.1.9",
        "7.0.0",
        "7.0.0.pre.a",
        "7.0.0.pre.b",
        "7.0.0.pre.c",
        "7.0.0.pre.rc1",
        "7.0.1",
        "7.0.10",
        "7.0.11",
        "7.0.12",
        "7.0.13",
        "7.0.14",
        "7.0.15",
        "7.0.16",
        "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.1.0",
        "7.1.0.pre.b1",
        "7.1.0.pre.b2",
        "7.1.0.pre.rc1",
        "7.1.1",
        "7.1.10",
        "7.1.11",
        "7.1.12",
        "7.1.13",
        "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.2.0",
        "7.2.0.b",
        "7.2.0.rc1",
        "7.2.0.rc2",
        "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.10",
        "7.4.11",
        "7.4.12",
        "7.4.13",
        "7.4.14",
        "7.4.2",
        "7.4.3",
        "7.4.4",
        "7.4.5",
        "7.4.6",
        "7.4.7",
        "7.4.8",
        "7.4.9"
      ]
    }
  ],
  "aliases": [
    "CVE-2026-57579"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-862"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-06-19T17:47:13Z",
    "nvd_published_at": null,
    "severity": "HIGH"
  },
  "details": "# Unauthenticated nested page API leaks restricted & unpublished content\n\n- **Location:** `app/controllers/alchemy/api/pages_controller.rb:28` (`Api::PagesController#nested`)\n- **Affected version:** Alchemy CMS 8.3.0.dev (Rails 8.1.3)\n\n## Description\n\nThe 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.\nAppending `?elements=true` additionally dumps the element/ingredient **content** of restricted pages, fully bypassing the access control the sibling `show` and `index` actions enforce.\n\n## Root cause\n\n`Api::PagesController#nested` calls no `authorize!` and applies no `published`/`restricted` scoping, unlike `show` (`authorize! :show`) and `index` (`accessible_by(current_ability, :index)`).\n`PageTreePreloader` loads `page.self_and_descendants` unfiltered, and `PageTreeSerializer` emits every page's metadata (and, with `elements`, `public_version.elements`) with no ability check.\n\n## Evidence\n\nAn 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`).\nThe same guest hitting `GET /api/pages/3` (`show`) gets HTTP **403** `{\"error\":\"Not authorized\"}`, proving `nested` returns what `show` correctly denies.\n\n### Reproduction\n\n```bash\n# 1) Metadata leak (guest, no auth)\ncurl -s http://localhost:3000/api/pages/nested | python3 -m json.tool | grep -E '\"name\"|\"restricted\"|\"public\"'\n\n# 2) Content leak of restricted page\ncurl -s \"http://localhost:3000/api/pages/nested?elements=true\" | grep -oE 'TOPSECRET_RESTRICTED_BODY_[A-Za-z0-9]+|RESTRICTED_RICHTEXT_[A-Za-z0-9]+'\n\n# 3) Contrast — show denies the same guest\ncurl -s -o /dev/null -w \"show /api/pages/3 -> HTTP %{http_code}\\n\" http://localhost:3000/api/pages/3\n```\n\n### Suggested fix\n\n```ruby\ndef nested\n  @page = Page.find_by(id: params[:page_id]) || Language.current_root_page\n  authorize! :show, @page\n  preloaded_page = PageTreePreloader.new(page: @page, user: current_alchemy_user, ability: current_ability).call\n  render json: PageTreeSerializer.new(preloaded_page, ability: current_ability,\n                                      user: current_alchemy_user, elements: params[:elements])\nend\n```\n\nAdditionally 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)`.",
  "id": "GHSA-mqq5-j7w8-2hgh",
  "modified": "2026-09-15T03:56:01.761610104Z",
  "published": "2026-06-19T17:47:13Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/AlchemyCMS/alchemy_cms/security/advisories/GHSA-mqq5-j7w8-2hgh"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/AlchemyCMS/alchemy_cms"
    }
  ],
  "schema_version": "1.9.0",
  "severity": [
    {
      "score": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N",
      "type": "CVSS_V3"
    }
  ],
  "summary": "AlchemyCMS: Unauthenticated nested page API leaks restricted & unpublished content"
}