@@ -58,6 +58,62 @@ func TestFilesystemTool_IsPathAllowed(t *testing.T) {
5858 assert .Contains (t , err .Error (), "not within allowed directories" )
5959}
6060
61+ // TestFilesystemTool_IsPathAllowed_SiblingDirectories tests the fix for issue #1076
62+ // It verifies that sibling directories with similar names don't bypass the allow-list
63+ func TestFilesystemTool_IsPathAllowed_SiblingDirectories (t * testing.T ) {
64+ t .Parallel ()
65+
66+ // Create a temporary directory structure:
67+ // - tmpRoot/project (allowed)
68+ // - tmpRoot/project-secrets (should NOT be allowed)
69+ // - tmpRoot/project2 (should NOT be allowed)
70+ // - tmpRoot/projectx (should NOT be allowed)
71+ tmpRoot := t .TempDir ()
72+
73+ projectDir := filepath .Join (tmpRoot , "project" )
74+ projectSecretsDir := filepath .Join (tmpRoot , "project-secrets" )
75+ project2Dir := filepath .Join (tmpRoot , "project2" )
76+ projectXDir := filepath .Join (tmpRoot , "projectx" )
77+
78+ require .NoError (t , os .Mkdir (projectDir , 0o755 ))
79+ require .NoError (t , os .Mkdir (projectSecretsDir , 0o755 ))
80+ require .NoError (t , os .Mkdir (project2Dir , 0o755 ))
81+ require .NoError (t , os .Mkdir (projectXDir , 0o755 ))
82+
83+ // Only allow the "project" directory
84+ tool := NewFilesystemTool ([]string {projectDir })
85+
86+ // Test that subdirectories of allowed directory are accessible
87+ allowedSubdir := filepath .Join (projectDir , "src" , "main.go" )
88+ err := tool .isPathAllowed (allowedSubdir )
89+ require .NoError (t , err , "Subdirectories of allowed directory should be accessible" )
90+
91+ // Test that the allowed directory itself is accessible
92+ err = tool .isPathAllowed (projectDir )
93+ require .NoError (t , err , "Allowed directory itself should be accessible" )
94+
95+ // Test that sibling directories with similar names are NOT accessible
96+ siblingTests := []struct {
97+ name string
98+ path string
99+ }{
100+ {"project-secrets" , filepath .Join (projectSecretsDir , "confidential.txt" )},
101+ {"project2" , filepath .Join (project2Dir , "file.txt" )},
102+ {"projectx" , filepath .Join (projectXDir , "file.txt" )},
103+ {"project-secrets dir" , projectSecretsDir },
104+ {"project2 dir" , project2Dir },
105+ {"projectx dir" , projectXDir },
106+ }
107+
108+ for _ , tc := range siblingTests {
109+ t .Run (tc .name , func (t * testing.T ) {
110+ err := tool .isPathAllowed (tc .path )
111+ require .Error (t , err , "Sibling directory %s should NOT be accessible" , tc .name )
112+ assert .Contains (t , err .Error (), "not within allowed directories" )
113+ })
114+ }
115+ }
116+
61117func TestFilesystemTool_WriteFile (t * testing.T ) {
62118 t .Parallel ()
63119 tmpDir := t .TempDir ()
0 commit comments