Pusher-compatible REST API, Body MD5 Not Verified Replay/Body Substitution, CVE: N/A (Critical) -DC-Sep2026-2489

Listen to this Post

The Pusher-compatible REST API signs requests using HMAC.

The signed string includes auth_key, auth_timestamp, auth_version, body_md5, and auth_signature.
In pusher/http.go, Handler extracts body_md5 from URL query string.

This happens at line 169.

Handler includes body_md5 verbatim in stringToSign at line 175.

It verifies HMAC(stringToSign, secret) equals auth_signature.

The server never computes MD5 of received HTTP body.

It never compares computed md5(body) to signed body_md5.

After HMAC verification succeeds, handleEvents reads r.Body at lines 201-212.

handleEvents parses the body without body digest validation.

Pusher protocol requires server-side body_md5 verification.

This requirement prevents body-substitution attacks.

Because body_md5 is only signed, not checked, body can be replaced.
An attacker who observes one signed request can reuse its query string.
The original auth_signature remains valid for the modified body.

There is also no auth_timestamp staleness check.

Replays remain valid indefinitely.

A legitimate POST targets /apps//events.

Query includes auth_key=K, auth_timestamp=T, auth_version=1.0.

Query includes body_md5=LEGIT_MD5 and auth_signature=SIG.

Original body carries {“name”:”safe-event”,”channel”:”ch”,”data”:”…”}.

Attacker sends same query string parameters.

Attacker changes body to {“name”:”injected-event”,”channel”:”admin”,”data”:”malicious-payload”}.

Server accepts request because HMAC over stringToSign matches original.
Server broadcasts injected event to all subscribers of admin.

Attacker can read signed requests from logs.

Attacker can read from shared proxy or network tap.

Impact includes arbitrary events to any channel indefinitely.

Impact includes forged server-side events and corrupted application state.

Impact includes phishing messages to WebSocket clients.

DailyCVE Form:

Platform: Pusher-compatible REST API
Version: Not specified
Vulnerability: body_md5 not verified
Severity: Critical
date: Not specified

Prediction: Unknown patch date

(end of form)

What Undercode Say:

Analytics:

grep -n "body_md5|auth_timestamp|auth_signature|stringToSign" pusher/http.go
sed -n '160,215p' pusher/http.go
openssl dgst -md5 <<< '{"name":"safe-event","channel":"ch","data":"..."}'
curl -X POST 'https://target/apps/APP_ID/events?auth_key=K&auth_timestamp=T&auth_version=1.0&body_md5=LEGIT_MD5&auth_signature=SIG' \
-H 'Content-Type: application/json' \
-d '{"name":"injected-event","channel":"admin","data":"malicious-payload"}'
body, _ := io.ReadAll(r.Body)
sum := md5.Sum(body)
expected := hex.EncodeToString(sum[:])
if subtle.ConstantTimeCompare([]byte(expected), []byte(r.URL.Query().Get("body_md5"))) != 1 {
http.Error(w, "invalid body_md5", http.StatusUnauthorized)
return
}
ts, _ := strconv.ParseInt(r.URL.Query().Get("auth_timestamp"), 10, 64)
if time.Since(time.Unix(ts, 0)) > 600time.Second {
http.Error(w, "stale auth_timestamp", http.StatusUnauthorized)
return
}

Exploit: (Educational Purposes!)

curl -X POST 'https://target/apps/APP_ID/events?auth_key=K&auth_timestamp=T&auth_version=1.0&body_md5=LEGIT_MD5&auth_signature=SIG' \
-H 'Content-Type: application/json' \
-d '{"name":"safe-event","channel":"ch","data":"..."}'
curl -X POST 'https://target/apps/APP_ID/events?auth_key=K&auth_timestamp=T&auth_version=1.0&body_md5=LEGIT_MD5&auth_signature=SIG' \
-H 'Content-Type: application/json' \
-d '{"name":"injected-event","channel":"admin","data":"malicious-payload"}'

Protection: from this CVE

body, err := io.ReadAll(r.Body)
if err != nil {
http.Error(w, "read error", http.StatusBadRequest)
return
}
sum := md5.Sum(body)
expected := hex.EncodeToString(sum[:])
if subtle.ConstantTimeCompare([]byte(expected), []byte(r.URL.Query().Get("body_md5"))) != 1 {
http.Error(w, "invalid body_md5", http.StatusUnauthorized)
return
}
ts, err := strconv.ParseInt(r.URL.Query().Get("auth_timestamp"), 10, 64)
if err != nil || time.Since(time.Unix(ts, 0)) > 600time.Second {
http.Error(w, "stale auth_timestamp", http.StatusUnauthorized)
return
}

Impact:

An attacker who can read any single signed Pusher API request can broadcast arbitrary events to any channel indefinitely, potentially forging server-side events, corrupting application state, or delivering phishing messages to WebSocket clients.

🎯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

🔐JOIN OUR CYBER WORLD [ CVE News • HackMonitor • UndercodeNews ]

💬 Whatsapp | 💬 Telegram

📢 Follow DailyCVE & Stay Tuned:

𝕏 formerly Twitter 🐦 | @ Threads | 🔗 Linkedin Featured Image

Scroll to Top