Path filters that do not filter: CVE-2026-57441 and CVE-2026-57442 in MCPVault
MCPVault restricts which directories a language model can read. Two advisories describe ways past those restrictions, and both turn on how the code compares a path rather than on a missing check. CVE-2026-57441 carries a CVSS score of 8.4, and CVE-2026-57442 carries 6.9.
CVE-2026-57441: the case that a string comparison misses
The restriction in MCPVault is implemented as two functions, isAllowed() and isAllowedForListing(). Both decide whether a path is permitted, and both compare the path as a string.
On a case-insensitive filesystem, that comparison produces a different answer than the filesystem does. The advisory gives the example of a path that contains a case variant of .git, .obsidian or node_modules. The variant does not match the deny entry in the string comparison, so both functions return that the path is allowed. The filesystem then resolves the variant to the same directory the deny list was meant to protect. The restriction is present in the code and absent in effect.
CVE-2026-57442: the deny list anchored at the root
The second issue concerns a deny list that matches only at the root of the tree. The advisory describes nested .git or .obsidian directories that the anchored pattern does not match. Where a repository or a vault contains a nested working directory, a path through it passes the check.
This is a simpler failure than the first, and it is more common. A pattern written against the visible layout of a project stops matching as soon as the layout contains a directory the author did not picture.
Why these are one class
Both advisories describe a check written against the representation of a path rather than against the resolved path. The representation is a string, and the string is interpreted later by a filesystem whose rules, on a case-insensitive volume, are not the rules the string comparison uses.
The same shape appears elsewhere in the disclosure window. CVE-2026-73496 concerns an Atlassian MCP attachment file_path that is not confined to the intended directory, and the mcp-gitlab advisories describe an upload_markdown parameter that reached /proc/self/environ. The consistent finding is that a path parameter is an input and requires the same treatment as any other input.
The fix pattern
Path confinement done correctly follows a short sequence. Resolve the path to its absolute, canonical form with the filesystem's own resolution rules. Compare that resolution against the allowed root, using a boundary-aware comparison rather than a prefix check on a string. Re-resolve after following any symlink, since the target of a link is what the filesystem will open. And perform the check at the point of use rather than earlier in the pipeline, so that a path that changes between validation and access is caught.
A deny list is the weaker construction of the two. An allow list of directories is easier to reason about because it does not depend on enumerating what should be excluded, and the enumeration is where both advisories found their gap.
For operators running MCP file tools
Upgrade to the versions named in the advisories. Then reduce the value of the boundary so that a future bypass reaches less. Run the server as a user that can read only the directories the integration requires, rather than as the developer's own account. Keep credentials out of the process environment, since a file read that reaches the process environment is a credential read on most Linux systems. And where the integration supports a read-only mode, use it, because a read of an unintended file is a smaller problem than a write to one.
The two advisories are a reminder that a filter is a control only after it has been tested against the filesystem it runs on.
References
- Freebuf analysis covering CVE-2026-57441 and CVE-2026-57442: https://www.freebuf.com/articles/ai-security/501022.html
- MCPVault project repository: https://github.com/bitbonsai/mcpvault
- National Vulnerability Database: https://nvd.nist.gov/
Top comments (0)