Skip to content

HTTP notification listener accepts unauthenticated requests (DoS + client ID enumeration) #601

@Ryujiyasu

Description

@Ryujiyasu

Summary

The Fleetspeak HTTP notification listener accepts POST /client/<clientID> from any source with zero authentication, no TLS, and no IP filtering.

Vulnerable Code

File: fleetspeak/src/server/components/notifications/http.go:79-110

func (l *HttpListener) runServer() {
    err := http.Serve(l.listener, http.HandlerFunc(l.handle))
}

func (l *HttpListener) handle(w http.ResponseWriter, r *http.Request) {
    dir, name := path.Split(r.URL.EscapedPath())
    if dir != "/client/" {
        http.Error(w, "not found", http.StatusNotFound)
        return
    }
    id, err := common.StringToClientID(name)
    if err != nil { ... }
    l.out <- id   // triggers pending message delivery to this agent
    w.WriteHeader(http.StatusOK)
}

This endpoint is the cross-server notification channel: in multi-server deployments, one Fleetspeak server POSTs to another's notification port to signal that pending messages exist for a given client. It is served over plain HTTP with http.Serve — no TLS, no token, no IP allowlist enforcement in the code.

Impact

  1. DoS via amplification: Any caller can trigger repeated delivery attempts for any client ID, causing the server to repeatedly query the database for pending messages
  2. Client ID enumeration (timing oracle): Triggering a wake-up for a valid client ID causes different internal behavior than an invalid one
  3. Notification poisoning in multi-server deployments: An attacker on the internal network can disrupt the notification dispatch system by sending spurious wake-ups

The source code comment says this port "should not be exposed to the public" — but there is no code-level enforcement.

Suggested Fix

Add authentication (e.g., a shared secret/token header) and/or IP allowlist validation to the HTTP notification listener.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions