From 3ae0ba09a249a1bb8f0928a304291055cb0bde34 Mon Sep 17 00:00:00 2001 From: Alessio Perugini Date: Thu, 24 Oct 2024 12:59:00 +0200 Subject: [PATCH 1/2] upload: don't ignore BindJSON errors --- conn.go | 6 ++++-- main_test.go | 30 ++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/conn.go b/conn.go index 727a5cad..b6e03268 100644 --- a/conn.go +++ b/conn.go @@ -80,9 +80,11 @@ type Upload struct { var uploadStatusStr = "ProgrammerStatus" func uploadHandler(c *gin.Context) { - data := new(Upload) - c.BindJSON(data) + if err := c.BindJSON(data); err != nil { + c.String(http.StatusBadRequest, fmt.Sprintf("err with the payload. %v", err.Error())) + return + } log.Printf("%+v %+v %+v %+v %+v %+v", data.Port, data.Board, data.Rewrite, data.Commandline, data.Extra, data.Filename) diff --git a/main_test.go b/main_test.go index 56855695..4111c365 100644 --- a/main_test.go +++ b/main_test.go @@ -18,6 +18,7 @@ package main import ( "bytes" "crypto/x509" + "encoding/base64" "encoding/json" "encoding/pem" "fmt" @@ -56,6 +57,11 @@ func TestUploadHandlerAgainstEvilFileNames(t *testing.T) { r.POST("/", uploadHandler) ts := httptest.NewServer(r) + fmt.Println(base64.StdEncoding.EncodeToString([]byte("test"))) + + //Padding: dGVzdA== + //Raw: dGVzdA + uploadEvilFileName := Upload{ Port: "/dev/ttyACM0", Board: "arduino:avr:uno", @@ -87,6 +93,30 @@ func TestUploadHandlerAgainstEvilFileNames(t *testing.T) { } } +func TestUploadHandlerAgainstBase64WithoutPaddingMustFail(t *testing.T) { + r := gin.New() + r.POST("/", uploadHandler) + ts := httptest.NewServer(r) + defer ts.Close() + + // When calling the `BindJSON` func, when a json field will be Unmarshaled + // in a []byte type, we expect to receive a base64 padded string in input. + // In case we receive a base64 unpadded string BindJSON fails. + // The expectation here is that the upload handler won't continue with the + // upload operation. + base64ContentWithoutPadding := base64.RawStdEncoding.EncodeToString([]byte("test")) + payload := fmt.Sprintf(`{"hex": "%s"}`, base64ContentWithoutPadding) + + resp, err := http.Post(ts.URL, "encoding/json", bytes.NewBufferString(payload)) + require.NoError(t, err) + require.Equal(t, http.StatusBadRequest, resp.StatusCode) + + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + require.NoError(t, err) + require.Contains(t, string(body), "err with the payload. illegal base64 data at input") +} + func TestInstallToolV2(t *testing.T) { indexURL := "https://downloads.arduino.cc/packages/package_index.json" From f401ddc140c868a80bbba750ba388d44fa0826aa Mon Sep 17 00:00:00 2001 From: Alessio Perugini Date: Thu, 24 Oct 2024 13:31:18 +0200 Subject: [PATCH 2/2] remove debug leftover --- main_test.go | 5 ----- 1 file changed, 5 deletions(-) diff --git a/main_test.go b/main_test.go index 4111c365..d6f23fce 100644 --- a/main_test.go +++ b/main_test.go @@ -57,11 +57,6 @@ func TestUploadHandlerAgainstEvilFileNames(t *testing.T) { r.POST("/", uploadHandler) ts := httptest.NewServer(r) - fmt.Println(base64.StdEncoding.EncodeToString([]byte("test"))) - - //Padding: dGVzdA== - //Raw: dGVzdA - uploadEvilFileName := Upload{ Port: "/dev/ttyACM0", Board: "arduino:avr:uno",