The vulnerability exists in the @tinacms/graphql package and is a classic path traversal issue (CWE-22) combined with improper link resolution (CWE-59). The root cause is the assertWithinBase function in packages/@tinacms/graphql/src/database/bridge/filesystem.ts, which was responsible for ensuring that file operations occurred within a designated base directory. This function's validation was purely lexical; it used path.resolve and string comparisons (startsWith) to check for path containment. It failed to account for symlinks or Windows junctions.
An attacker could create a symlink inside the allowed content directory that points to an arbitrary location on the filesystem. When a GraphQL operation (like read, write, or delete) was performed on a path that traversed this symlink, the assertWithinBase check would pass because the lexical path appeared to be within the allowed directory. However, the underlying filesystem operation would follow the symlink, resulting in access to files or directories outside the intended root.
The FilesystemBridge class methods get, put, delete, and glob all relied on this flawed assertWithinBase function for security validation, making them the direct vectors for exploitation. The patch addresses this by modifying assertWithinBase to use fs.realpathSync to resolve the canonical filesystem path of both the target and the base directory, ensuring that the final path is truly contained within the base directory before allowing any I/O operations.