Open-Source Security Intelligence

Know every vulnerability
before it knows you.

DevGuard continuously monitors your dependencies and alerts you when CVEs like this one affect your stack — with real-time threat intelligence built for developers.

Search

GHSA-gj84-924c-48fx

MediumCVSS 4.3 / 10
Published May 20, 2026·Last modified May 20, 2026
Affected Components(0)

No affected components available

Description

Summary

The SSE event server bound to 0.0.0.0:5553 on Linux/macOS by default because the platform-dependent host default in engine/flags.go:39-46 set host = "" for non-Windows, and utils.JoinHostPort("", ":5553") resolves to ":5553" — a Go http.Server.Addr of ":5553" listens on every interface. On Windows the same code chose "localhost", binding loopback only.

The result was a platform split where the OS Algernon's dev workflow is most often used on (Linux/macOS) got the network-exposed default, and only Windows users got the loopback-safe one. A LAN peer with no developer interaction could connect to <dev-laptop-ip>:5553 and read the file-change stream.

This advisory covers the bind-address default in isolation. The fix is independent of authentication (#2a) and CORS (#2b) — switching the default to loopback can be done without touching either.

Details

Root cause — platform-dependent host default in handleFlags

// engine/flags.go:39-46  (1.17.6)
host := ""
if runtime.GOOS == "windows" {
    host = "localhost"
    // Default Bolt database file
    ac.defaultBoltFilename = filepath.Join(serverTempDir, "algernon.db")
    // Default log file
    ac.defaultLogFile = filepath.Join(serverTempDir, "algernon.log")
}
// engine/config.go:388-391  (1.17.6, finalConfiguration)
if ac.eventAddr == "" {
    ac.eventAddr = utils.JoinHostPort(host, ac.defaultEventColonPort)
}

Result tabulated:

| Platform | host | eventAddr after JoinHostPort | Effective bind | |---|---|---|---| | Linux | "" | ":5553" | 0.0.0.0:5553 (all interfaces) | | macOS | "" | ":5553" | 0.0.0.0:5553 (all interfaces) | | Windows | "localhost" | "localhost:5553" | 127.0.0.1:5553 (loopback) |

The same host value also governs the main web server bind, so the platform split affects both ports. The web-server bind on Linux/macOS is a separate (defensible) design decision — a server intended to be reachable; the SSE port is not such a service and inherited the same default by accident.

Why this is an independent finding

The fix is a single line: change the default host value, or change the eventAddr default specifically, to "localhost" regardless of platform. No change to authentication or CORS is required to close the network-reach half of the original bundled advisory. A LAN peer can no longer connect — the listener is unreachable from another host — even if the SSE handler still has no authentication and still returns Allow-Origin: *.

PoC (against 1.17.6 on Linux/macOS)

# Operator's laptop on a hotel/cafe/office WiFi:
algernon -a /path/to/project
# => SSE listener bound to 0.0.0.0:5553

# Any peer on the same subnet:
$ curl -sN http://<dev-laptop-ip>:5553/sse
id: 0
data: /path/to/project/secret-notes.md

id: 1
data: /path/to/project/.env.local

No interaction from the developer is required. The peer needs network reach and nothing else.

Impact

  • Confidentiality: medium. LAN-bounded continuous information disclosure of filenames and edit timing.
  • Integrity: none.
  • Availability: none directly.

The CVSS vector uses AV:A (adjacent network) to model the LAN-only reach. The vector for a misconfigured deployment behind a NAT-less or routed network would shift to AV:N and rise to 5.3.

Suggestions to fix

Primary fix — pick localhost as the SSE default on every platform.

// engine/flags.go -- platform-independent default for the event listener
// (keep the existing platform split for the WEB server if desired, but
// not for the event server)
host := "localhost"

Or, more surgically:

// engine/config.go -- finalConfiguration
if ac.eventAddr == "" {
    ac.eventAddr = utils.JoinHostPort("localhost", ac.defaultEventColonPort)
}

An operator who genuinely wants LAN-reachable SSE can pass --eventserver 0.0.0.0:5553 explicitly and accept the consequences.

Stronger fix — eliminate the second listener entirely. Mount the SSE handler on the main mux at /sse. The bind address is then whatever the main server uses; there is no second listener and therefore no second bind-address default to get wrong.

Live verification

Audit-host bind check (Windows 10):

$ netstat -an | findstr 5553
  TCP    127.0.0.1:5553         0.0.0.0:0              LISTENING

Confirms the Windows default is localhost. The Linux/macOS bind to 0.0.0.0:5553 is documented in the code path above; it was not exercised on the audit machine because the audit host was Windows. A maintainer reproducing on a Linux host would see 0.0.0.0:5553 LISTENING from ss -tlnp.

Risk Scores
Base Score
4.3

The vulnerability can be exploited over a local network, such as Wi-Fi. It is easy for an attacker to exploit this vulnerability. An attacker does not need any special privileges or access rights. No user interaction is needed for the attacker to exploit this vulnerability. The impact is confined to the system where the vulnerability exists. There is a low impact on the confidentiality of the information.

Threat Intelligence
4.0

Exploitation attempts have been detected. Elevated vigilance and prompt remediation are advised.

EPSS
0.20%

The exploit probability is very low. The vulnerability is unlikely to be exploited in the next 30 days.

Exploit
Not available

We did not find any exploit available. Neither in GitHub repositories nor in the Exploit-Database.

Browse More

Scan your project

Continuously monitor your dependencies and get alerted when vulnerabilities like this one affect your stack.

Checkout DevGuard