From 3a77465e4ed252f5d92da12321613328b30b941c Mon Sep 17 00:00:00 2001 From: zeripath Date: Thu, 16 Dec 2021 23:03:20 +0000 Subject: [PATCH] Prevent double decoding of % in url params (#17997) (#18001) --- .../4c/61dd0a799e0830e77edfe6c74f7c349bc8e62a | Bin 0 -> 40 bytes .../50/4d9fe743979d4e9785a25a363c7007293f0838 | Bin 0 -> 40 bytes .../59/e2c41e8f5140bb0182acebec17c8ad9831cc62 | Bin 0 -> 847 bytes .../64/89894ad11093fdc49c0ed857d80682344a7264 | Bin 0 -> 39 bytes .../84/7c6d93c6860dd377651245711b7fbcd34a18d4 | Bin 0 -> 41 bytes .../9b/9cc8f558d1c4f815592496fa24308ba2a9c824 | Bin 0 -> 47 bytes .../a4/f1bb3f2f8c6a0e840e935812ef4903ce515dad | Bin 0 -> 394 bytes .../c7/85b65bf16928b58567cb23669125c0ccd25a4f | Bin 0 -> 44 bytes .../e9/63733b8a355cf860c465b4af7b236a6ef08783 | Bin 0 -> 47 bytes .../utf8.git/refs/heads/Plus+Is+Not+Space | 2 +- integrations/nonascii_branches_test.go | 46 ++++++++++++++++-- modules/context/context.go | 4 ++ modules/context/repo.go | 2 +- 13 files changed, 47 insertions(+), 7 deletions(-) create mode 100644 integrations/gitea-repositories-meta/user2/utf8.git/objects/4c/61dd0a799e0830e77edfe6c74f7c349bc8e62a create mode 100644 integrations/gitea-repositories-meta/user2/utf8.git/objects/50/4d9fe743979d4e9785a25a363c7007293f0838 create mode 100644 integrations/gitea-repositories-meta/user2/utf8.git/objects/59/e2c41e8f5140bb0182acebec17c8ad9831cc62 create mode 100644 integrations/gitea-repositories-meta/user2/utf8.git/objects/64/89894ad11093fdc49c0ed857d80682344a7264 create mode 100644 integrations/gitea-repositories-meta/user2/utf8.git/objects/84/7c6d93c6860dd377651245711b7fbcd34a18d4 create mode 100644 integrations/gitea-repositories-meta/user2/utf8.git/objects/9b/9cc8f558d1c4f815592496fa24308ba2a9c824 create mode 100644 integrations/gitea-repositories-meta/user2/utf8.git/objects/a4/f1bb3f2f8c6a0e840e935812ef4903ce515dad create mode 100644 integrations/gitea-repositories-meta/user2/utf8.git/objects/c7/85b65bf16928b58567cb23669125c0ccd25a4f create mode 100644 integrations/gitea-repositories-meta/user2/utf8.git/objects/e9/63733b8a355cf860c465b4af7b236a6ef08783 diff --git a/integrations/gitea-repositories-meta/user2/utf8.git/objects/4c/61dd0a799e0830e77edfe6c74f7c349bc8e62a b/integrations/gitea-repositories-meta/user2/utf8.git/objects/4c/61dd0a799e0830e77edfe6c74f7c349bc8e62a new file mode 100644 index 0000000000000000000000000000000000000000..17b3104773bbfb8ccdb5084cd6dda8a5ec794098 GIT binary patch literal 40 xcmb&m$%0RUr;5sm-= literal 0 HcmV?d00001 diff --git a/integrations/gitea-repositories-meta/user2/utf8.git/objects/50/4d9fe743979d4e9785a25a363c7007293f0838 b/integrations/gitea-repositories-meta/user2/utf8.git/objects/50/4d9fe743979d4e9785a25a363c7007293f0838 new file mode 100644 index 0000000000000000000000000000000000000000..25794ae805e8a5405454ae83c9d854eabaf63f82 GIT binary patch literal 40 wcmblhEoiLBnXFNksc<6)~1Zn7b`1t8Qd&I=Btb+4C072*vod5s; literal 0 HcmV?d00001 diff --git a/integrations/gitea-repositories-meta/user2/utf8.git/objects/59/e2c41e8f5140bb0182acebec17c8ad9831cc62 b/integrations/gitea-repositories-meta/user2/utf8.git/objects/59/e2c41e8f5140bb0182acebec17c8ad9831cc62 new file mode 100644 index 0000000000000000000000000000000000000000..736a24227c153003864cb1b41e751db5af19f495 GIT binary patch literal 847 zcmbGQzwaVP8j`swq3aPHoC z^!|klf0-p3C$qXeNR^xL#r;ToU0(DDmMM0#Kd>!2-&7}A^+DE;Tl=5OhWLbEYmc9n zU)H^G#%iWNf7gd3=T{!M|65_pw|PQG(;u6wGcc|?P_?>iQC91unNt%lY(BFo`BPAV z_>76hKkxPJvt638ggf}D4-od$X6Vk@emz7ov5Z|K^n$-OFE>dN*|RZg1W{S=75R{Kj_4Qd6_fKg+`Z z_O?ys=by4iIrQq(L+9MY|7Xje=y0!jwkTRK{u|2+zuv;yxu#v8a<%sPJ&*K|`F=+J zf{a{befPqYUeP@)ow_YP7g)HtMORenoD7`2EJI#CXVS~uSATZsZB>sco!T?^}FVztcSrU)Fo^EKHGn(Zt>=v#Klr literal 0 HcmV?d00001 diff --git a/integrations/gitea-repositories-meta/user2/utf8.git/objects/64/89894ad11093fdc49c0ed857d80682344a7264 b/integrations/gitea-repositories-meta/user2/utf8.git/objects/64/89894ad11093fdc49c0ed857d80682344a7264 new file mode 100644 index 0000000000000000000000000000000000000000..87e198aa9ca2e9f95e3fa41a231e50e697b131af GIT binary patch literal 39 vcmb2lZ0;dW9HS!N? literal 0 HcmV?d00001 diff --git a/integrations/gitea-repositories-meta/user2/utf8.git/objects/84/7c6d93c6860dd377651245711b7fbcd34a18d4 b/integrations/gitea-repositories-meta/user2/utf8.git/objects/84/7c6d93c6860dd377651245711b7fbcd34a18d4 new file mode 100644 index 0000000000000000000000000000000000000000..ffea321c19db661925c77ef5367155c13ba0b308 GIT binary patch literal 41 xcmbQMN-+!N#Zt2>io<4C~ckHdZCBEX7b2qQ=)sQn^ytKR|(#~6cG=21FqWq$X zT9@lqN|fkFRXVY*dUI$Jx3u1yJsYG`Ziz4Z|B~IT`(#AfoquWg7pJELNs)Ib@fi3IUjt&SLf8TM@$TVJ9v%& E0Kn@L+yDRo literal 0 HcmV?d00001 diff --git a/integrations/gitea-repositories-meta/user2/utf8.git/refs/heads/Plus+Is+Not+Space b/integrations/gitea-repositories-meta/user2/utf8.git/refs/heads/Plus+Is+Not+Space index 00dd05db8c..c2850d4c4d 100644 --- a/integrations/gitea-repositories-meta/user2/utf8.git/refs/heads/Plus+Is+Not+Space +++ b/integrations/gitea-repositories-meta/user2/utf8.git/refs/heads/Plus+Is+Not+Space @@ -1 +1 @@ -3a810dbf6b96afaa8c5f69a8b6ec1dabfca7368b +59e2c41e8f5140bb0182acebec17c8ad9831cc62 diff --git a/integrations/nonascii_branches_test.go b/integrations/nonascii_branches_test.go index 22d71e6ee2..1aab16fa3e 100644 --- a/integrations/nonascii_branches_test.go +++ b/integrations/nonascii_branches_test.go @@ -6,6 +6,7 @@ package integrations import ( "net/http" + "net/url" "path" "testing" @@ -83,7 +84,7 @@ func TestNonasciiBranches(t *testing.T) { }, { from: "Plus+Is+Not+Space/Файл.md", - to: "branch/Plus+Is+Not+Space/%d0%a4%d0%b0%d0%b9%d0%bb.md", + to: "branch/Plus+Is+Not+Space/%D0%A4%D0%B0%D0%B9%D0%BB.md", status: http.StatusOK, }, { @@ -114,7 +115,7 @@ func TestNonasciiBranches(t *testing.T) { }, { from: "タグ/ファイル.md", - to: "tag/%e3%82%bf%e3%82%b0/%e3%83%95%e3%82%a1%e3%82%a4%e3%83%ab.md", + to: "tag/%e3%82%bf%e3%82%b0/%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB.md", status: http.StatusOK, }, // Files @@ -125,12 +126,12 @@ func TestNonasciiBranches(t *testing.T) { }, { from: "Файл.md", - to: "branch/Plus+Is+Not+Space/%d0%a4%d0%b0%d0%b9%d0%bb.md", + to: "branch/Plus+Is+Not+Space/%D0%A4%D0%B0%D0%B9%D0%BB.md", status: http.StatusOK, }, { from: "ファイル.md", - to: "branch/Plus+Is+Not+Space/%e3%83%95%e3%82%a1%e3%82%a4%e3%83%ab.md", + to: "branch/Plus+Is+Not+Space/%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB.md", status: http.StatusNotFound, // it's not on default branch }, // Same but url-encoded (few tests) @@ -146,7 +147,7 @@ func TestNonasciiBranches(t *testing.T) { }, { from: "%D0%A4%D0%B0%D0%B9%D0%BB.md", - to: "branch/Plus+Is+Not+Space/%d0%a4%d0%b0%d0%b9%d0%bb.md", + to: "branch/Plus+Is+Not+Space/%D0%A4%D0%B0%D0%B9%D0%BB.md", status: http.StatusOK, }, { @@ -159,6 +160,41 @@ func TestNonasciiBranches(t *testing.T) { to: "tag/%d0%81/%e4%ba%ba", status: http.StatusOK, }, + { + from: "Plus+Is+Not+Space/%25%252525mightnotplaywell", + to: "branch/Plus+Is+Not+Space/%25%252525mightnotplaywell", + status: http.StatusOK, + }, + { + from: "Plus+Is+Not+Space/%25253Fisnotaquestion%25253F", + to: "branch/Plus+Is+Not+Space/%25253Fisnotaquestion%25253F", + status: http.StatusOK, + }, + { + from: "Plus+Is+Not+Space/" + url.PathEscape("%3Fis?and#afile"), + to: "branch/Plus+Is+Not+Space/" + url.PathEscape("%3Fis?and#afile"), + status: http.StatusOK, + }, + { + from: "Plus+Is+Not+Space/10%25.md", + to: "branch/Plus+Is+Not+Space/10%25.md", + status: http.StatusOK, + }, + { + from: "Plus+Is+Not+Space/" + url.PathEscape("This+file%20has 1space"), + to: "branch/Plus+Is+Not+Space/" + url.PathEscape("This+file%20has 1space"), + status: http.StatusOK, + }, + { + from: "Plus+Is+Not+Space/" + url.PathEscape("This+file%2520has 2 spaces"), + to: "branch/Plus+Is+Not+Space/" + url.PathEscape("This+file%2520has 2 spaces"), + status: http.StatusOK, + }, + { + from: "Plus+Is+Not+Space/" + url.PathEscape("£15&$6.txt"), + to: "branch/Plus+Is+Not+Space/" + url.PathEscape("£15&$6.txt"), + status: http.StatusOK, + }, } defer prepareTestEnv(t)() diff --git a/modules/context/context.go b/modules/context/context.go index 568865d90e..82771b0c24 100644 --- a/modules/context/context.go +++ b/modules/context/context.go @@ -669,6 +669,10 @@ func Contexter() func(next http.Handler) http.Handler { var locale = middleware.Locale(resp, req) var startTime = time.Now() var link = setting.AppSubURL + strings.TrimSuffix(req.URL.EscapedPath(), "/") + + chiCtx := chi.RouteContext(req.Context()) + chiCtx.RoutePath = req.URL.EscapedPath() + var ctx = Context{ Resp: NewResponse(resp), Cache: mc.GetCache(), diff --git a/modules/context/repo.go b/modules/context/repo.go index 12943ae37f..0f78ff429b 100644 --- a/modules/context/repo.go +++ b/modules/context/repo.go @@ -833,7 +833,7 @@ func RepoRefByType(refType RepoRefType, ignoreNotExistErr ...bool) func(*Context setting.AppSubURL, strings.TrimSuffix(ctx.Req.URL.Path, ctx.Params("*")), ctx.Repo.BranchNameSubURL(), - ctx.Repo.TreePath)) + util.PathEscapeSegments(ctx.Repo.TreePath))) return } }