From af5d2561d2475caa5af564ecfbf2382bd12fb23a Mon Sep 17 00:00:00 2001 From: Joona Hoikkala Date: Fri, 22 Feb 2019 16:53:11 +0200 Subject: [PATCH] Fail closed with malformed allowfrom data in register endpoint (#148) * Prepare readme for release * Fail closed with malformed allowfrom data in register endpoint --- acmetxt.go | 10 ++++++++++ api.go | 15 ++++++++++++++- api_test.go | 37 ++++++++++++++++++++++++++++++++++--- 3 files changed, 58 insertions(+), 4 deletions(-) diff --git a/acmetxt.go b/acmetxt.go index cec7176..63454a6 100644 --- a/acmetxt.go +++ b/acmetxt.go @@ -30,6 +30,16 @@ func (c *cidrslice) JSON() string { return string(ret) } +func (c *cidrslice) isValid() error { + for _, v := range *c { + _, _, err := net.ParseCIDR(sanitizeIPv6addr(v)) + if err != nil { + return err + } + } + return nil +} + func (c *cidrslice) ValidEntries() []string { valid := []string{} for _, v := range *c { diff --git a/api.go b/api.go index 5e532ef..5916591 100644 --- a/api.go +++ b/api.go @@ -22,10 +22,11 @@ type RegResponse struct { func webRegisterPost(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { var regStatus int var reg []byte + var err error aTXT := ACMETxt{} bdata, _ := ioutil.ReadAll(r.Body) if bdata != nil && len(bdata) > 0 { - err := json.Unmarshal(bdata, &aTXT) + err = json.Unmarshal(bdata, &aTXT) if err != nil { regStatus = http.StatusBadRequest reg = jsonError("malformed_json_payload") @@ -35,6 +36,18 @@ func webRegisterPost(w http.ResponseWriter, r *http.Request, _ httprouter.Params return } } + + // Fail with malformed CIDR mask in allowfrom + err = aTXT.AllowFrom.isValid() + if err != nil { + regStatus = http.StatusBadRequest + reg = jsonError("invalid_allowfrom_cidr") + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(regStatus) + w.Write(reg) + return + } + // Create new user nu, err := DB.Register(aTXT.AllowFrom) if err != nil { diff --git a/api_test.go b/api_test.go index b3368f8..c51f144 100644 --- a/api_test.go +++ b/api_test.go @@ -96,8 +96,9 @@ func TestApiRegister(t *testing.T) { allowfrom := map[string][]interface{}{ "allowfrom": []interface{}{"123.123.123.123/32", - "1010.10.10.10/24", - "invalid"}, + "2001:db8:a0b:12f0::1/32", + "[::1]/64", + }, } response := e.POST("/register"). @@ -112,7 +113,37 @@ func TestApiRegister(t *testing.T) { ContainsKey("allowfrom"). NotContainsKey("error") - response.Value("allowfrom").Array().Elements("123.123.123.123/32") + response.Value("allowfrom").Array().Elements("123.123.123.123/32", "2001:db8:a0b:12f0::1/32", "::1/64") +} + +func TestApiRegisterBadAllowFrom(t *testing.T) { + router := setupRouter(false, false) + server := httptest.NewServer(router) + defer server.Close() + e := getExpect(t, server) + invalidVals := []string{ + "invalid", + "1.2.3.4/33", + "1.2/24", + "1.2.3.4", + "12345:db8:a0b:12f0::1/32", + "1234::123::123::1/32", + } + + for _, v := range invalidVals { + + allowfrom := map[string][]interface{}{ + "allowfrom": []interface{}{v}} + + response := e.POST("/register"). + WithJSON(allowfrom). + Expect(). + Status(http.StatusBadRequest). + JSON().Object(). + ContainsKey("error") + + response.Value("error").Equal("invalid_allowfrom_cidr") + } } func TestApiRegisterMalformedJSON(t *testing.T) {