Skip to content

Commit 5d674c8

Browse files
use SafeJoin in the uploadHandler
1 parent 4c73aa6 commit 5d674c8

File tree

2 files changed

+43
-2
lines changed

2 files changed

+43
-2
lines changed

conn.go

+6-2
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,11 @@ func uploadHandler(c *gin.Context) {
140140
}
141141

142142
for _, extraFile := range data.ExtraFiles {
143-
path := filepath.Join(tmpdir, extraFile.Filename)
143+
path, err := utilities.SafeJoin(tmpdir, extraFile.Filename)
144+
if err != nil {
145+
c.String(http.StatusBadRequest, err.Error())
146+
return
147+
}
144148
filePaths = append(filePaths, path)
145149
log.Printf("Saving %s on %s", extraFile.Filename, path)
146150

@@ -150,7 +154,7 @@ func uploadHandler(c *gin.Context) {
150154
return
151155
}
152156

153-
err := os.WriteFile(path, extraFile.Hex, 0644)
157+
err = os.WriteFile(path, extraFile.Hex, 0644)
154158
if err != nil {
155159
c.String(http.StatusBadRequest, err.Error())
156160
return

main_test.go

+37
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import (
2626
"path/filepath"
2727
"testing"
2828

29+
"github.com/arduino/arduino-create-agent/upload"
2930
"github.com/arduino/arduino-create-agent/config"
3031
"github.com/arduino/arduino-create-agent/gen/tools"
3132
v2 "github.com/arduino/arduino-create-agent/v2"
@@ -48,6 +49,42 @@ func TestValidSignatureKey(t *testing.T) {
4849
require.NotNil(t, key)
4950
}
5051

52+
func TestUploadHandlerAgainstEvilFileNames(t *testing.T) {
53+
r := gin.New()
54+
r.POST("/", uploadHandler)
55+
ts := httptest.NewServer(r)
56+
57+
uploadEvilFileName := Upload{
58+
Port: "/dev/ttyACM0",
59+
Board: "arduino:avr:uno",
60+
Extra: upload.Extra{Network: true},
61+
Hex: []byte("test"),
62+
Filename: "../evil.txt",
63+
ExtraFiles: []additionalFile{{Hex: []byte("test"), Filename: "../evil.txt"}},
64+
}
65+
uploadEvilExtraFile := Upload{
66+
Port: "/dev/ttyACM0",
67+
Board: "arduino:avr:uno",
68+
Extra: upload.Extra{Network: true},
69+
Hex: []byte("test"),
70+
Filename: "file.txt",
71+
ExtraFiles: []additionalFile{{Hex: []byte("test"), Filename: "../evil.txt"}},
72+
}
73+
74+
for _, request := range []Upload{uploadEvilFileName, uploadEvilExtraFile} {
75+
payload, err := json.Marshal(request)
76+
require.NoError(t, err)
77+
78+
resp, err := http.Post(ts.URL, "encoding/json", bytes.NewBuffer(payload))
79+
require.NoError(t, err)
80+
require.Equal(t, http.StatusBadRequest, resp.StatusCode)
81+
82+
body, err := io.ReadAll(resp.Body)
83+
require.NoError(t, err)
84+
require.Contains(t, string(body), "unsafe path join")
85+
}
86+
}
87+
5188
func TestInstallToolDifferentContentType(t *testing.T) {
5289
r := gin.New()
5390
goa := v2.Server(config.GetDataDir().String())

0 commit comments

Comments
 (0)