CVE-2026-69197
Executive Summary
CVE-2026-69197 is an information disclosure vulnerability (CWE-200) in Umbraco, an ASP.NET-based content management system. In affected versions prior to 13.15.1, 17.5.3, and 18.0.2, the Content Delivery API enforces member and Public Access authorization checks only against the directly requested node, not against referenced nodes serialized via Content Picker or Multi-Node Tree Picker properties (including pickers nested inside Block List, Block Grid, or Rich Text Editor blocks). This allows an anonymous or API-key-holding caller to retrieve protected node metadata — name, route, and id — and, via the ?expand parameter, full property values of nodes the caller is not authorized to read.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Technical Analysis
Umbraco's Content Delivery API exposes content as JSON to headless and decoupled front ends. Authorization for content access is governed by two mechanisms referenced in the advisory: member / Public Access checks (per-node access restrictions assigned in the CMS) and content-type alias restrictions (allowed or disallowed type lists for the Delivery API). A supporting configuration flag, DeliveryApi:PublicAccess, controls whether Public Access rules are enforced on the Delivery API surface at all.
The core flaw is a missing authorization check on the serialization graph. When a client requests a node, Umbraco serializes not just that node's own properties but also the properties of content referenced through relationship properties — specifically Content Picker and Multi-Node Tree Picker. These evaluated references, and references nested inside Block List, Block Grid, or Rich Text Editor blocks, are serialized without re-applying the caller's Public Access or content-type alias authorization at the referenced-node level. The authorization decision is made once, for the directly requested node, and then trusted for the entire transitively expanded object graph.
The advisory explicitly names RequestContextOutputExpansionStrategyV2 and ElementOnlyOutputExpansionStrategy as the code paths that carry this defect. These expansion strategies drive how ?expand resolves referenced content into full serialized representations — and they bypass allowed/disallowed content-type alias restrictions in the same way they bypass per-node Public Access.
Two distinct exposure configurations exist:
DeliveryApi:PublicAccessenabled — an anonymous caller retrieves a protected node's name, route, and id through an unprotected referencing node, and via?expandretrieves full property values of the protected node.- Organization-wide API key gate — the Delivery API is locked behind a single API key. A holder of that key can still bypass per-node Public Access rules through the same expansion path. This is significant: the API key is a coarse, tenant-wide credential, and individual node-level restrictions are the finer-grained control that the flaw defeats.
Critically, direct requests to the protected node still return HTTP 401, so the bypass is invisible to a naive spot check of the protected node itself. The leak is only observable in the serialized response of an unprotected referring node. There is no established integrity or availability impact — this is purely a confidentiality defect.
The affected version line is broad: two major generations (13.x and the 17.x/18.x branch) indicate the flaw survived multiple releases and was addressed in coordinated patch releases across maintenance tracks.
Exploitation Scenarios
No public PoC or exploit code is available. The attack chain below is inferred strictly from the vulnerability class (missing authorization check on a serialized object graph) and the specifics named in the NVD description.
1) Reconnaissance / target identification
The attacker identifies an Umbraco 13.x (< 13.15.1), 17.x (< 17.5.3), or 18.x (< 18.0.2) instance exposing the Content Delivery API. If DeliveryApi:PublicAccess is enabled (configuration observable through response behavior at the Delivery API surface), no credential is required. If the Delivery API requires the organization-wide API key, the attacker must first obtain a valid key — from a leaked front-end build, a mobile app binary, a misconfigured CI/CD environment, or credential reuse — which is an equally valuable target.
2) Locating a reference path to the protected node The attacker enumerates content that is publicly readable and whose Content Delivery API response contains Content Picker or Multi-Node Tree Picker properties — including pickers nested in Block List, Block Grid, or Rich Text Editor blocks — that reference the protected node. These reference relationships are the pivot: the attacker never requests the protected node directly (which would return 401) but requests the unprotected referencing node.
3) Triggering the flawed serialization path
By requesting the unprotected referencing node, the attacker causes RequestContextOutputExpansionStrategyV2 / ElementOnlyOutputExpansionStrategy to serialize the referenced node. The referencing-node response carries the protected node's name, route, and id. Using the Delivery API's ?expand parameter on the requesting node, the attacker causes full translation of the referenced node into its complete serialized property set — including content whose per-node Public Access should block the caller, and content whose content-type alias should be disallowed.
4) Post-exploitation impact Recovered values may include internal titles, URLs/routes (useful for enumerating otherwise hidden CMS structure), member-facing or partner-facing content, and any sensitive business data stored in protected properties. The technique is stealthy: it produces a 200 on an unprotected resource, so log review focused on 401/403 responses misses it entirely. There is no established integrity or availability impact — the attacker reads content that was meant to be access-restricted and maps the protected content graph.
Impact Assessment
Confidentiality: Low–Moderate (context dependent). Per CWE-200 and the advisory's framing, the direct impact is unauthorized disclosure of protected node metadata and, with ?expand, full property values. The direct-request path returns 401, which is why the CVSS confidentiality subscore for the inherent flaw is limited (inferred C:L), but real-world impact depends entirely on what the organization stores in Public Access-restricted nodes — pricing, internal-only copy, member-gated data, unreleased announcements, partner contracts, or PII.
Integrity: None. The advisory explicitly establishes no integrity impact. Availability: None. No availability impact established.
Blast radius:
- Any Umbraco 13.x, 17.x, or 18.x deployment running the Content Delivery API with either
DeliveryApi:PublicAccessenabled or an organization-wide API key. - Anonymous exposure in the Public Access configuration; authenticated-to-the-API-key exposure in the API-key configuration, where per-node restrictions are the finer control being defeated.
- Any site relying on Public Access as the sole gate for sensitive content should be treated as fully disclosed.
- The API-key configuration is notable for insider/second-party risk: any current or former holder of the tenant-wide key can enumerate per-node-restricted content.
Overall: a high-severity data-exposure finding for content-governed sites, scored moderate when treated as pure confidentiality with no integrity/availability component.
Detection Guidance
Detection must focus on anomalous delivery of Content Picker / Multi-Node Tree Picker references and substantial ?expand usage, since the vulnerable resource returns 200. There is no I/O signature in the classic sense.
Sigma Rule
title: Umbraco Content Delivery API Protected Node Disclosure via Expand (CVE-2026-69197)
id: 8f3c1a6e-2b7d-4e91-9c05-1a2f7d6e0b44
status: experimental
description: Detects Content Delivery API requests using ?expand against referencing nodes, the pattern that bypasses per-node Public Access and content-type alias restrictions in Umbraco < 13.15.1, < 17.5.3, < 18.0.2.
references:
- https://nvd.nist.gov/vuln/detail/CVE-2026-69197
author: valtersit.com Threat Intelligence
date: 2026/01/01
tags:
- attack.t1213.003
- cwe.200
logsource:
category: webserver
detection:
selection_path:
cs-uri-query|contains:
- 'expand='
- '%24expand='
- '$expand='
selection_api:
cs-uri-stem|contains|all:
- '/umbraco/delivery/api'
condition: selection_api and selection_path
falsepositives:
- Legitimate headless front-end expansion of intentionally public referenced content
level: medium
YARA Rule
rule CVE_2026_69197_Umbraco_DeliveryApi_Expand_Probe
{
meta:
description = "Detects HTTP requests probing Umbraco Content Delivery API expansion for CVE-2026-69197"
author = "valtersit.com Threat Intelligence"
reference = "https://nvd.nist.gov/vuln/detail/CVE-2026-69197"
date = "2026-01-01"
severity = "medium"
strings:
$api = "/umbraco/delivery/api" ascii nocase
$exp1 = "$expand=" ascii nocase
$exp2 = "%24expand=" ascii nocase
$exp3 = "?expand=" ascii nocase
condition:
$api and any of ($exp*)
}
Suricata IDS Rule
alert http any any -> any any (msg:"CVE-2026-69197 Umbraco Delivery API protected-node disclosure via expand"; flow:established,to_server; http.uri; content:"/umbraco/delivery/api"; nocase; http.uri; content:"expand"; nocase; fast_pattern; classtype:attempted-recon; reference:cve,2026-69197; sid:202669197; rev:1;)
Elastic Detection
sequence by source.ip with maxspan=2m
[network where http.request.method == "GET"
and url.path : "/umbraco/delivery/api*"
and stringContains(url.query, "expand")]
[network where http.request.method == "GET"
and url.path : "/umbraco/delivery/api*"]
Splunk SPL Query
index=web sourcetype=access_combined
| where like(uri_path, "%/umbraco/delivery/api%")
| where like(uri_query, "%expand=%") OR like(uri_query, "%$expand=%") OR like(uri_query, "%24expand=%")
| stats count min(_time) as first_seen max(_time) as last_seen values(uri_query) as queries by src_ip uri_path status
| where count > 5
| sort - count
Wazuh OSSEC Rule
<group name="web,umbraco,cve_2026_69197,">
<rule id="2026919" level="8">
<decoded_as>web</decoded_as>
<id>31100</id>
<match>umbraco/delivery/api</match>
<regex type="pcre2">(?i)(%24|%24|\\$)?expand=</regex>
<description>Possible exploitation of CVE-2026-69197: Umbraco Content Delivery API protected node disclosure via expand parameter</description>
<mitre>
<id>T1213.003</id>
</mitre>
<group>pci_dss_10.6.1,gdpr_IV_35.7.d,</group>
</rule>
</group>
Mitigation & Patch Guidance
Patch confidence: 0/4 (UNPATCHED — no patch evidence from any tracked source).
The vendor advisory states the issue is fixed in 13.15.1, 17.5.3, and 18.0.2, but no patch evidence has been confirmed from tracked sources, no workarounds were published in the advisory, and the affected-version list is empty in the source data. Treat all 13.x < 13.15.1, 17.x < 17.5.3, and 18.x < 18.0.2 deployments as exposed until verified.
1) Immediate mitigations
- Disable the Content Delivery API if it is not in production use, eliminating the exposed surface entirely.
- If the Delivery API is required, do not rely on Public Access or content-type alias restrictions as a security boundary for sensitive content. Place unprotected (publicly readable) referencing nodes under the same trust assumptions as the nodes they reference — treat any content reachable via Content Picker / Multi-Node Tree Picker as potentially public.
- Restrict or remove
?expandusage: audit which referencing-node responses enable expansion and avoid exposing full property expansion for any node that can reference restricted content. - Rotate the organization-wide API key. The API-key model does not defend per-node Public Access on vulnerable versions, so a leaked key is a direct content-disclosure credential.
- Front the Delivery API with a reverse proxy / WAF rule that blocks requests combining a delivery-API path with a large
expandparameter set, and alert on the pattern.
2) Patch / upgrade steps
- Upgrade to Umbraco 13.15.1, 17.5.3, or 18.0.2 on the matching major track.
- Because multi-generation tracks are involved, inventory every Umbraco instance and confirm its track before upgrading; a fix on one track does not cover instances pinned to an older line.
- Verify post-upgrade that (a) direct requests to protected nodes still return 401 and (b) referencing-node responses no longer leak protected node name/route/id or expanded property values.
3) Long-term hardening
- Never treat presentation-layer access controls (Public Access, content-type alias restrictions, a shared API key) as your only authorization boundary for sensitive content. Enforce authorization at the API/serialization layer with per-object checks applied at every node of the serialized graph, including transitively referenced and block-nested content.
- Maintain a least-privilege content model: keep genuinely sensitive data out of the public Delivery API's reachable graph, not merely behind per-node rules.
- Log and monitor 200 responses from the Delivery API rather than only 401/403, because this class of flaw succeeds with a success status.
- Add automated regression tests that request a referencing node with
?expandenabled and assert no protected-node fields appear in the response.
References
- NVD — CVE-2026-69197: https://nvd.nist.gov/vuln/detail/CVE-2026-69197
- Umbraco security advisories / release notes for 13.15.1, 17.5.3, and 18.0.2 (vendor advisory; confirm on the Umbraco security portal)
- CWE-200: Exposure of Sensitive Information to an Unauthorized Actor — https://cwe.mitre.org/data/definitions/200.html
- MITRE ATT&CK T1213.003 — Data from Information Repositories: Code Repositories — https://attack.mitre.org/techniques/T1213/003/
- CISA KEV Catalog — CVE-2026-69197: not listed as of this report.
Threat actor / exploit-in-the-wild evidence: None established. No public PoC, no Nuclei template, no exploit code, and no CISA KEV listing. EPSS has not yet been scored by FIRST.org; no EPSS value is asserted here. Any exploit activity is currently theoretical and would be conducted as a low-noise, authenticated-or-anonymous content-enumeration campaign against exposed Umbraco Delivery API endpoints.
What is this? Security researchers use these exact search queries on Shodan.io (a search engine for internet-connected devices) to find vulnerable systems globally. You can copy these dorks to see if your organization's IP space is exposed.