Back to Blog
critical SEVERITY3 min read

Music Studio App Express Server: CWE-287 Authentication Bypass via

A critical authentication bypass vulnerability in a music studio application's Express server allowed remote attackers to access API endpoints despite the intended localhost-only restriction. The localRequest middleware validated the Host header but failed to verify the actual remote socket address, enabling trivial bypasses in containerized and multi-user environments.

O
By Orbis AppSec
•Technically reviewed by Anupam Mediratta•Published October 8, 2026•Reviewed October 8, 2026

Answer Summary

The music studio application's Express server in server/app.mjs used a localRequest middleware that only validated the Host header against localhost patterns, without checking req.socket.remoteAddress. An attacker could bypass this restriction by sending a crafted Host header while connecting from any remote IP address, gaining unauthorized access to song management and voice-kit API endpoints. The fix adds explicit remote address validation against 127.0.0.1, ::1, and ::ffff:127.0.0.1 before Host header checks. CWE-287 (Improper Authentication).

Vulnerability at a Glance

cweCWE-287 (Improper Authentication)
fixAdded req.socket.remoteAddress whitelist check before Host header validation
riskRemote unauthorized access to local-only API endpoints
languageJavaScript (Node.js/Express)
root causeHost header validation without socket remote address verification
vulnerabilityAuthentication Bypass

Affected Versions

Affected not applicable (first-party code)
Fixed in not applicable (first-party code) — see PR for fix commit
Ecosystem N/A
CVE / GHSA not assigned
CWE CWE-287 (Improper Authentication)

The Vulnerability Explained

The music studio application deployed an Express server with a localRequest middleware designed to restrict API access to localhost connections only. The intended security model was simple: if you're not connecting from the same machine, you shouldn't access song storage or voice-kit endpoints.

The original implementation validated only the HTTP Host header:

function localRequest(req, res, next) {
  const host = req.headers.host;
  if (!host || !/^(localhost|127\.0\.0\.1|\[::1\])(?::[0-9]{1,5})?$/.test(host)) {
    return res.status(403).json({ error: '只接受本机地址访问' });
  }
  // ... continues to protected routes
}

The critical flaw: HTTP headers are attacker-controlled. The Host header is supplied by the client and can be set to localhost or 127.0.0.1 regardless of the actual TCP connection origin. The middleware never verified req.socket.remoteAddress, which reflects the actual network-layer source address.

An attacker could exploit this by:
1. Connecting to the exposed server from any remote IP address
2. Sending Host: localhost or Host: 127.0.0.1:3000 in the HTTP request
3. Passing the regex validation and gaining full API access

This bypass is particularly dangerous in containerized deployments (Docker, Kubernetes) where "localhost" inside a container is distinct from the host's localhost, and in multi-user systems where network namespaces might be shared.

The Fix

The patch adds explicit socket-level remote address validation before the Host header check:

function localRequest(req, res, next) {
  const remote = req.socket?.remoteAddress;
  if (!remote || !['127.0.0.1', '::1', '::ffff:127.0.0.1'].includes(remote)) {
    return res.status(403).json({ error: '只接受本机地址访问' });
  }
  const host = req.headers.host;
  if (!host || !/^(localhost|127\.0\.0\.1|\[::1\])(?::[0-9]{1,5})?$/.test(host)) {
    return res.status(403).json({ error: '只接受本机地址访问' });
  }

The fix introduces a defense-in-depth approach:

  1. Socket address validation first: req.socket.remoteAddress is kernel-provided and cannot be forged by HTTP header manipulation. The whitelist covers IPv4 localhost (127.0.0.1), IPv6 localhost (::1), and the IPv4-mapped IPv6 form (::ffff:127.0.0.1) that Node.js commonly reports.

  2. Preserved Host header check: The original validation remains as a secondary check, catching edge cases where socket address might be misleading (though unlikely for localhost).

  3. Early return: Both checks fail fast with the same 403 response, preventing any downstream middleware or route handlers from executing on unauthorized requests.

Key Takeaways

  • Never trust HTTP headers for security decisions about connection origin: The Host header, X-Forwarded-For, and similar headers are client-supplied and trivially spoofed. Always validate req.socket.remoteAddress or equivalent kernel-reported addresses for localhost restrictions.
  • IPv6 has multiple localhost representations: The fix must account for ::1, ::ffff:127.0.0.1, and potentially 127.0.0.0/8 variants. Node.js's representation varies by binding configuration.
  • "Local-only" applications often escape their boundaries: Container networking, reverse proxies, and development tunnels can expose supposedly local services. Design authentication mechanisms that survive these transitions.
  • Middleware ordering matters: The localRequest validation runs before route handlers, but if any earlier middleware (error handlers, logging) executes first, it might leak information or accept malformed requests.

How Orbis AppSec Detected This

Source: The req.headers.host HTTP request parameter (attacker-controlled header)

Sink: The localRequest middleware function that gates access to createSongStore and mountVoiceKit API endpoints

Missing control: No validation of req.socket.remoteAddress before processing the request; the middleware relied solely on forgeable Host header pattern matching

CWE: CWE-287 — Improper Authentication

Fix: Added explicit whitelist check of req.socket.remoteAddress against ['127.0.0.1', '::1', '::ffff:127.0.0.1'] before Host header validation

Orbis AppSec automatically detected this vulnerability and opened a pull request with the fix. Try Orbis AppSec on your repositories to find and fix issues like this automatically.

Conclusion

This vulnerability demonstrates how a seemingly robust localhost restriction can collapse when implemented at the wrong abstraction layer. The original localRequest middleware looked correct—until you realize it validates user input rather than network reality. For applications designed to run locally, the req.socket.remoteAddress check added in this fix provides the actual security boundary that HTTP headers cannot.

Prevention and further reading

Frequently Asked Questions

Why did the original localRequest middleware check the Host header but not req.socket.remoteAddress?

The implementation assumed that a localhost Host header implied a localhost connection, but HTTP clients can set arbitrary Host headers regardless of actual network origin, making this check bypassable.

What addresses does the fixed localRequest middleware explicitly whitelist?

The fix validates req.socket.remoteAddress against 127.0.0.1, ::1, and ::ffff:127.0.0.1 before proceeding to Host header validation, closing the bypass vector.

Does the error message "只接受本机地址访问" indicate this was designed for Chinese-language deployments?

The error message is in Chinese, suggesting the application was intended for Chinese-speaking users or deployments, but the vulnerability affects all deployments regardless of locale.

View the Security Fix

Check out the pull request that fixed this vulnerability

View PR #1

Related Articles

high

CVE-2026-104850: MCP TypeScript SDK OAuth Credential Leak

The MCP TypeScript SDK (`@modelcontextprotocol/sdk`) contained a flaw in its OAuth client flow where the MCP server being connected to could influence which authorization server the client talked to, meaning client credentials and token-exchange traffic could be directed to an endpoint the attacker controls. This project was pinned to the affected `1.30.0`; the dependency has been moved to `^1.31.0`, which carries the upstream fix for CVE-2026-104850. Any MCP client that performs OAuth against t

high

SQLite Auth Database Plaintext Storage in InitAuthDB()

The `InitAuthDB()` function opened SQLite databases without restricting filesystem permissions, leaving bcrypt password hashes, session tokens, and user settings exposed to any local account with read access. The fix explicitly sets `os.Chmod(filepath, 0600)` immediately after database creation, ensuring only the owner can access authentication secrets.

high

undici 8.10.0 Cache Poisoning: CVE-2026-85152 Auth Bypass

undici, the HTTP client used by Node.js's `fetch()` implementation, shipped a caching layer that did not properly isolate cached responses by origin, letting a response poisoned on one origin be served to requests for another. This created a path to cross-origin authentication bypass, tracked as CVE-2026-85152 and fixed in undici 8.10.2.

critical

Hybridauth Telegram OAuth Timing Attack in `authenticateCheckError()`

The Telegram OAuth provider in Hybridauth relied on `strcmp()` to validate HMAC-SHA256 signatures, exposing a timing side-channel that could allow attackers to forge authentication tokens character by character. The fix replaces this with PHP's timing-safe `hash_equals()` function, eliminating the information leak.

critical

Node.js Auth Query SQL Injection via Group Code Interpolation

A sign-in authorization check built its SQL query by mapping an `authorizedGroups` array into quoted string literals and joining them directly into a template literal, creating a classic SQL injection point in a critical authentication path. The fix replaces every interpolated value — including the previously "typed" parameter — with `?` placeholders bound through a value-builder helper, closing off the injection vector entirely.

critical

proxy-addr 2.0.7 IP Spoofing: CVE-2026-90711 Trust Bypass

A critical vulnerability in proxy-addr 2.0.7 allowed attackers to spoof client IP addresses by manipulating X-Forwarded-For headers when the trust chain evaluation contained specific misconfigurations. The fix in version 2.0.8 hardens the trust evaluation logic to prevent IP address falsification in Express.js applications relying on this common middleware dependency.