Skip to content

Commit de6ef14

Browse files
mrsdizziezeripath
authored andcommitted
Validate External Tracker URL Format (#7089)
* Validate External Tracker URL Format Add some validation checks for external tracker URL format. Fixes #7068 * Don't make {index} a hard requirement * Fix Description * make fmt * move regex to package level * fix copyright date
1 parent 592924a commit de6ef14

File tree

3 files changed

+87
-1
lines changed

3 files changed

+87
-1
lines changed

modules/validation/helpers.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,16 @@ package validation
77
import (
88
"net"
99
"net/url"
10+
"regexp"
1011
"strings"
1112

1213
"code.gitea.io/gitea/modules/setting"
1314
)
1415

1516
var loopbackIPBlocks []*net.IPNet
1617

18+
var externalTrackerRegex = regexp.MustCompile(`({?)(?:user|repo|index)+?(}?)`)
19+
1720
func init() {
1821
for _, cidr := range []string{
1922
"127.0.0.0/8", // IPv4 loopback
@@ -75,3 +78,19 @@ func IsValidExternalURL(uri string) bool {
7578

7679
return true
7780
}
81+
82+
// IsValidExternalTrackerURLFormat checks if URL matches required syntax for external trackers
83+
func IsValidExternalTrackerURLFormat(uri string) bool {
84+
if !IsValidExternalURL(uri) {
85+
return false
86+
}
87+
88+
// check for typoed variables like /{index/ or /[repo}
89+
for _, match := range externalTrackerRegex.FindAllStringSubmatch(uri, -1) {
90+
if (match[1] == "{" || match[2] == "}") && (match[1] != "{" || match[2] != "}") {
91+
return false
92+
}
93+
}
94+
95+
return true
96+
}

modules/validation/helpers_test.go

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,3 +88,70 @@ func Test_IsValidExternalURL(t *testing.T) {
8888
})
8989
}
9090
}
91+
92+
func Test_IsValidExternalTrackerURLFormat(t *testing.T) {
93+
setting.AppURL = "https://try.gitea.io/"
94+
95+
cases := []struct {
96+
description string
97+
url string
98+
valid bool
99+
}{
100+
{
101+
description: "Correct external tracker URL with all placeholders",
102+
url: "https://github.com/{user}/{repo}/issues/{index}",
103+
valid: true,
104+
},
105+
{
106+
description: "Local external tracker URL with all placeholders",
107+
url: "https://127.0.0.1/{user}/{repo}/issues/{index}",
108+
valid: false,
109+
},
110+
{
111+
description: "External tracker URL with typo placeholder",
112+
url: "https://github.com/{user}/{repo/issues/{index}",
113+
valid: false,
114+
},
115+
{
116+
description: "External tracker URL with typo placeholder",
117+
url: "https://github.com/[user}/{repo/issues/{index}",
118+
valid: false,
119+
},
120+
{
121+
description: "External tracker URL with typo placeholder",
122+
url: "https://github.com/{user}/repo}/issues/{index}",
123+
valid: false,
124+
},
125+
{
126+
description: "External tracker URL missing optional placeholder",
127+
url: "https://github.com/{user}/issues/{index}",
128+
valid: true,
129+
},
130+
{
131+
description: "External tracker URL missing optional placeholder",
132+
url: "https://github.com/{repo}/issues/{index}",
133+
valid: true,
134+
},
135+
{
136+
description: "External tracker URL missing optional placeholder",
137+
url: "https://github.com/issues/{index}",
138+
valid: true,
139+
},
140+
{
141+
description: "External tracker URL missing optional placeholder",
142+
url: "https://github.com/issues/{user}",
143+
valid: true,
144+
},
145+
{
146+
description: "External tracker URL with similar placeholder names test",
147+
url: "https://github.com/user/repo/issues/{index}",
148+
valid: true,
149+
},
150+
}
151+
152+
for _, testCase := range cases {
153+
t.Run(testCase.description, func(t *testing.T) {
154+
assert.Equal(t, testCase.valid, IsValidExternalTrackerURLFormat(testCase.url))
155+
})
156+
}
157+
}

routers/repo/setting.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,7 @@ func SettingsPost(ctx *context.Context, form auth.RepoSettingForm) {
249249
ctx.Redirect(repo.Link() + "/settings")
250250
return
251251
}
252-
if len(form.TrackerURLFormat) != 0 && !validation.IsValidExternalURL(form.TrackerURLFormat) {
252+
if len(form.TrackerURLFormat) != 0 && !validation.IsValidExternalTrackerURLFormat(form.TrackerURLFormat) {
253253
ctx.Flash.Error(ctx.Tr("repo.settings.tracker_url_format_error"))
254254
ctx.Redirect(repo.Link() + "/settings")
255255
return

0 commit comments

Comments
 (0)