This is a master key to the building’s telemetry closet, not a battering ram for the front door
In Dify versions up to 1.14.1, the console trace-configuration endpoints for applications did not consistently verify that the targeted app_id belonged to the caller’s tenant. The practical effect is cross-tenant authorization bypass: a user authenticated in tenant A could change tracing for an app in tenant B and point its telemetry at an attacker-controlled Langfuse or OpenTelemetry endpoint, causing later prompts, outputs, and metadata from that victim app to be exported off-platform.
The vendor's CRITICAL 9.1 overstates enterprise reality. This is not host takeover, not unauthenticated RCE, and not broad internet compromise by itself; it is a management-plane data-exfil path that still needs product access, a reachable console, a target app identifier, and usually an editor-capable session. The risk is still real because the stolen content can be sensitive, but the attack chain has enough deployment friction that this lands as MEDIUM, not panic-grade.
4 steps from start to impact.
Get a foothold in Dify
curl, or Burp Suite Repeater is enough.- Dify console is reachable from the attacker's network position
- Attacker can self-register, be invited, or reuse stolen credentials/session
- Target deployment is running Dify rather than only exposing downstream published apps
- Many self-hosted Dify consoles sit behind SSO, VPN, reverse proxies, or private ingress
- MFA, IP allowlists, and SCIM/IdP controls stop the easiest path
- Published apps alone are not enough; the attacker needs console/API access
<=1.14.1, but they cannot prove exploitability.Find a victim app identifier
/console/api/apps/<app_id>/trace-config. The attacker needs a valid target app_id, which can come from API/UI leakage, shared links, browser history, prior tenant knowledge, or other low-grade information exposure. Burp, browser dev tools, or direct API enumeration attempts are sufficient.- Attacker can reach the console API
- Attacker can discover or infer a victim
app_id
- App identifiers are not guaranteed to be discoverable across tenants
- Blind UUID guessing is poor tradecraft unless another leak exists
- A 404-like behavior after the fix removes easy validation
/console/api/apps/*/trace-config, especially many misses or cross-app probing patterns.Overwrite trace configuration cross-tenant
GET/POST/PATCH/DELETE requests to the trace-config endpoints and points the victim app at an attacker-controlled Langfuse host or OTLP collector. The fix in PR #35793 adds tenant-scoped app resolution via @get_app_model; without that check, the controller trusted the supplied app_id too much.- Deployment is running Dify
<=1.14.1 - Trace configuration endpoints are enabled and reachable
- Attacker has a session accepted by the console auth layer
- Outbound egress controls may block arbitrary Langfuse or OTLP destinations
- Some deployments do not use tracing at all or restrict observability integrations
- This changes telemetry settings, not business logic or system code execution
Collect victim prompts and outputs
- Victim app continues to receive traffic after the malicious trace change
- Tracing stays enabled long enough to capture useful data
- Blast radius is bounded to traced application activity, not the whole host fleet
- No direct evidence in sources of code execution, destructive impact, or automated worming
- Low-traffic apps may yield little value before defenders notice
The supporting signals.
| In-the-wild status | No primary-source evidence of active exploitation found. Not in CISA KEV and no vendor or CISA campaign note was located in the reviewed sources. |
|---|---|
| Proof-of-concept availability | There is no polished public exploit repo in the reviewed primary sources, but the exploit path is effectively exposed by the public patch diff in PR #35793 and the fixing commit. For a competent tester, this is patch-diff-to-PoC. |
| EPSS | 0.00038 with percentile 0.11674 as shown by the CIRCL/Vulnerability-Lookup mirror of FIRST data on 2026-05-28 — low empirical exploitation pressure. |
| KEV status | Not listed in the CISA Known Exploited Vulnerabilities Catalog as checked against available official catalog pages. |
| CVSS reality check | NVD displays a 9.1 CRITICAL CNA vector CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N, but the CVE 5.2 record mirrored by CIRCL also shows a VulnCheck GENERAL scenario scored 7.4 HIGH with AC:H. That inconsistency matters because the narrative text says authenticated editor users, which is materially different from a clean PR:N internet bug. |
| Affected versions | Affected range is Dify <= 1.14.1 according to the CVE record and patch references. |
| Fixed version | Patched in 1.14.2 per the official release notes, which call out tenant isolation hardening for app trace-config endpoints. |
| Impact mechanics | Per PR #35793, the attacker can redirect victim app traces to an attacker-controlled Langfuse/OpenTelemetry destination and capture prompts, outputs, and trace metadata from later app runs. |
| Exposure population | This is a management-plane issue, not a published-app bug. Dify is widely adopted — the repository shows roughly 143k GitHub stars in the reviewed snapshot — but no authoritative Shodan/Censys/FOFA census was found in primary sources, so internet-facing exposure should be treated as deployment-dependent, not assumed universal. |
| Disclosure and credit | Public CVE publication was 2026-05-18. The CIRCL-mirrored CVE record credits Ido Shani and Gal Zaban of Zafran Security; the patch discussion also references disclosure via Huntr. |
noisgate verdict.
The decisive downward pressure is attacker position: in most enterprises this requires access to the Dify management plane, not just the public app endpoint, and often also a low-friction path to an authenticated session. The amplifier is that once reached, the flaw can siphon sensitive prompts and outputs across tenants, but the blast radius is still confined to traced application traffic rather than host takeover or fleet-wide compromise.
Why this verdict
- Downgrade for attacker position: despite the vendor
PR:Nframing, the exploit narrative and patch notes describe an attacker who is already inside the Dify console path — on self-hosted estates that usually implies SSO/VPN/private ingress or prior compromise. - Downgrade for population reach: this hits the console management plane, not every internet-exposed Dify-published app. Many enterprises expose the chatbot endpoint but not the admin/API surface needed for
/console/api/apps/<app_id>/trace-config. - Downgrade for chained prerequisites: the attacker still needs a valid session, a target
app_id, and outbound reachability to an attacker-controlled trace sink. Each requirement narrows the reachable population and compounds downward pressure. - Keep it at MEDIUM, not LOW: the confidentiality/integrity impact on affected apps is real. If the target runs multi-tenant Dify Cloud or a shared creator platform with open signup, a low-trust outsider can pivot into cross-tenant data capture with very little noise.
- Low empirical threat pressure: EPSS is extremely low and there is no KEV or campaign evidence in the reviewed sources, which argues against treating this like an emergency fleet event.
Why not higher?
This is not an unauthenticated front-door break against the average enterprise host. It does not deliver code execution, domain-wide blast radius, or one-shot full-instance compromise; it abuses a tenant check in an authenticated console workflow and then waits for victim app traffic. That is dangerous, but it is not the same operational class as an internet RCE or auth bypass on a widely exposed appliance.
Why not lower?
Cross-tenant prompt and output exfiltration is a serious privacy and IP event, especially in AI platforms where traces may contain secrets, customer content, and workflow metadata. The vendor docs confirm tracing sends debugging or production data to external observability platforms, so a successful exploit can leak exactly the material most teams care about.
What to do — in priority order.
- Restrict console reachability — Put the Dify console/API behind VPN, private ingress, or IdP-enforced SSO if it is not already. For a MEDIUM verdict there is no mitigation SLA, but this is the fastest risk reducer for exposed deployments and should be done immediately where the console is internet-facing.
- Tighten signup and role assignment — Disable open self-registration where possible and review who actually holds editor-capable access in Dify. There is no mitigation SLA for MEDIUM, but reducing the pool of low-trust authenticated users cuts the exploit population sharply while you schedule remediation.
- Constrain observability egress — Allow outbound trace traffic only to approved Langfuse/OTLP destinations through proxy or firewall policy. There is no mitigation SLA for MEDIUM, but this directly blocks the exfil path even if a tenant-scope bug exists.
- Alert on trace-config changes — Instrument audit logging or reverse-proxy detection for
/console/api/apps/*/trace-configand on any new external tracing hostnames. There is no mitigation SLA for MEDIUM; use this as compensating telemetry until all vulnerable nodes are upgraded.
- A WAF alone does not solve this; the requests are legitimate authenticated console API calls, not obviously malicious payloads.
- Relying only on MFA is incomplete; MFA helps stop account abuse, but a legitimately created or invited account can still exercise the vulnerable endpoint.
- Blocking published app endpoints does not fix the problem if the console/API remains reachable, because the bug lives in management-plane trace configuration.
Crowdsourced verification payload.
Run this on the Dify host or source checkout directory, not from a remote auditor workstation. Invoke it as bash verify-cve-2026-41947.sh /opt/dify and it needs read access to the Dify install path; root is not required unless your repo directory or Docker metadata is restricted.
#!/usr/bin/env bash
# verify-cve-2026-41947.sh
# Checks whether a Dify installation appears vulnerable to CVE-2026-41947
# by determining the local checked-out version/tag. Designed for source-based
# and Docker Compose installs where the Dify repo/tag is present on disk.
#
# Exit codes:
# 0 = PATCHED
# 1 = VULNERABLE
# 2 = UNKNOWN / insufficient evidence
set -u
TARGET_DIR="${1:-.}"
FIXED_VERSION="1.14.2"
ver_ge() {
# returns 0 if $1 >= $2
[ "$(printf '%s\n%s\n' "$1" "$2" | sort -V | tail -n1)" = "$1" ]
}
normalize_tag() {
local t="$1"
t="${t#refs/tags/}"
t="${t#v}"
t="${t#release-}"
printf '%s' "$t"
}
extract_version_from_file() {
local dir="$1"
local candidate
for candidate in \
"$dir/api/pyproject.toml" \
"$dir/api/setup.py" \
"$dir/web/package.json" \
"$dir/package.json"; do
if [ -f "$candidate" ]; then
local v
v=$(grep -Eom1 '[0-9]+\.[0-9]+\.[0-9]+' "$candidate" 2>/dev/null || true)
if [ -n "$v" ]; then
printf '%s' "$v"
return 0
fi
fi
done
return 1
}
get_git_version() {
local dir="$1"
if command -v git >/dev/null 2>&1 && [ -d "$dir/.git" ]; then
local tag
tag=$(git -C "$dir" describe --tags --exact-match 2>/dev/null || true)
if [ -z "$tag" ]; then
tag=$(git -C "$dir" describe --tags --abbrev=0 2>/dev/null || true)
fi
if [ -n "$tag" ]; then
normalize_tag "$tag"
return 0
fi
fi
return 1
}
main() {
if [ ! -d "$TARGET_DIR" ]; then
echo "UNKNOWN - target directory not found: $TARGET_DIR"
exit 2
fi
local version=""
version=$(get_git_version "$TARGET_DIR" 2>/dev/null || true)
if [ -z "$version" ]; then
version=$(extract_version_from_file "$TARGET_DIR" 2>/dev/null || true)
fi
if [ -z "$version" ]; then
echo "UNKNOWN - could not determine local Dify version from git tags or common metadata files"
exit 2
fi
if ver_ge "$version" "$FIXED_VERSION"; then
echo "PATCHED - detected Dify version $version (fixed threshold: $FIXED_VERSION)"
exit 0
fi
echo "VULNERABLE - detected Dify version $version (< $FIXED_VERSION)"
exit 1
}
main
If you remember one thing.
<=1.14.1 systems to 1.14.2 or newer within the noisgate remediation SLA of ≤365 days.Sources
What defenders are saying.
Crowdsourced verification outputs.
Results submitted by users who ran the verification payload against their environment.