Path Traversal in React Router/Remix createFileSessionStorage
CVE-2025-61686 is a path traversal issue affecting @react-router/node versions 7.0.0 through 7.9.3, @remix-run/node prior to 2.17.2, and @remix-run/deno prior to 2.17.2. When createFileSessionStorage() is used with an unsigned cookie, attacker-controlled session data can cause the application to attempt to read from or write to filesystem locations outside the configured session file directory. Exploitation depends on the filesystem permissions of the web server process. File contents are not directly returned to the attacker, and read operations only succeed in a meaningful way if the targeted file matches the expected session file format. If such a file is successfully parsed, its data is loaded into the server-side session and may become exposed only if the application later returns session-derived values.
Are you exposed to this one?
Mallory correlates every CVE against your assets, your vendors, and active adversary campaigns. Know which vulnerabilities matter for you, not just which ones are loud.
Impact, mitigation & remediation
What it means. What to do now. Patch path, mitigations, and the assume-compromise checklist.
Impact
What an attacker gets, and what they’ve been doing with it.
Mitigation
If you can’t patch tonight, do this now.
Remediation
Patch, then assume compromise.
Exploits
3 valid exploits after Mallory filtered fakes, detection scripts, and README-only repos.
Repository purpose: a PoC for CVE-2025-61686 demonstrating an arbitrary file read/path traversal condition in @react-router/node's createFileSessionStorage when the session cookie value can be attacker-controlled. Structure and key files: - server.js: Minimal Express server on port 3005 that initializes createFileSessionStorage with dir=./sessions and cookie name 'session'. On GET / it calls storage.getSession(cookieHeader) and returns session.id and session.data. On error it returns HTTP 500 with {error: error.message}, which can leak parsing details. - exploit.js: Sends a single HTTP request to localhost:3005/ with a crafted Cookie header. The cookie value is base64(JSON.stringify(traversalId)) where traversalId is '../../../../../../etc/passwd'. Comments explain a path-joining quirk (splitting '..' via slicing) that reduces effective traversal depth. - exploit-2.js: Similar request, but expects the server to attempt JSON.parse on the loaded file content; it then parses the returned JSON error message and uses regexes to extract the embedded file content from the "Invalid JSON" / "Unexpected token" error text. - secret_session / secret_session.json: Sample artifacts containing a mock secret flag, likely to illustrate what a session file might look like. - package.json / package-lock.json: Node project dependencies (notably @react-router/node 7.0.0, express 5.2.1). Exploit capability details: - Primary capability is arbitrary file read via path traversal by embedding traversal sequences in the session identifier carried in the 'session' cookie. - exploit.js is closer to a confirmation PoC (may only yield a 500 and error due to JSON.parse failing on non-JSON files). - exploit-2.js attempts to turn the JSON.parse failure into an information disclosure by extracting file bytes echoed inside the error message, effectively upgrading confirmation into content exfiltration when the runtime includes offending input in parse errors. No evidence of RCE, persistence, or lateral movement is present; the code is narrowly focused on file read/verification against a local test server.
Repository is a CVE demo/PoC for CVE-2025-61686 affecting @react-router/node file-based session storage when cookies are unsigned (no `secrets`). Structure: top-level README.md provides a detailed vulnerability write-up (cookie decoding, getFile() path join behavior, and impacts: read/write/delete). The `vulnerable-app/` directory contains a runnable Dockerized Express server (`server.js`) intentionally configured with `createFileSessionStorage({dir:'/tmp/sessions', cookie:{name:'__session'}})` without secrets, plus a Node PoC client (`exploit.js`) that crafts base64(JSON.stringify(sessionId)) cookies and sends GET requests to `/profile` to confirm the server accepts attacker-controlled session IDs and to illustrate path resolution escaping `/tmp/sessions`. Dockerfile/docker-compose/quick-start.sh provide an easy lab environment; the server also creates demo sensitive files `/tmp/secret.txt` and `/tmp/config.json` to show potential traversal targets. The PoC primarily verifies the condition (server accepts malicious session IDs) and demonstrates path traversal feasibility; it does not implement a full arbitrary file read exfiltration beyond the server’s reflected sessionId behavior.
Repository is a minimal Docker-based reproduction lab/PoC for CVE-2025-61686 affecting @react-router/node file session storage (notably version 7.9.3). Structure: (1) docker-compose.yml builds and exposes a single Node service, mapping host 3001->container 3000 and bind-mounting ./vulnerable/sessions to /app/sessions. (2) vulnerable/Dockerfile builds a Node 20 image, installs dependencies, and runs server.js. (3) vulnerable/server.js starts an HTTP server and uses createFileSessionStorage({dir:'./sessions', cookie:{name:'session', secrets:[]}}). The empty secrets array makes the session cookie unsigned for demonstration, enabling an attacker to supply an arbitrary session id. The underlying vulnerable logic (described in README) splits the session id into a subdirectory (first 4 chars) and filename (rest) via path.join(dir, id.slice(0,4), id.slice(4)); if the remainder contains '../' sequences, path.join resolves a path outside the intended sessions directory, enabling directory traversal in session file operations. README provides a working example: base64url-encode a JSON string like "AAAA../../../tmp/flower", place it in the Cookie: session=..., request http://localhost:3001/, and observe a file created/accessible under /tmp/flower in the container. This repo is a PoC/lab (no weaponized payload beyond demonstrating traversal).
Affected products & vendors
Products and vendors Mallory has correlated with this vulnerability. Open in Mallory to drill down to specific CPE configurations and version ranges.
Vendor-confirmed product mapping. Mallory continuously reconciles this list against your asset inventory.
Recent activity
17 sources tracked across advisories, community write-ups, and news. New activity surfaces here as Mallory finds it.
The version that knows your environment.
Query your assets running an affected version, and investigate the blast radius.
Every observed campaign linking this CVE to a named adversary.
Malware families riding this exploit, with evidence and IOCs.
YARA, Sigma, Snort, and vendor rules, auto-deployed to your SIEM.
Cross-references every affected SKU, including bundled OEM variants.
Community discussion across Reddit, Mastodon, and other social sources.