Node Media Server is an open-source Node.js library that implements an RTMP, RTMPS, HTTP-FLV, and WebSocket-FLV streaming server, and its biggest security risks come from deployment mistakes — unauthenticated publishing, an exposed admin API, and default settings — rather than any single headline bug. If you are standing up node-media-server for live video, the defaults get you streaming quickly, and that speed is exactly what leads teams to ship it wide open.
A media server is a juicy target. It accepts inbound connections, spawns processes for transcoding, serves files, and often runs on a box with generous bandwidth. Each of those is a lever an attacker will pull.
Anyone can publish unless you stop them
By default, an RTMP server will accept a stream published to any application path. Without authentication, a stranger who learns your ingest URL can push their own video into your stream keys, hijacking a broadcast, or simply hammer your transcoder to burn CPU and bandwidth.
Node Media Server supports publish and play authentication using a signed token scheme. Enable it and require a signature on the ingest side:
const NodeMediaServer = require('node-media-server');
const config = {
rtmp: { port: 1935, chunk_size: 60000, gop_cache: true, ping: 30, ping_timeout: 60 },
http: { port: 8000, allow_origin: 'https://app.example.com' },
auth: {
play: true,
publish: true,
secret: process.env.NMS_SECRET, // never hardcode
},
};
new NodeMediaServer(config).run();
With publish: true and a secret, publishers must present a token whose signature and expiry your server validates. Generate short-lived signed URLs server-side per authorized broadcaster; never share a single long-lived key.
Lock down or remove the admin API
Node Media Server exposes an HTTP API and, in some setups, an admin interface for stream stats and control. If that HTTP port is reachable from the internet without authentication, it leaks the list of active streams and, worse, can be used to manipulate sessions. Two rules:
- Bind the HTTP/admin interface to localhost or an internal interface, and put access behind a reverse proxy that enforces authentication.
- Restrict
allow_originto your actual front-end origin instead of the wildcard*, so a random web page cannot script requests against your API from a victim's browser.
If you do not use the admin features, do not expose the port at all.
Path traversal and static file serving
Media servers serve files — recorded segments, HLS playlists, thumbnails. Any time a server maps a request path onto the filesystem, path traversal is a risk: a crafted request with ../ sequences trying to read files outside the media root. This is a general class of bug in HTTP file serving, not unique to any one project. Defend against it by:
- Keeping the media root on its own directory with least-privilege filesystem permissions, so even a traversal cannot reach application secrets.
- Running the process as a non-root, unprivileged user.
- Putting a reverse proxy in front that normalizes and rejects suspicious paths.
I am not citing a specific CVE here because you should not rely on the absence of one — treat filesystem-facing endpoints as hostile input regardless of the current advisory state, and keep the package updated so any disclosed fix reaches you promptly.
Transcoding turns input into code execution risk
If you enable transcoding, Node Media Server shells out to FFmpeg. That means untrusted stream data flows into a media-processing binary, and media parsers are a historically rich source of memory-safety bugs. Mitigations:
- Keep FFmpeg patched; it ships security fixes regularly.
- Never build FFmpeg command arguments by concatenating untrusted stream metadata; pass arguments as an array so nothing is interpreted by a shell.
- Run transcoding in a container or sandbox with constrained CPU, memory, and no network egress it does not need.
Deployment hardening checklist
Put the whole thing behind sensible infrastructure:
- Terminate TLS at a reverse proxy; use RTMPS rather than plain RTMP for ingest where clients support it.
- Rate-limit connections per IP to blunt resource-exhaustion attempts.
- Run as a non-root user inside a container with a read-only root filesystem where possible.
- Store the auth secret in an environment variable or secret manager, never in the committed config.
- Keep node-media-server and its dependencies current, and scan them in CI.
That last point is where supply-chain hygiene meets media serving. node-media-server pulls in a dependency tree, and any of those packages can pick up an advisory over time. An SCA tool will map your installed versions to known advisories, and a tool such as Safeguard can flag a vulnerable transitive dependency before it reaches production. For the broader dynamic-testing angle on an exposed service like this, see our DAST overview.
FAQ
Does Node Media Server require authentication by default?
No. Out of the box it will accept publishing and playback without credentials. You must enable auth with publish and play set and provide a secret, then issue signed, short-lived tokens to authorized clients.
Should I expose the HTTP API to the internet?
No. Bind it to an internal interface and place it behind an authenticating reverse proxy, or do not expose the port at all if you are not using the admin features. Also restrict allow_origin to your real front-end rather than a wildcard.
Is it safe to enable transcoding?
It can be, but transcoding feeds untrusted media into FFmpeg. Keep FFmpeg patched, pass arguments as an array rather than a shell string, and sandbox the transcoding process with resource limits and minimal privileges.
How do I keep node-media-server itself patched?
Pin versions with a committed lockfile, watch the project's releases, and run dependency scanning in CI so newly disclosed advisories in its dependency tree are surfaced automatically.