I reviewed Lumiverse, a self-hosted AI chat app, and found five vulnerabilities. Two could be chained together for unauthenticated RCE. A registration race condition let an attacker create an account without administrator approval. That account had enough access to exploit the Model Context Protocol (MCP) vulnerability and run code on the server.
Remote code execution through MCP
Any logged-in user could run code on the Lumiverse server through its MCP integration. With the stdio transport, Lumiverse launches a local tool as a subprocess and communicates with it over standard input and output.
Lumiverse checked the executable against an allowlist and passed the arguments through without any checks. The allowlist included Node.js (node), which can execute JavaScript supplied as an argument. A regular user could configure an MCP tool and run code with the permissions of the Lumiverse server process. That could expose saved chats, uploads, and other files the process could read. The fix restricted the arguments Lumiverse accepts when launching tools.
Registration race condition
Lumiverse restricted account creation to administrators. The registration check looked for a valid authorization token without checking whether it belonged to the request being processed. While an administrator’s token was valid, the check could accept another user’s registration. The fix bound the token to the administrator’s request.
Registration was the timing-dependent part of the chain. Once the attacker had a valid session, regular user permissions were enough for the MCP bug.
Sandbox escape with custom TSX components
Lumiverse used a custom sandbox to run React components written in TSX. It blocked direct access to window while exposing DOM elements that could reach it. A malicious component could therefore make authenticated requests as the user who enabled it.
Custom components in imported themes were disabled by default, so the user had to enable one for the code to run. The fix added a validator that parses the TSX and checks its syntax tree.
Code execution during extension installation
Spindle, Lumiverse’s extension system, ran bun install before scanning the extension’s backend bundle. Bun could execute package lifecycle scripts during installation, so a malicious extension could run code on the server before the scan started. Spindle used the same sequence on updates.
The fix changed dependency installation to bun install --ignore-scripts.
Command injection in SMB migration
Lumiverse used smbclient to check whether files existed on a network share. In one fallback, it split the path into a directory and filename, validated the directory, and inserted the unchecked filename into a command string. smbclient interpreted that string as commands, which let the filename change what ran on the host.
The affected operation required an owner or administrator and a host with smbclient installed. The fix added filename validation to the fallback.
Disclosure timeline
| Date | Event |
|---|---|
| I reported the five vulnerabilities to the Lumiverse maintainers. | |
| The maintainers acknowledged the report. | |
| GitHub published the five security advisories. |
The advisories list versions through 0.9.5 as affected and 0.9.7 as the fixed release. Thanks to Prolix for the quick response and fixes. Lumiverse security advisories
Lessons learned
- Validate every part of the input a command interprets. An executable allowlist leaves the arguments to review. Apply the same validation on fallback paths.
- Review what code can access from the moment it runs. A scan that runs after installation can miss code that already executed. A browser sandbox has to account for what components can reach through the objects it exposes.
Reviewing AI-generated code
Review the full diff against the task you gave the AI. Check that it solves the problem and follows the project’s conventions. If it adds a dependency, verify the package and check whether the project already has what it needs.
Run the existing tests and use static analysis in CI to catch common issues. CodeQL is one option for security scanning. Read any test changes as part of the review. If the AI rewrote a failing test, check that the new assertions still enforce the original requirement.