CVE-2022-24863 (published 2022-04-18T19:15Z)

http-swagger is an open source wrapper to automatically generate RESTful API documentation with Swagger 2.0. In versions of http-swagger prior to 1.2.6 an attacker may perform a denial of service attack consisting of memory exhaustion on the host system. The cause of the memory exhaustion is down to improper handling of http methods. Users are advised to upgrade. Users unable to upgrade may to restrict the path prefix to the "GET" method as a workaround.

Severity: HIGH
CVSS v2 base score: 7.8 (AV:N/AC:L/Au:N/C:N/I:N/A:C)
CVSS v3 base score: 7.5, HIGH (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H)

Weakness information:
cwe_id: CWE-755
cwe_name: Improper Handling of Exceptional Conditions
description: The product does not handle or incorrectly handles an exceptional condition.
extended_description: 
            
         
         

Fix information:
repo_url: https://github.com/swaggo/http-swagger
commit_details: repo_url: https://github.com/swaggo/http-swagger
author: Bogdan U
author_date: 2022-04-16 09:23:47+03:00
msg: fix: security improvement (#62)
repository: repo_url: https://github.com/swaggo/http-swagger
repo_name: swaggo/http-swagger
description: Default net/http wrapper to automatically generate RESTful API documentation with Swagger 2.0.
repo_language: Go
owner: swaggo
file_changes: filename: ci.yml
change_type: ModificationType.MODIFY
diff: @@ -10,7 +10,7 @@ jobs:
   test:
     strategy:
       matrix:
-        go: [ '1.15.x', '1.16.x', '1.17.x' ]
+        go: [ '1.15.x', '1.16.x', '1.17.x', '1.18.x' ]
     runs-on: ubuntu-latest
     steps:
       - uses: actions/checkout@master

programming_language: Markdown
filename: swagger.go
change_type: ModificationType.MODIFY
diff: @@ -122,6 +122,10 @@ func Handler(configFns ...func(*Config)) http.HandlerFunc {
 	var re = regexp.MustCompile(`^(.*/)([^?].*)?[?|.]*$`)
 
 	return func(w http.ResponseWriter, r *http.Request) {
+		if r.Method != http.MethodGet {
+			http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
+			return
+		}
 		matches := re.FindStringSubmatch(r.RequestURI)
 		path := matches[2]
 
@@ -155,7 +159,7 @@ func Handler(configFns ...func(*Config)) http.HandlerFunc {
 			}
 			_, _ = w.Write([]byte(doc))
 		case "":
-			http.Redirect(w, r, h.Prefix+"index.html", 301)
+			http.Redirect(w, r, h.Prefix+"index.html", http.StatusMovedPermanently)
 		default:
 			h.ServeHTTP(w, r)
 		}

programming_language: Go
filename: swagger_test.go
change_type: ModificationType.MODIFY
diff: @@ -43,35 +43,36 @@ func TestWrapHandler(t *testing.T) {
 
 	router.Handle("/", Handler(DocExpansion("none"), DomID("#swagger-ui")))
 
-	w1 := performRequest("GET", "/index.html", router)
-	assert.Equal(t, 200, w1.Code)
+	w1 := performRequest(http.MethodGet, "/index.html", router)
+	assert.Equal(t, http.StatusOK, w1.Code)
 	assert.Equal(t, w1.Header()["Content-Type"][0], "text/html; charset=utf-8")
 
-	w2 := performRequest("GET", "/doc.json", router)
-	assert.Equal(t, 500, w2.Code)
+	assert.Equal(t, http.StatusInternalServerError, performRequest(http.MethodGet, "/doc.json", router).Code)
 
 	swag.Register(swag.Name, &mockedSwag{})
-	w2 = performRequest("GET", "/doc.json", router)
-	assert.Equal(t, 200, w2.Code)
+	w2 := performRequest(http.MethodGet, "/doc.json", router)
+	assert.Equal(t, http.StatusOK, w2.Code)
 	assert.Equal(t, "application/json; charset=utf-8", w2.Header().Get("content-type"))
 
-	w3 := performRequest("GET", "/favicon-16x16.png", router)
-	assert.Equal(t, 200, w3.Code)
+	w3 := performRequest(http.MethodGet, "/favicon-16x16.png", router)
+	assert.Equal(t, http.StatusOK, w3.Code)
 	assert.Equal(t, w3.Header()["Content-Type"][0], "image/png")
 
-	w4 := performRequest("GET", "/swagger-ui.css", router)
-	assert.Equal(t, 200, w4.Code)
+	w4 := performRequest(http.MethodGet, "/swagger-ui.css", router)
+	assert.Equal(t, http.StatusOK, w4.Code)
 	assert.Equal(t, w4.Header()["Content-Type"][0], "text/css; charset=utf-8")
 
-	w5 := performRequest("GET", "/swagger-ui-bundle.js", router)
-	assert.Equal(t, 200, w5.Code)
+	w5 := performRequest(http.MethodGet, "/swagger-ui-bundle.js", router)
+	assert.Equal(t, http.StatusOK, w5.Code)
 	assert.Equal(t, w5.Header()["Content-Type"][0], "application/javascript")
 
-	w6 := performRequest("GET", "/notfound", router)
-	assert.Equal(t, 404, w6.Code)
+	assert.Equal(t, http.StatusNotFound, performRequest(http.MethodGet, "/notfound", router).Code)
 
-	w7 := performRequest("GET", "/", router)
-	assert.Equal(t, 301, w7.Code)
+	assert.Equal(t, 301, performRequest(http.MethodGet, "/", router).Code)
+
+	assert.Equal(t, http.StatusMethodNotAllowed, performRequest(http.MethodPost, "/swagger/index.html", router).Code)
+
+	assert.Equal(t, http.StatusMethodNotAllowed, performRequest(http.MethodPut, "/swagger/index.html", router).Code)
 }
 
 func performRequest(method, target string, h http.Handler) *httptest.ResponseRecorder {

programming_language: Go