@@ -131,33 +131,77 @@ func TestTools(t *testing.T) {
131131 if len (installed ) != 0 {
132132 t .Fatalf ("expected %d == %d (%s)" , len (installed ), 0 , "len(installed)" )
133133 }
134+ }
134135
135- t .Run ("payload containing evil names" , func (t * testing.T ) {
136- evilFileNames := []string {
137- "/" ,
138- ".." ,
139- "../" ,
140- "../evil.txt" ,
141- "../../../../../../../../../../../../../../../../../../../../tmp/evil.txt" ,
142- "some/path/../../../../../../../../../../../../../../../../../../../../tmp/evil.txt" ,
143- }
144- if runtime .GOOS == "windows" {
145- evilFileNames = []string {
146- "..\\ " ,
147- "..\\ evil.txt" ,
148- "..\\ ..\\ ..\\ ..\\ ..\\ ..\\ ..\\ ..\\ ..\\ ..\\ ..\\ ..\\ ..\\ ..\\ ..\\ ..\\ ..\\ ..\\ ..\\ ..\\ tmp\\ evil.txt" ,
149- "some\\ path\\ ..\\ ..\\ ..\\ ..\\ ..\\ ..\\ ..\\ ..\\ ..\\ ..\\ ..\\ ..\\ ..\\ ..\\ ..\\ ..\\ ..\\ ..\\ ..\\ ..\\ tmp\\ evil.txt" ,
150- }
136+ func TestEvilFilename (t * testing.T ) {
137+
138+ // Initialize indexes with a temp folder
139+ tmp := t .TempDir ()
140+
141+ service := pkgs.Tools {
142+ Folder : tmp ,
143+ Indexes : & pkgs.Indexes {
144+ Folder : tmp ,
145+ },
146+ }
147+
148+ ctx := context .Background ()
149+
150+ type test struct {
151+ fileName string
152+ errBody string
153+ }
154+
155+ evilFileNames := []string {
156+ "/" ,
157+ ".." ,
158+ "../" ,
159+ "../evil.txt" ,
160+ "../../../../../../../../../../../../../../../../../../../../tmp/evil.txt" ,
161+ "some/path/../../../../../../../../../../../../../../../../../../../../tmp/evil.txt" ,
162+ }
163+ if runtime .GOOS == "windows" {
164+ evilFileNames = []string {
165+ "..\\ " ,
166+ "..\\ evil.txt" ,
167+ "..\\ ..\\ ..\\ ..\\ ..\\ ..\\ ..\\ ..\\ ..\\ ..\\ ..\\ ..\\ ..\\ ..\\ ..\\ ..\\ ..\\ ..\\ ..\\ ..\\ tmp\\ evil.txt" ,
168+ "some\\ path\\ ..\\ ..\\ ..\\ ..\\ ..\\ ..\\ ..\\ ..\\ ..\\ ..\\ ..\\ ..\\ ..\\ ..\\ ..\\ ..\\ ..\\ ..\\ ..\\ ..\\ tmp\\ evil.txt" ,
151169 }
152- for _ , evilFileName := range evilFileNames {
170+ }
171+ tests := []test {}
172+ for _ , evilFileName := range evilFileNames {
173+ tests = append (tests , test {fileName : evilFileName ,
174+ errBody : "unsafe path join" })
175+ }
176+
177+ toolsTemplate := tools.ToolPayload {
178+ // We'll replace the name directly in the test
179+ Checksum : strpoint ("SHA-256:1ae54999c1f97234a5c603eb99ad39313b11746a4ca517269a9285afa05f9100" ),
180+ Signature : strpoint ("382898a97b5a86edd74208f10107d2fecbf7059ffe9cc856e045266fb4db4e98802728a0859cfdcda1c0b9075ec01e42dbea1f430b813530d5a6ae1766dfbba64c3e689b59758062dc2ab2e32b2a3491dc2b9a80b9cda4ae514fbe0ec5af210111b6896976053ab76bac55bcecfcececa68adfa3299e3cde6b7f117b3552a7d80ca419374bb497e3c3f12b640cf5b20875416b45e662fc6150b99b178f8e41d6982b4c0a255925ea39773683f9aa9201dc5768b6fc857c87ff602b6a93452a541b8ec10ca07f166e61a9e9d91f0a6090bd2038ed4427af6251039fb9fe8eb62ec30d7b0f3df38bc9de7204dec478fb86f8eb3f71543710790ee169dce039d3e0" ),
181+ URL : strpoint ("http://downloads.arduino.cc/tools/bossac-1.7.0-arduino3-linux64.tar.gz" ),
182+ }
183+
184+ for _ , test := range tests {
185+ t .Run ("REMOVE payload containing evil names: " + test .fileName , func (t * testing.T ) {
153186 // Here we could inject malicious name also in the Packager and Version field.
154187 // Since the path is made by joining all of these 3 fields, we're using only the Name,
155188 // as it won't change the result and let us keep the test small and readable.
156- _ , err := service .Remove (ctx , & tools.ToolPayload {Name : evilFileName })
157- require .Error (t , err , evilFileName )
158- require .ErrorContains (t , err , "unsafe path join" )
159- }
160- })
189+ _ , err := service .Remove (ctx , & tools.ToolPayload {Name : test .fileName })
190+ require .Error (t , err , test )
191+ require .ErrorContains (t , err , test .errBody )
192+ })
193+ }
194+ for _ , test := range tests {
195+ toolsTemplate .Name = test .fileName
196+ t .Run ("INSTALL payload containing evil names: " + toolsTemplate .Name , func (t * testing.T ) {
197+ // Here we could inject malicious name also in the Packager and Version field.
198+ // Since the path is made by joining all of these 3 fields, we're using only the Name,
199+ // as it won't change the result and let us keep the test small and readable.
200+ _ , err := service .Install (ctx , & toolsTemplate )
201+ require .Error (t , err , test )
202+ require .ErrorContains (t , err , test .errBody )
203+ })
204+ }
161205}
162206
163207func strpoint (s string ) * string {
0 commit comments