@@ -131,79 +131,79 @@ func TestTools(t *testing.T) {
131
131
if len (installed ) != 0 {
132
132
t .Fatalf ("expected %d == %d (%s)" , len (installed ), 0 , "len(installed)" )
133
133
}
134
+ }
134
135
135
- // Install a tool by specifying url and checksum
136
- _ , err = service . Install ( ctx , & tools. ToolPayload {
137
- Packager : "arduino" ,
138
- Name : "avrdude" ,
139
- Version : "6.0.1-arduino2" ,
140
- URL : strpoint ( url ()),
141
- Checksum : strpoint ( checksum ()) ,
142
- })
143
- if err != nil {
144
- t . Fatal ( err )
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
+ },
145
146
}
146
147
147
- installed , err = service .Installed (ctx )
148
- if err != nil {
149
- t .Fatal (err )
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" ,
169
+ }
150
170
}
151
- if len (installed ) != 1 {
152
- t .Fatalf ("expected %d == %d (%s)" , len (installed ), 1 , "len(installed)" )
171
+ tests := []test {}
172
+ for _ , evilFileName := range evilFileNames {
173
+ tests = append (tests , test {fileName : evilFileName ,
174
+ errBody : "unsafe path join" })
153
175
}
154
176
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 {
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 ) {
173
186
// Here we could inject malicious name also in the Packager and Version field.
174
187
// Since the path is made by joining all of these 3 fields, we're using only the Name,
175
188
// 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
- })
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
+ }
181
205
}
182
206
183
207
func strpoint (s string ) * string {
184
208
return & s
185
209
}
186
-
187
- func url () string {
188
- urls := map [string ]string {
189
- "linuxamd64" : "https://downloads.arduino.cc/tools/avrdude-6.0.1-arduino2-x86_64-pc-linux-gnu.tar.bz2" ,
190
- "linux386" : "https://downloads.arduino.cc/tools/avrdude-6.0.1-arduino2-i686-pc-linux-gnu.tar.bz2" ,
191
- "darwinamd64" : "https://downloads.arduino.cc/tools/avrdude-6.0.1-arduino2-i386-apple-darwin11.tar.bz2" ,
192
- "windows386" : "https://downloads.arduino.cc/tools/avrdude-6.0.1-arduino2-i686-mingw32.zip" ,
193
- "windowsamd64" : "https://downloads.arduino.cc/tools/avrdude-6.0.1-arduino2-i686-mingw32.zip" ,
194
- }
195
-
196
- return urls [runtime .GOOS + runtime .GOARCH ]
197
- }
198
-
199
- func checksum () string {
200
- checksums := map [string ]string {
201
- "linuxamd64" : "SHA-256:2489004d1d98177eaf69796760451f89224007c98b39ebb5577a9a34f51425f1" ,
202
- "linux386" : "SHA-256:6f633dd6270ad0d9ef19507bcbf8697b414a15208e4c0f71deec25ef89cdef3f" ,
203
- "darwinamd64" : "SHA-256:71117cce0096dad6c091e2c34eb0b9a3386d3aec7d863d2da733d9e5eac3a6b1" ,
204
- "windows386" : "SHA-256:6c5483800ba753c80893607e30cade8ab77b182808fcc5ea15fa3019c63d76ae" ,
205
- "windowsamd64" : "SHA-256:6c5483800ba753c80893607e30cade8ab77b182808fcc5ea15fa3019c63d76ae" ,
206
- }
207
- return checksums [runtime .GOOS + runtime .GOARCH ]
208
-
209
- }
0 commit comments