highCVE-2026-69197Sep 17, 2026

CVE-2026-69197: Umbraco.Cms Delivery API Protected Content Disclosure via Property Expansion

Rohit Hatagale
AI Security Researcher, SecureLayer7

Umbraco's Content Delivery API leaks member-gated content to anonymous callers because access checks are only applied to the directly requested node, not to protected nodes pulled in through Content…

PackageUmbraco.Cms
Ecosystemnuget
Affected>= 12.0.0, < 13.15.1
Fixed in13.15.1

The problem

The Delivery API enforces Public Access (member-gating) only at the controller layer, on the node being directly requested. When a public node references a protected node via a Content Picker or Multi-Node Tree Picker (including pickers nested in Block List, Block Grid, or Rich Text Editor blocks), the expansion serializer outputs the protected node's full data with no access check.

An anonymous caller gets the protected node's name, route, and id even without expansion. Adding ?expand on the picker property dumps all property values. Content-type alias allow/deny restrictions configured in DeliveryApi:DisallowedContentTypeAliases are bypassed the same way.

Proof of concept

A working proof-of-concept for CVE-2026-69197 in Umbraco.Cms, with the exact payload below.

http
GET /umbraco/delivery/api/v2/content/item/public-page-slug?expand=properties[pickerAlias] HTTP/1.1
Host: target.example.com
Accept: application/json

# Step 1 - no expand: leaks name, route, id of protected referenced node
GET /umbraco/delivery/api/v2/content/item/public-page-slug HTTP/1.1
Host: target.example.com
Accept: application/json

# Step 2 - with expand: dumps all properties of the protected referenced node
GET /umbraco/delivery/api/v2/content/item/public-page-slug?expand=properties[pickerAlias] HTTP/1.1
Host: target.example.com
Accept: application/json

The root cause is in RequestContextOutputExpansionStrategyV2 and ElementOnlyOutputExpansionStrategy: both strategies expand and serialize referenced content items without consulting the Public Access service or the content-type alias allow/deny list. The access gate only ran at the top-level controller action, so any picker property on a public node became a blind spot.

The patch (commits 26312a3, 5360e2a, a9649da) adds per-node Public Access and content-type alias checks inside the expansion strategies, so each referenced node is evaluated independently before being serialized. This maps directly to CWE-862 (missing authorization) and CWE-200 (sensitive information exposure).

The fix

Upgrade to Umbraco.Cms 13.15.1, 17.5.3, or 18.0.2. If an immediate upgrade is not possible, disable the Delivery API (DeliveryApi:Enabled: false) or restrict org-wide access with an API key (DeliveryApi:PublicAccess: false) as a partial mitigation. Note that the API-key mitigation only reduces severity; it does not fully prevent the bypass for key holders.

Reported by suryadina.

References: [1][2][3][4][5][6]

Related research