Oct 3, 2026·7 min read·14 visits
A DNS-rebinding SSRF vulnerability in the SiYuan Kernel AI Agent tools allows remote attackers to bypass private IP validation and access internal networks or cloud metadata by exploiting a Time-of-Check to Time-of-Use (TOCTOU) window in DNS resolution.
An Server-Side Request Forgery (SSRF) vulnerability via DNS-Rebinding Time-of-Check to Time-of-Use (TOCTOU) has been discovered in SiYuan (思源笔记), an open-source personal knowledge management system. The flaw exists within the AI Agent tools http_request (util.HTTPRequest) and web_fetch (util.WebFetch) of the SiYuan Kernel, allowing unauthenticated remote attackers to bypass SSRF validation and access private internal services or cloud metadata endpoints.
The vulnerability identified as CVE-2026-82234 is a Server-Side Request Forgery (SSRF) flaw in SiYuan, an open-source personal knowledge management system. The vulnerability specifically affects the AI Agent integration within the SiYuan Kernel, which exposes tools designed to retrieve external web pages and interface with third-party web services. These capabilities are exposed through functions such as util.HTTPRequest and util.WebFetch which run inside the core application environment.
To prevent abuse, the developers introduced SSRF validation logic called CheckHostSSRF to screen requested hosts before connection attempts. However, because this validation occurs during the URL parsing phase independently of the socket-creation phase, a Time-of-Check to Time-of-Use (TOCTOU) gap is introduced. Attackers can leverage this window of vulnerability using DNS-rebinding techniques, allowing arbitrary network requests to bypass the application's verification gates and access local resources.
The root cause of this vulnerability lies in a critical architectural mismatch between validation logic and connection-level network execution. The validation function CheckHostSSRF resolves the provided domain name using standard DNS query mechanisms. If the resolved IP address belongs to public network spaces, the address passes validation, and the application proceeds to execute the request using the default HTTP client client instance.
However, Go's default http.Client transport does not reuse the IP address resolved during the parsing validation step. Instead, when initiating the connection, the client's underlying network dialer performs an entirely separate DNS query to resolve the domain to an IP address for the socket connection. An attacker controlling the DNS server can exploit this by returning a public IP during the first resolution and an internal IP during the second resolution.
This behavior is documented as a Classic DNS-Rebinding attack pattern. Because the internal validation mechanism lacks IP pinning, it fails to bind the resolved socket connection to the validated destination. The connection-level socket is thus opened directly to internal loopback interfaces or cloud metadata servers without passing subsequent checks.
In the vulnerable implementation found in version 3.8.0, the AI agent's HTTP request utility relies on a default browser request instance via httpclient.NewBrowserRequest(). This client uses standard Go transport layers that lack custom DNS validation or socket connection interceptors. The code first performs the host validation using CheckHostSSRF but fails to pass any state or IP pinning parameters to the browser request that executes immediately afterward.
// Vulnerable execution path in v3.8.0
func HTTPRequest(method, rawURL string, headers map[string]string, body string) ... {
// ...
// Parse-time check only: validation occurs here
if err := CheckHostSSRF(host); err != nil {
return 0, "", "", err
}
// Connection-time resolution occurs here without IP validation
request := httpclient.NewBrowserRequest()
resp, err := sendByMethod(request, method, rawURL)
}The patch committed in dd2778b70d020b15491ef7418f5f63214583cd63 mitigates this vulnerability by replacing the default HTTP client with a hardcoded ssrfSafeClient. This specialized client overrides the transport's dial context with a custom dialer function called ssrfSafeDialContext. Instead of letting the default dialer resolve the hostname and dial the socket, the custom function handles name resolution directly and filters out private IP addresses before the socket connection is initiated.
// Patched execution path in v3.8.1 implementing ssrfSafeDialContext
func ssrfSafeDialContext(timeout time.Duration) func(ctx context.Context, network, addr string) (net.Conn, error) {
dialer := &net.Dialer{Timeout: timeout}
return func(ctx context.Context, network, addr string) (net.Conn, error) {
// ...
// DNS resolution is performed directly in the dialer
ips, err := net.DefaultResolver.LookupIPAddr(ctx, host)
for _, ipAddr := range ips {
if isPrivateIP(ipAddr.IP) {
continue // Private IPs are explicitly rejected during the connection dial phase
}
// Directly dialing the resolved, validated IP address pins the connection and prevents rebinding
return dialer.DialContext(ctx, network, net.JoinHostPort(ipAddr.IP.String(), port))
}
}
}To execute this exploit, an attacker must configure an authoritative DNS server to handle queries for a target domain under their control. The DNS server is programmed to alternate its responses or use an extremely low Time-To-Live (TTL) of zero seconds. The sequence of DNS resolutions must return a public IP for the first query and a local IP address for the subsequent connection query.
When the victim's AI agent processes an instruction containing a reference to the attacker-controlled domain, the application makes its first query. The DNS server returns a benign public IP address such as 203.0.113.1, which passes the CheckHostSSRF check. Immediately after validation, the HTTP client initiates the connection and issues a second DNS query because the TTL of the first response was set to zero.
The authoritative DNS server responds to this second query with a target internal IP address such as 127.0.0.1 or the link-local metadata IP 169.254.169.254. The Go HTTP client establishes the TCP connection directly to this private IP. This allows the attacker to execute arbitrary HTTP methods against internal API endpoints, loopback web servers, or cloud instance metadata services, completely bypassing firewalls and external boundary protections.
The security impact of this vulnerability is significant, as it transforms a simple personal knowledge application into an initial access vector for local networks. If the SiYuan application is hosted within a cloud computing environment (such as AWS, GCP, or Azure), an attacker can access the Instance Metadata Service (IMDS). Through IMDS access, the attacker can extract sensitive system credentials, service role privileges, and internal configuration details.
On localized deployments, the vulnerability allows the attacker to interact with other containerized services sharing the loopback interface or the internal Docker network. Attackers can issue HTTP requests to internal databases, memory caches, and management dashboards that do not require authentication for local connections. This can lead to database corruption, execution of administrative commands, or exfiltration of sensitive localized data assets.
The vulnerability is assigned a CVSS score of 8.2, reflecting its remote exploitability, low complexity, and high confidentiality impact. Because the vulnerability changes the security scope from the application context to the underlying network environment, it receives a Scope: Changed metric, highlighting its potential to expose adjacent internal network segments.
Remediation of CVE-2026-82234 requires updating the SiYuan Kernel to version 3.8.1 or later. This version replaces the insecure browser HTTP requests with the pinned client architecture that enforces IP validation during the dial context phase. Organizations hosting older versions of SiYuan must isolate the application using strict network segmentation to limit the blast radius of any outbound traffic.
Temporary workarounds include configuring local firewall rules (such as iptables or AWS Security Groups) to block all outbound traffic from the SiYuan server to private subnets or the metadata endpoint (169.254.169.254). Implementing DNS filtering solutions that detect and drop responses containing RFC1918 or loopback addresses (DNS Rebinding protection) can also block this attack vector at the network edge.
Developers should learn from this vulnerability by ensuring that validation and connection phases are structurally linked. Name resolution should occur once, and the validated IP address must be utilized directly to establish the network socket, avoiding any subsequent lookup calls. Implementing a custom dialer context that enforces strict IP range checking during socket creation is the recommended best practice for all Go-based applications handling user-supplied URLs.
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:L/A:N| Product | Affected Versions | Fixed Version |
|---|---|---|
SiYuan siyuan-note | <= 3.8.0 | 3.8.1 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-918 |
| Attack Vector | Network |
| CVSS v3.1 Score | 8.2 (High) |
| EPSS Score | 0.00362 (Percentile: 27.74%) |
| Impact | Confidentiality: High, Scope: Changed |
| Exploit Status | Proof of Concept (PoC) verified |
| CISA KEV Status | Not Listed |
The web application receives a URL from an upstream component or user input, and requests the URL without properly validating that the host resolves to a non-private IP address at connection-time, leaving it vulnerable to DNS rebinding.
A path traversal vulnerability (CWE-22) in Contao CMS allows unauthenticated remote attackers to bypass directory boundary restrictions in ImagesController and access files within the project directory.
Contao Open Source CMS versions 4.0.0 through 5.3.49 and 5.4.0-RC1 through 5.7.11 contain a Cross-Site Request Forgery (CSRF) vulnerability in backend parameter handling. The `RequestTokenListener` component validates anti-CSRF tokens solely for HTTP POST requests, while GET-based declarative guards run only when an `act` parameter is present in the query string. Consequently, custom backend actions dispatched via alternative parameters such as `key=` can execute without CSRF token verification when triggered by an authenticated user.
Contao CMS versions 4.1.0 through 5.3.49 and 5.4.0-RC1 through 5.7.11 fail to validate form submission tokens and enforce rate limiting when processing activation email resend requests via HTTP POST, enabling resource exhaustion and account state enumeration.
An information disclosure vulnerability in Contao CMS allows unauthenticated site visitors to view protected page titles, URLs, and text excerpts through search queries when protected page indexing is disabled after previously being enabled.
In Vikunja prior to version 2.6.0, relation creation via the CalDAV endpoint fails to invoke the TaskRelation.CanCreate authorization check. This missing access control allows an authenticated user to establish unauthorized relationships and perform write operations against any task, provided its unique identifier (UID) is known.
A cross-project information disclosure vulnerability in Vikunja allows authenticated users with read access to one project to view private task details from unauthorized projects via subtask expansion parameters.