CVE-2026-52769 Overview
YesWiki is a wiki system written in PHP. CVE-2026-52769 is a Server-Side Request Forgery (SSRF) vulnerability [CWE-918] in YesWiki versions 4.6.2 through 4.6.5. The publicly exposed POST /api/forms/{formId}/actor/inbox route accepts an HTTP Signature header whose keyId parameter is a URL. The HttpSignatureService::verifySignature() method fetches that URL server-side before any cryptographic verification or URL validation. An unauthenticated remote attacker can force YesWiki to issue arbitrary outbound HTTP GET requests to internal services, cloud metadata endpoints, or intranet admin panels. The issue is patched in version 4.6.6.
Critical Impact
Unauthenticated SSRF allows attackers to reach internal-only services, scan ports, and query cloud IAM metadata endpoints such as 169.254.169.254 on affected deployments.
Affected Products
- YesWiki 4.6.2
- YesWiki 4.6.3 through 4.6.5
- Deployments with ActivityPub enabled on at least one Bazar form
Discovery Timeline
- 2026-09-05 - CVE-2026-52769 published to NVD
- 2026-09-08 - Last updated in NVD database
Technical Details for CVE-2026-52769
Vulnerability Analysis
The vulnerability resides in tools/bazar/services/HttpSignatureService.php. When a POST request arrives at the ActivityPub inbox endpoint, the service parses the Signature header and extracts the keyId parameter. YesWiki treats this parameter as a URL and immediately issues a server-side HTTP GET to retrieve the signer's public key. This fetch executes before any URL validation, scheme check, or host allow-listing.
The route is exposed with acl:"public", so no authentication is required. An attacker controls both the target URL and the request timing. Response bodies are not returned directly to the attacker, but timing differences and error messages act as oracles for port scanning and service enumeration. On cloud instances, this reaches IAM metadata services and returns credential material through subsequent verification error paths.
Root Cause
The root cause is missing input validation on an attacker-controlled URL prior to a server-initiated network request. The verifySignature() method inverted the correct order of operations by fetching remote content before validating the source. Neither the URL scheme, host, nor resolved IP address was checked against a deny-list of private, loopback, reserved, or link-local ranges.
Attack Vector
An unauthenticated attacker sends a POST request to /api/forms/{formId}/actor/inbox with a crafted Signature header. The keyId field points to any URL the server can reach. The attacker uses HTTP or non-HTTP schemes, internal hostnames, or metadata IPs to enumerate the internal environment. The only precondition is that ActivityPub be enabled on at least one Bazar form.
// Patch: tools/bazar/services/HttpSignatureService.php
// Source: github.com/YesWiki/yeswiki/commit/87e627f33e79879827a3669fee2aa1244612c487
/**
* Validate that a keyId URL is safe to fetch: must be HTTPS and must not
* resolve to a private, loopback, reserved, or link-local address (SSRF guard).
*/
private function validateKeyIdUrl(string $url): void
{
$parts = parse_url($url);
if ($parts === false || empty($parts['scheme']) || empty($parts['host'])) {
throw new Exception('Invalid keyId URL');
}
if ($parts['scheme'] !== 'https') {
throw new Exception('keyId URL must use HTTPS');
}
// Strip IPv6 brackets (e.g. [::1] -> ::1)
$host = trim($parts['host'], '[]');
// Collect all IPs the host resolves to so every address family is checked.
if (filter_var($host, FILTER_VALIDATE_IP)) {
$ips = [$host];
} else {
$ips = [];
$ipv4 = gethostbyname($host);
if ($ipv4 !== $host) {
$ips[] = $ipv4;
}
foreach (dns_get_record($host, DNS_AAAA) ?: [] as $record) {
// additional AAAA record handling
}
}
}
The patch enforces HTTPS-only URLs, resolves every address family for the target host, and rejects private, loopback, reserved, and link-local addresses before any fetch occurs.
Detection Methods for CVE-2026-52769
Indicators of Compromise
- POST requests to /api/forms/*/actor/inbox originating from unauthenticated sources.
- Signature headers where the keyId parameter resolves to internal IP ranges such as 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 127.0.0.0/8, or 169.254.169.254.
- Outbound HTTP requests from the YesWiki server process to cloud metadata endpoints or non-public hosts.
Detection Strategies
- Inspect web server access logs for POST traffic to the ActivityPub inbox route paired with abnormal Signature header values.
- Correlate inbound inbox requests with immediate outbound connections from the PHP process to unexpected destinations.
- Baseline expected federation peers and alert on keyId URLs pointing to non-federated or internal hosts.
Monitoring Recommendations
- Enable egress filtering on the YesWiki host and log every blocked connection attempt for review.
- Monitor cloud metadata service access (169.254.169.254) from application workloads that should never query it.
- Track PHP-FPM or web-worker outbound DNS queries for internal hostnames not tied to legitimate workflows.
How to Mitigate CVE-2026-52769
Immediate Actions Required
- Upgrade YesWiki to version 4.6.6 or later without delay.
- If upgrading is not immediately possible, disable ActivityPub on all Bazar forms to remove the precondition for exploitation.
- Enforce host-level egress filtering that blocks the YesWiki process from reaching internal ranges and cloud metadata IPs.
Patch Information
The fix is included in YesWiki release v4.6.6 and delivered via commit 87e627f. Full technical details are in the GitHub Security Advisory GHSA-vw42-752g-5mrp. The patch adds a validateKeyIdUrl() method that enforces HTTPS and rejects private, loopback, reserved, and link-local destinations before any fetch.
Workarounds
- Disable ActivityPub across all Bazar forms until patching completes.
- Place a reverse proxy or WAF rule in front of YesWiki that blocks POST requests to /api/forms/*/actor/inbox from untrusted sources.
- On cloud instances, require IMDSv2 session tokens to reduce the value of any SSRF probe against 169.254.169.254.
# Example egress restriction using iptables to block metadata endpoint access
iptables -A OUTPUT -m owner --uid-owner www-data -d 169.254.169.254 -j REJECT
iptables -A OUTPUT -m owner --uid-owner www-data -d 10.0.0.0/8 -j REJECT
iptables -A OUTPUT -m owner --uid-owner www-data -d 172.16.0.0/12 -j REJECT
iptables -A OUTPUT -m owner --uid-owner www-data -d 192.168.0.0/16 -j REJECT
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.