@@ -27,6 +27,7 @@ import (
2727 "github.com/arduino/arduino-create-agent/gen/indexes"
2828 "github.com/arduino/arduino-create-agent/gen/tools"
2929 "github.com/arduino/arduino-create-agent/v2/pkgs"
30+ "github.com/stretchr/testify/require"
3031)
3132
3233// TestTools performs a series of operations about tools, ensuring it behaves as expected.
@@ -150,6 +151,33 @@ func TestTools(t *testing.T) {
150151 if len (installed ) != 1 {
151152 t .Fatalf ("expected %d == %d (%s)" , len (installed ), 1 , "len(installed)" )
152153 }
154+
155+ t .Run ("payload containing evil names" , func (t * testing.T ) {
156+ evilFileNames := []string {
157+ "/" ,
158+ ".." ,
159+ "../" ,
160+ "../evil.txt" ,
161+ "../../../../../../../../../../../../../../../../../../../../tmp/evil.txt" ,
162+ "some/path/../../../../../../../../../../../../../../../../../../../../tmp/evil.txt" ,
163+ }
164+ if runtime .GOOS == "windows" {
165+ evilFileNames = []string {
166+ "..\\ " ,
167+ "..\\ evil.txt" ,
168+ "..\\ ..\\ ..\\ ..\\ ..\\ ..\\ ..\\ ..\\ ..\\ ..\\ ..\\ ..\\ ..\\ ..\\ ..\\ ..\\ ..\\ ..\\ ..\\ ..\\ tmp\\ evil.txt" ,
169+ "some\\ path\\ ..\\ ..\\ ..\\ ..\\ ..\\ ..\\ ..\\ ..\\ ..\\ ..\\ ..\\ ..\\ ..\\ ..\\ ..\\ ..\\ ..\\ ..\\ ..\\ ..\\ tmp\\ evil.txt" ,
170+ }
171+ }
172+ for _ , evilFileName := range evilFileNames {
173+ // Here we could inject malicious name also in the Packager and Version field.
174+ // Since the path is made by joining all of these 3 fields, we're using only the Name,
175+ // as it won't change the result and let us keep the test small and readable.
176+ _ , err := service .Remove (ctx , & tools.ToolPayload {Name : evilFileName })
177+ require .Error (t , err , evilFileName )
178+ require .ErrorContains (t , err , "unsafe path join" )
179+ }
180+ })
153181}
154182
155183func strpoint (s string ) * string {
0 commit comments