aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
3 files changed, 51 insertions, 17 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9e932df2..765d6935 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -25,6 +25,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)
- 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)
diff --git a/internal/pathutil/pathutil.go b/internal/pathutil/pathutil.go
index 6a7286e1..26ea76b6 100644
--- a/internal/pathutil/pathutil.go
+++ b/internal/pathutil/pathutil.go
@@ -9,7 +9,9 @@ import (
"strings"
)
-// Clean cleans up given path and returns a relative path that goes straight down.
+// Clean cleans up given path and returns a relative path that goes straight
+// down to prevent path traversal.
func Clean(p string) string {
+ p = strings.ReplaceAll(p, `\`, "/")
return strings.Trim(path.Clean("/"+p), "/")
}
diff --git a/internal/pathutil/pathutil_test.go b/internal/pathutil/pathutil_test.go
index eb8cc176..d20e537a 100644
--- a/internal/pathutil/pathutil_test.go
+++ b/internal/pathutil/pathutil_test.go
@@ -12,38 +12,69 @@ import (
func TestClean(t *testing.T) {
tests := []struct {
- path string
- expVal string
+ path string
+ wantVal string
}{
{
- path: "../../../readme.txt",
- expVal: "readme.txt",
+ path: "../../../readme.txt",
+ wantVal: "readme.txt",
},
{
- path: "a/../../../readme.txt",
- expVal: "readme.txt",
+ path: "a/../../../readme.txt",
+ wantVal: "readme.txt",
},
{
- path: "/../a/b/../c/../readme.txt",
- expVal: "a/readme.txt",
+ path: "/../a/b/../c/../readme.txt",
+ wantVal: "a/readme.txt",
},
{
- path: "/a/readme.txt",
- expVal: "a/readme.txt",
+ path: "/a/readme.txt",
+ wantVal: "a/readme.txt",
},
{
- path: "/",
- expVal: "",
+ path: "/",
+ wantVal: "",
},
{
- path: "/a/b/c/readme.txt",
- expVal: "a/b/c/readme.txt",
+ path: "/a/b/c/readme.txt",
+ wantVal: "a/b/c/readme.txt",
+ },
+
+ // Windows-specific
+ {
+ path: `..\..\..\readme.txt`,
+ wantVal: "readme.txt",
+ },
+ {
+ path: `a\..\..\..\readme.txt`,
+ wantVal: "readme.txt",
+ },
+ {
+ path: `\..\a\b\..\c\..\readme.txt`,
+ wantVal: "a/readme.txt",
+ },
+ {
+ path: `\a\readme.txt`,
+ wantVal: "a/readme.txt",
+ },
+ {
+ path: `..\..\..\../README.md`,
+ wantVal: "README.md",
+ },
+ {
+ path: `\`,
+ wantVal: "",
+ },
+
+ {
+ path: `\a\b\c\readme.txt`,
+ wantVal: `a/b/c/readme.txt`,
},
}
for _, test := range tests {
- t.Run("", func(t *testing.T) {
- assert.Equal(t, test.expVal, Clean(test.path))
+ t.Run(test.path, func(t *testing.T) {
+ assert.Equal(t, test.wantVal, Clean(test.path))
})
}
}