CVE-2026-105766 Overview
CVE-2026-105766 affects Chainguard Academy (edu), the documentation site operated by Chainguard. The flaw resides in nginx.conf and stems from the use of the backend-facing $scheme variable in a trailing-slash directory redirect. Because TLS terminates at the load balancer in front of Nginx, the $scheme variable resolves to http rather than https. When a client requests a slashless directory path over HTTPS, Nginx returns a 301 response that redirects the client to a plaintext http:// URL. An on-path network attacker can then read or modify the documentation content delivered to the victim.
Critical Impact
Clients that do not enforce HTTP Strict Transport Security (HSTS), such as command-line HTTP clients and automation scripts that follow redirects, can be downgraded to plaintext and intercepted on the network path.
Affected Products
- Chainguard Academy (edu) repository chainguard-dev/edu
- Commits from 0b75ff98057f69b044a3e7194e428066ac5ad0d4 up to (but not including) 93dc0e50739c225f5aee2e803800a47fc0feb906
- Non-HSTS clients consuming the site (CLI HTTP clients, scripts following redirects)
Discovery Timeline
- 2026-10-05 - CVE-2026-105766 published to the National Vulnerability Database (NVD)
- 2026-10-06 - Last updated in NVD database
Technical Details for CVE-2026-105766
Vulnerability Analysis
The vulnerability is a cleartext transmission issue classified as [CWE-319]. The Chainguard Academy site runs behind a load balancer that terminates TLS before forwarding requests to Nginx. In this topology, the Nginx $scheme variable reflects the backend-facing connection scheme (http), not the client-facing scheme (https). When Nginx issues a 301 directory redirect built from $scheme, the resulting Location header points to an http:// URL. A client that follows the redirect without enforcing HSTS will downgrade to plaintext for the follow-up request.
Browsers that honor the HSTS preload list are not exposed, because .dev is a preloaded top-level domain and the browser rewrites http:// to https:// before issuing the request. Non-browser clients, such as curl, wget, package installers, or CI/CD scripts, typically do not consult the preload list and will issue the downgraded request as directed.
Root Cause
The root cause is the use of $scheme in a redirect generated behind a TLS-terminating proxy. $scheme is populated from the connection Nginx itself receives, not from the original client request. Without consulting a forwarded header such as X-Forwarded-Proto, Nginx cannot reconstruct the client's original scheme and emits a plaintext redirect.
Attack Vector
Exploitation requires an on-path network attacker between the victim and the load balancer, plus a victim client that does not enforce HSTS. The attacker waits for the victim to request a slashless directory path (for example https://edu.chainguard.dev/some/path), observes the 301 response pointing to http://edu.chainguard.dev/some/path/, and intercepts or modifies the subsequent plaintext request. The attacker can then rewrite documentation content, inject malicious commands into copy-paste instructions, or harvest request metadata.
The upstream fix in commit 93dc0e50739c225f5aee2e803800a47fc0feb906 addresses adjacent redirect handling in nginx.conf and layouts/index.aliases. A representative excerpt of the patched redirect map logic is below:
+ # Key the redirect map on the request path with the query string removed.
+ # $request_uri carries the query, and nearly every rule below ends in $1,
+ # so matching $request_uri put the query inside $redirect_url -- and the
+ # rewrite that applies the map appends the request arguments again,
+ # emitting "?utm_source=x?utm_source=x" (DOCS-187). A query-free key keeps
+ # $redirect_url query-free, so the append becomes the only source of a
+ # query on the Location, and it lands exactly once.
+ map $request_uri $request_path {
+ "~^(?<path_without_query>[^?]*)" $path_without_query;
+ }
+
# add URLs after the `default` line that are moved and aren't redirecting via Hugo aliases
- map $request_uri $redirect_url {
+ map $request_path $redirect_url {
default "";
Source: GitHub Commit 93dc0e5
Detection Methods for CVE-2026-105766
Indicators of Compromise
- 301 responses from edu.chainguard.dev whose Location header begins with http:// instead of https://.
- Outbound plaintext HTTP requests from automation or CI runners to edu.chainguard.dev immediately following an HTTPS request to the same host.
- Unexpected content differences in documentation payloads retrieved by non-browser clients compared to the canonical HTTPS source.
Detection Strategies
- Inspect HTTP response headers at egress proxies for 301 redirects that downgrade scheme from https to http on known documentation hosts.
- Compare build and CI logs for curl/wget invocations against edu.chainguard.dev that resolve to http:// after redirect following.
- Alert on TLS-to-plaintext transitions in network session metadata when the originating hostname is on a preload-listed TLD.
Monitoring Recommendations
- Enable network telemetry collection for CI/CD runners and developer workstations that regularly fetch external documentation.
- Centralize egress HTTP logs so plaintext requests to .dev hosts can be queried and reviewed over time.
- Track script and installer commands that pipe remote content directly into shells (for example curl | sh) and flag any that resolve through an http:// hop.
How to Mitigate CVE-2026-105766
Immediate Actions Required
- Pull the latest chainguard-dev/edu content at or after commit 93dc0e50739c225f5aee2e803800a47fc0feb906 if operating a fork or mirror.
- Audit CI/CD pipelines, container builds, and scripts that fetch resources from edu.chainguard.dev without HSTS enforcement and force https:// URLs explicitly.
- Configure HTTP clients used in automation to refuse plaintext redirects (for example curl --proto '=https' --proto-redir '=https').
Patch Information
The issue is addressed in commit 93dc0e50739c225f5aee2e803800a47fc0feb906 of the chainguard-dev/edu repository. Review GitHub Pull Request 3989 for the full discussion and the patch commit for the applied changes to nginx.conf and layouts/index.aliases.
Workarounds
- Replace $scheme in redirect directives with a literal https or with a value derived from the X-Forwarded-Proto header set by the load balancer.
- Always request trailing-slash directory URLs directly from automation to avoid triggering the 301 redirect.
- Pin clients to HTTPS-only mode and reject any redirect that changes scheme from https to http.
# Nginx configuration example: derive client scheme from X-Forwarded-Proto
map $http_x_forwarded_proto $client_scheme {
default $scheme;
https https;
}
server {
listen 8080;
server_name edu.chainguard.dev;
# Issue trailing-slash directory redirects using the client-facing scheme
location ~ ^(?<dir>/.+[^/])$ {
if (-d $document_root$dir) {
return 301 $client_scheme://$host$dir/;
}
}
}
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

