Przeglądaj źródła

http: clean request path from Git endpoints (#7022)

Joe Chen 2 lat temu
rodzic
commit
9bf748b6c4
3 zmienionych plików z 17 dodań i 5 usunięć
  1. 1 0
      CHANGELOG.md
  2. 4 0
      internal/pathutil/pathutil_test.go
  3. 12 5
      internal/route/repo/http.go

+ 1 - 0
CHANGELOG.md

@@ -26,6 +26,7 @@ All notable changes to Gogs are documented in this file.
 - _Security:_ OS Command Injection in file editor. [#7000](https://github.com/gogs/gogs/issues/7000)
 - _Security:_ Sanitize `DisplayName` in repository issue list. [#7009](https://github.com/gogs/gogs/pull/7009)
 - _Security:_ Path Traversal in file editor on Windows. [#7001](https://github.com/gogs/gogs/issues/7001)
+- _Security:_ Path Traversal in Git HTTP endpoints. [#7002](https://github.com/gogs/gogs/issues/7002)
 - Unable to use LDAP authentication on ARM machines. [#6761](https://github.com/gogs/gogs/issues/6761)
 - Unable to init repository during creation on Windows. [#6967](https://github.com/gogs/gogs/issues/6967)
 - Mysterious panic on `Value not found for type *repo.HTTPContext`. [#6963](https://github.com/gogs/gogs/issues/6963)

+ 4 - 0
internal/pathutil/pathutil_test.go

@@ -27,6 +27,10 @@ func TestClean(t *testing.T) {
 			path:    "/../a/b/../c/../readme.txt",
 			wantVal: "a/readme.txt",
 		},
+		{
+			path:    "../../objects/info/..",
+			wantVal: "objects",
+		},
 		{
 			path:    "/a/readme.txt",
 			wantVal: "a/readme.txt",

+ 12 - 5
internal/route/repo/http.go

@@ -24,6 +24,7 @@ import (
 	"gogs.io/gogs/internal/conf"
 	"gogs.io/gogs/internal/db"
 	"gogs.io/gogs/internal/lazyregexp"
+	"gogs.io/gogs/internal/pathutil"
 	"gogs.io/gogs/internal/tool"
 )
 
@@ -408,15 +409,21 @@ func HTTP(c *HTTPContext) {
 		}
 
 		if route.method != c.Req.Method {
-			c.NotFound()
+			c.Error(http.StatusNotFound)
 			return
 		}
 
-		file := strings.TrimPrefix(reqPath, m[1]+"/")
-		dir, err := getGitRepoPath(m[1])
+		cleaned := pathutil.Clean(m[1])
+		if m[1] != "/"+cleaned {
+			c.Error(http.StatusBadRequest, "Request path contains suspicious characters")
+			return
+		}
+
+		file := strings.TrimPrefix(reqPath, cleaned)
+		dir, err := getGitRepoPath(cleaned)
 		if err != nil {
 			log.Warn("HTTP.getGitRepoPath: %v", err)
-			c.NotFound()
+			c.Error(http.StatusNotFound)
 			return
 		}
 
@@ -435,5 +442,5 @@ func HTTP(c *HTTPContext) {
 		return
 	}
 
-	c.NotFound()
+	c.Error(http.StatusNotFound)
 }