CVE-2026-72723
Executive Summary
CVE-2026-72723 is an authorization-check omission in Discourse, an open-source discussion platform, affecting all installations prior to versions 2026.1.6, 2026.5.2, 2026.6.1, and 2026.7.0. An unauthenticated remote attacker can retrieve restricted tag names and descriptions through the public /site.json endpoint when those tags are limited by inaccessible categories, category tag groups, or tag-group permissions. The vulnerability has a CVSS base score of 5.3 (Medium) with low confidentiality impact; no integrity or availability impact, and no authentication or user interaction is required.
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
The flaw resides in the serialization path that constructs the site-wide configuration payload returned to anonymous visitors. Specifically, the method SiteSerializer.anonymous_default_navigation_menu_tags serializes tags sourced from the site setting SiteSetting.default_navigation_menu_tags. In a correctly functioning Discourse deployment, tag visibility is enforced through the DiscourseTagging.filter_visible routine, which filters out tags that the requesting viewer is not permitted to see based on:
- Category-level restrictions (tags assigned to categories the user cannot access),
- Category tag-group constraints,
- Tag-group permission rules (e.g., tags restricted to specific trust levels or groups).
In vulnerable versions, the anonymous serializer path omits this DiscourseTagging.filter_visible call. As a result, the JSON payload emitted for unauthenticated visitors at /site.json includes the complete set of tags configured in the default navigation menu — including those that should be hidden from anonymous viewers. The disclosed data consists of tag names and their descriptions.
The vulnerability class is CWE-862 (Missing Authorization). It is not an injection flaw and requires no crafted payload: the attack is a plain HTTP GET request to a legitimate, public endpoint, and the server over-discloses data because the authorization filter was never applied on that code path. The affected endpoint, /site.json, is part of Discourse's bootstrap configuration and is normally served without authentication, which is why the vulnerable serialization path is exposed to unauthenticated users.
The severity is moderated by the fact that only tag names and descriptions are leaked — not topic content, user records, or credentials. However, tag names and descriptions frequently encode sensitive operational information, such as internal project codenames, private-team designations, or references to restricted content areas.
Exploitation Scenarios
No public proof-of-concept or exploit code is currently available, and no Nuclei template or known in-the-wild exploitation has been reported. The attack chain below is inferred strictly from the vulnerability class described in the NVD entry.
Step 1 — Reconnaissance / Target Identification.
An attacker identifies Discourse instances exposed to the internet using search-engine or network-mapping techniques (e.g., Shodan queries for "Discourse" in HTTP titles or HTML content). Discourse instances are widely deployed as public forums, customer-support portals, and corporate community hubs, so a large number of targets will be reachable without authentication.
Step 2 — Triggering the Flaw.
The attacker sends an unauthenticated HTTP GET request to /site.json on the target. This endpoint is part of the normal client bootstrap sequence and returns a JSON document containing site configuration. On a vulnerable build, the serialization of the anonymous default navigation menu tags bypasses the DiscourseTagging.filter_visible authorization check, so the response includes tags that should be restricted.
Step 3 — Payload / Execution Method.
No payload or injection is required. The "execution" is simply parsing the HTTP response body. The attacker extracts the default_navigation_menu_tags portion of the JSON and enumerates the returned tag names and descriptions. Because the request is indistinguishable from a legitimate anonymous site visitor's request at the network layer, the attack is extremely difficult to block without breaking the public site's bootstrap.
Step 4 — Post-Exploitation Impact.
The attacker obtains names and descriptions of tags that the administrator intended to keep private — for example, tags bound to invite-only categories, internal projects, or employee-only content groups. This information can be leveraged for:
- Targeted phishing or social-engineering campaigns using internal project/team names,
- Mapping the structure of private communities and hidden categories,
- Correlating leaked tag names with other public data to infer business activities,
- Further reconnaissance against adjacent systems using the discovered naming conventions.
The confidentiality impact is limited to these metadata strings, but in enterprise deployments the practical business impact can exceed the technical CVSS sub-score.
Impact Assessment
- CVSS 5.3 (Medium) — Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N.
- Attack vector: Network; the vulnerability is remotely exploitable with no authentication, no user interaction, and low attack complexity.
- Confidentiality: Low (tag names/descriptions only).
- Integrity / Availability: None.
- Affected systems: Self-hosted Discourse instances running any version before 2026.1.6, 2026.5.2, 2026.6.1, or 2026.7.0. Discourse-hosted (cloud) instances are presumably patched by the vendor and are not affected unless otherwise indicated.
- Blast radius: Any anonymous visitor can trigger the disclosure; there is no privilege requirement. The data disclosed is site metadata, not user content, limiting direct account/data compromise but enabling follow-on reconnaissance.
- Exploitation likelihood: Low currently. EPSS score 0.00385 (31.7th percentile), CISA KEV status "NO", no public PoC, no exploit code, and patch confidence is 2/4 (CLAIMED — single source, not independently confirmed).
Detection Guidance
The detection challenge is that /site.json is a legitimate, frequently requested endpoint for all Discourse visitors. Rules should therefore focus on behavioral anomalies: high-frequency /site.json requests from a single unauthenticated IP, rapid replay of the request, or successful responses to /site.json from clients that never complete a normal site session.
Sigma Rule
title: Suspicious Unauthenticated Discourse /site.json Enumeration
id: 5f3a8b2e-7c41-4d6a-9f20-3a8e6b1d4c90
status: experimental
description: >
Detects repeated unauthenticated HTTP GET requests to the Discourse /site.json
endpoint, which returns site configuration including default navigation menu tags.
On versions vulnerable to CVE-2026-72723 (< 2026.1.6, < 2026.5.2, < 2026.6.1,
< 2026.7.0), the response may disclose restricted tag names and descriptions due
to a missing DiscourseTagging.filter_visible check in the anonymous serializer path.
author: Valters IT Threat Intelligence
date: 2026/07/15
logsource:
category: webserver
product: nginx
detection:
selection:
cs-method: GET
cs-uri-stem: /site.json
filter_known:
cs-useragent:
- "Mozilla*"
- "Discourse*
timeframe: 30m
condition: selection and not filter_known | count() by src_ip > 20
fields:
- src_ip
- cs-uri-stem
- cs-useragent
- sc-status
falsepositives:
- Load balancers or uptime monitors polling /site.json
- Developer tooling or Discourse mobile apps refreshing site config
level: medium
tags:
- attack.t1190
- cve.2026.72723
- cwe.862
YARA Rule
rule CVE_2026_72723_Discourse_SiteJSON_TagLeak
{
meta:
author = "Valters IT Threat Intelligence"
description = "Detects HTTP server responses or captured traffic containing Discourse /site.json payloads with navigation-menu tag serialization, indicating possible CVE-2026-72723 restricted-tag disclosure."
reference = "CVE-2026-72723"
cve = "2026-72723"
date = "2026-07-15"
severity = "medium"
strings:
$s_endpoint = "/site.json" ascii
$s_serializer_tag = "default_navigation_menu_tags" ascii
$s_site_key = "site" ascii
$s_tag_desc = "description" ascii
condition:
$s_endpoint and $s_serializer_tag and #s_tag_desc >= 1
}
Suricata IDS Rule
alert http any any -> $EXTERNAL_NET any (msg:"ET POLICY Discourse /site.json Unauthenticated Tag Disclosure Attempt (CVE-2026-72723)"; flow:established,to_server; http.method; content:"GET"; http.uri; content:"/site.json"; nocase; http.protocol; content:"HTTP/1.1"; classtype:attempted-recon; reference:cve,2026-72723; sid:2026723; rev:1;)
Deployment note: This rule triggers on the trigger request. For post-response detection of actual disclosure, deploy the rule inline on the server response path or combine with a threshold so that a single /site.json request from an IP that has no other site interaction is alerted.
Elastic Detection
sequence by source.ip with maxspan=15m
[ network where event.dataset == "nginx.access" and http.request.method == "GET" and url.path == "/site.json" ]
[ network where event.dataset == "nginx.access" and http.response.status_code == 200 and url.path == "/site.json" ]
The EQL sequence flags an unauthenticated client that requests /site.json more than once within 15 minutes and receives a 200 response — a pattern consistent with tag-metadata harvesting. SOC analysts should correlate the result with the absence of later session activity (no /t/ or /c/ requests) on the same source.ip.
Splunk SPL Query
index=web sourcetype=nginx:access
method=GET uri_path="/site.json"
| eval auth_status=if(match(http_user_agent, "^Discourse|^Mozilla"), "auth_like", "anon_like")
| stats count min(_time) as first_seen max(_time) as last_seen
values(uri_path) as endpoints by src_ip, auth_status
| where auth_status="anon_like" AND count > 20
| rename src_ip as "Source IP", count as "Request Count",
first_seen as "First Seen", last_seen as "Last Seen"
| table "Source IP", "Request Count", "First Seen", "Last Seen"
| sort - "Request Count"
Wazuh OSSEC Rule
<group name="discourse,cve-2026-72723,">
<rule id="100273" level="10" frequency="15" timeframe="3600">
<if_matched_sid>100270</if_matched_sid>
<field name="url">/site.json</field>
<description>Discourse CVE-2026-72723: Repeated unauthenticated /site.json requests detected (restricted tag disclosure attempt).</description>
<group>discourse,cve-2026-72723,recon,</group>
<mitre>
<id>T1190</id>
</mitre>
</rule>
</group>
Note: The parent rule (if_matched_sid) should decode the web-server access log and match any request whose URL contains /site.json. The child rule applies a frequency threshold (15 hits within 3,600 seconds) to reduce false positives from routine site bootstrap traffic.
Mitigation & Patch Guidance
Patch confidence: 2/4 (CLAIMED — single source claims patch, not independently confirmed).
Immediate mitigations (until patched):
- If your Discourse instance contains tags that must not be public, remove them from the
default_navigation_menu_tagssite setting. This does not fix the authorization gap but shrinks the disclosure surface. - Place the instance behind an authentication proxy (e.g., SSO/portal) if the community is intended to be private —
/site.jsonwill then only be served to authenticated users, defeating the anonymous attack path. - Add temporary detection rules (Sigma/Splunk above) and alert on anomalous
/site.jsonrequest volumes from single IPs. - If a web application firewall is available, log (do not blindly block)
/site.jsonaccess from IPs that do not subsequently request any other Discourse resource.
- If your Discourse instance contains tags that must not be public, remove them from the
Patch / upgrade steps:
- Upgrade Discourse to a fixed release: 2026.1.6, 2026.5.2, 2026.6.1, or 2026.7.0 (choose the patched build matching your release branch).
- Because patch confirmation rests on a single OSV source, verify the fix independently: review the release notes for the target version, confirm that
SiteSerializer.anonymous_default_navigation_menu_tagsnow appliesDiscourseTagging.filter_visible, and test/site.jsonresponses with a restricted tag in place before and after upgrade. - Standard Discourse installations (Docker
discourse/discourseimage or./launcherbased deploys) should apply the upgrade through the standard./launcher rebuild appprocedure, then runbin/rake db:migrateif required by the release notes.
Long-term hardening:
- Enforce a least-privilege model for tags: review tag-group permissions and category tag restrictions quarterly; ensure anonymous visibility is explicitly denied for sensitive tags.
- Add security regression tests that assert
/site.jsonnever contains restricted tag metadata for unauthenticated sessions. - Track Discourse security advisories (vendor announcements on meta.discourse.org and GitHub) and subscribe to OSV/NVD feeds so that future authorization defects in serializer paths are caught before deployment.
- Include CVE-2026-72723 in internal vulnerability-management scanning; EPSS indicates low current exploitation likelihood, but the missing-authorization class is frequently chained with other reconnaissance in targeted campaigns.
References
- NVD Entry — https://nvd.nist.gov/vuln/detail/CVE-2026-72723
- OSV Advisory (patch source) — https://osv.dev/vulnerability/CVE-2026-72723
- Discourse Official Site & Security Announcements — https://meta.discourse.org/ (security category) and https://github.com/discourse/discourse
- CISA Known Exploited Vulnerabilities Catalog — CVE-2026-72723 is not listed (status: NO), indicating no confirmed exploitation in the wild as of this report.
- Exploit-in-the-wild evidence: none known at the time of writing; no public PoC, Nuclei template, or exploit code has been identified for this CVE.