Skip to content

Commit 7d7007d

Browse files
authored
Added option to disable webhooks (go-gitea#13176)
* Added option to disable web hooks This mod introduces DISABLE_WEB_HOOKS parameter in [security] section of app.ini (by default set to false). If set to true it disables web hooks feature. Any existing undelivered web hook tasks will be cancelled. Any existing web hook definitions will be left untouched in db but its delivery tasks will be ignored. Author-Change-Id: IB#1105130 * Webhook spelling fixed Webhook spelling fixed. Fixes: 07df661 Related: go-gitea#13176 (review) Author-Change-Id: IB#1105174 * Parameter description fixed Parameter description fixed. Fixes: 07df661 Related: go-gitea#13176 (review) Author-Change-Id: IB#1105174
1 parent ac70163 commit 7d7007d

File tree

12 files changed

+68
-25
lines changed

12 files changed

+68
-25
lines changed

custom/conf/app.example.ini

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -556,6 +556,8 @@ IMPORT_LOCAL_PATHS = false
556556
; It also enables them to access other resources available to the user on the operating system that is running the Gitea instance and perform arbitrary actions in the name of the Gitea OS user.
557557
; WARNING: This maybe harmful to you website or your operating system.
558558
DISABLE_GIT_HOOKS = true
559+
; Set to true to disable webhooks feature.
560+
DISABLE_WEBHOOKS = false
559561
; Set to false to allow pushes to gitea repositories despite having an incomplete environment - NOT RECOMMENDED
560562
ONLY_ALLOW_PUSH_IF_GITEA_ENVIRONMENT_SET = true
561563
;Comma separated list of character classes required to pass minimum complexity.

docs/content/doc/advanced/config-cheat-sheet.en-us.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -396,6 +396,7 @@ relation to port exhaustion.
396396
It also enables them to access other resources available to the user on the operating system that is running the
397397
Gitea instance and perform arbitrary actions in the name of the Gitea OS user.
398398
This maybe harmful to you website or your operating system.
399+
- `DISABLE_WEBHOOKS`: **false**: Set to `true` to disable webhooks feature.
399400
- `ONLY_ALLOW_PUSH_IF_GITEA_ENVIRONMENT_SET`: **true**: Set to `false` to allow local users to push to gitea-repositories without setting up the Gitea environment. This is not recommended and if you want local users to push to gitea repositories you should set the environment appropriately.
400401
- `IMPORT_LOCAL_PATHS`: **false**: Set to `false` to prevent all users (including admin) from importing local path on server.
401402
- `INTERNAL_TOKEN`: **\<random at every install if no uri set\>**: Secret used to validate communication within Gitea binary.

modules/setting/setting.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,7 @@ var (
156156
MinPasswordLength int
157157
ImportLocalPaths bool
158158
DisableGitHooks bool
159+
DisableWebhooks bool
159160
OnlyAllowPushIfGiteaEnvironmentSet bool
160161
PasswordComplexity []string
161162
PasswordHashAlgo string
@@ -801,6 +802,7 @@ func NewContext() {
801802
MinPasswordLength = sec.Key("MIN_PASSWORD_LENGTH").MustInt(6)
802803
ImportLocalPaths = sec.Key("IMPORT_LOCAL_PATHS").MustBool(false)
803804
DisableGitHooks = sec.Key("DISABLE_GIT_HOOKS").MustBool(true)
805+
DisableWebhooks = sec.Key("DISABLE_WEBHOOKS").MustBool(false)
804806
OnlyAllowPushIfGiteaEnvironmentSet = sec.Key("ONLY_ALLOW_PUSH_IF_GITEA_ENVIRONMENT_SET").MustBool(true)
805807
PasswordHashAlgo = sec.Key("PASSWORD_HASH_ALGO").MustString("argon2")
806808
CSRFCookieHTTPOnly = sec.Key("CSRF_COOKIE_HTTP_ONLY").MustBool(true)

modules/templates/helper.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,9 @@ func NewFuncMap() []template.FuncMap {
229229
"DisableGitHooks": func() bool {
230230
return setting.DisableGitHooks
231231
},
232+
"DisableWebhooks": func() bool {
233+
return setting.DisableWebhooks
234+
},
232235
"DisableImportLocal": func() bool {
233236
return !setting.ImportLocalPaths
234237
},

routers/api/v1/api.go

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -383,6 +383,16 @@ func reqGitHook() func(ctx *context.APIContext) {
383383
}
384384
}
385385

386+
// reqWebhooksEnabled requires webhooks to be enabled by admin.
387+
func reqWebhooksEnabled() func(ctx *context.APIContext) {
388+
return func(ctx *context.APIContext) {
389+
if setting.DisableWebhooks {
390+
ctx.Error(http.StatusForbidden, "", "webhooks disabled by administrator")
391+
return
392+
}
393+
}
394+
}
395+
386396
func orgAssignment(args ...bool) func(ctx *context.APIContext) {
387397
var (
388398
assignOrg bool
@@ -703,6 +713,14 @@ func Routes() *web.Route {
703713
m.Combo("/notifications").
704714
Get(reqToken(), notify.ListRepoNotifications).
705715
Put(reqToken(), notify.ReadRepoNotifications)
716+
m.Group("/hooks/git", func() {
717+
m.Combo("").Get(repo.ListGitHooks)
718+
m.Group("/{id}", func() {
719+
m.Combo("").Get(repo.GetGitHook).
720+
Patch(bind(api.EditGitHookOption{}), repo.EditGitHook).
721+
Delete(repo.DeleteGitHook)
722+
})
723+
}, reqToken(), reqAdmin(), reqGitHook(), context.ReferencesGitRepo(true))
706724
m.Group("/hooks", func() {
707725
m.Combo("").Get(repo.ListHooks).
708726
Post(bind(api.CreateHookOption{}), repo.CreateHook)
@@ -712,15 +730,7 @@ func Routes() *web.Route {
712730
Delete(repo.DeleteHook)
713731
m.Post("/tests", context.RepoRefForAPI, repo.TestHook)
714732
})
715-
m.Group("/git", func() {
716-
m.Combo("").Get(repo.ListGitHooks)
717-
m.Group("/{id}", func() {
718-
m.Combo("").Get(repo.GetGitHook).
719-
Patch(bind(api.EditGitHookOption{}), repo.EditGitHook).
720-
Delete(repo.DeleteGitHook)
721-
})
722-
}, reqGitHook(), context.ReferencesGitRepo(true))
723-
}, reqToken(), reqAdmin())
733+
}, reqToken(), reqAdmin(), reqWebhooksEnabled())
724734
m.Group("/collaborators", func() {
725735
m.Get("", reqAnyRepoReader(), repo.ListCollaborators)
726736
m.Combo("/{collaborator}").Get(reqAnyRepoReader(), repo.IsCollaborator).
@@ -984,7 +994,7 @@ func Routes() *web.Route {
984994
m.Combo("/{id}").Get(org.GetHook).
985995
Patch(bind(api.EditHookOption{}), org.EditHook).
986996
Delete(org.DeleteHook)
987-
}, reqToken(), reqOrgOwnership())
997+
}, reqToken(), reqOrgOwnership(), reqWebhooksEnabled())
988998
}, orgAssignment(true))
989999
m.Group("/teams/{teamid}", func() {
9901000
m.Combo("").Get(org.GetTeam).

routers/routes/web.go

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,14 @@ func RegisterRoutes(m *web.Route) {
248248
}
249249
}
250250

251+
// webhooksEnabled requires webhooks to be enabled by admin.
252+
webhooksEnabled := func(ctx *context.Context) {
253+
if setting.DisableWebhooks {
254+
ctx.Error(403)
255+
return
256+
}
257+
}
258+
251259
// FIXME: not all routes need go through same middleware.
252260
// Especially some AJAX requests, we can reduce middleware number to improve performance.
253261
// Routers.
@@ -446,7 +454,7 @@ func RegisterRoutes(m *web.Route) {
446454
m.Post("/matrix/{id}", bindIgnErr(auth.NewMatrixHookForm{}), repo.MatrixHooksEditPost)
447455
m.Post("/msteams/{id}", bindIgnErr(auth.NewMSTeamsHookForm{}), repo.MSTeamsHooksEditPost)
448456
m.Post("/feishu/{id}", bindIgnErr(auth.NewFeishuHookForm{}), repo.FeishuHooksEditPost)
449-
})
457+
}, webhooksEnabled)
450458

451459
m.Group("/{configType:default-hooks|system-hooks}", func() {
452460
m.Get("/{type}/new", repo.WebhooksNew)
@@ -568,7 +576,7 @@ func RegisterRoutes(m *web.Route) {
568576
m.Post("/matrix/{id}", bindIgnErr(auth.NewMatrixHookForm{}), repo.MatrixHooksEditPost)
569577
m.Post("/msteams/{id}", bindIgnErr(auth.NewMSTeamsHookForm{}), repo.MSTeamsHooksEditPost)
570578
m.Post("/feishu/{id}", bindIgnErr(auth.NewFeishuHookForm{}), repo.FeishuHooksEditPost)
571-
})
579+
}, webhooksEnabled)
572580

573581
m.Group("/labels", func() {
574582
m.Get("", org.RetrieveLabels, org.Labels)
@@ -621,6 +629,12 @@ func RegisterRoutes(m *web.Route) {
621629
Post(bindIgnErr(auth.ProtectBranchForm{}), context.RepoMustNotBeArchived(), repo.SettingsProtectedBranchPost)
622630
}, repo.MustBeNotEmpty)
623631

632+
m.Group("/hooks/git", func() {
633+
m.Get("", repo.GitHooks)
634+
m.Combo("/{name}").Get(repo.GitHooksEdit).
635+
Post(repo.GitHooksEditPost)
636+
}, context.GitHookService())
637+
624638
m.Group("/hooks", func() {
625639
m.Get("", repo.Webhooks)
626640
m.Post("/delete", repo.DeleteWebhook)
@@ -645,13 +659,7 @@ func RegisterRoutes(m *web.Route) {
645659
m.Post("/matrix/{id}", bindIgnErr(auth.NewMatrixHookForm{}), repo.MatrixHooksEditPost)
646660
m.Post("/msteams/{id}", bindIgnErr(auth.NewMSTeamsHookForm{}), repo.MSTeamsHooksEditPost)
647661
m.Post("/feishu/{id}", bindIgnErr(auth.NewFeishuHookForm{}), repo.FeishuHooksEditPost)
648-
649-
m.Group("/git", func() {
650-
m.Get("", repo.GitHooks)
651-
m.Combo("/{name}").Get(repo.GitHooksEdit).
652-
Post(repo.GitHooksEditPost)
653-
}, context.GitHookService())
654-
})
662+
}, webhooksEnabled)
655663

656664
m.Group("/keys", func() {
657665
m.Combo("").Get(repo.DeployKeys).

services/webhook/deliver.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,10 @@ func Deliver(t *models.HookTask) error {
141141
}
142142
}()
143143

144+
if setting.DisableWebhooks {
145+
return fmt.Errorf("Webhook task skipped (webhooks disabled): [%d]", t.ID)
146+
}
147+
144148
resp, err := webhookHTTPClient.Do(req)
145149
if err != nil {
146150
t.ResponseInfo.Body = fmt.Sprintf("Delivery: %v", err)

services/webhook/webhook.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,11 @@ func checkBranch(w *models.Webhook, branch string) bool {
120120
}
121121

122122
func prepareWebhook(w *models.Webhook, repo *models.Repository, event models.HookEventType, p api.Payloader) error {
123+
// Skip sending if webhooks are disabled.
124+
if setting.DisableWebhooks {
125+
return nil
126+
}
127+
123128
for _, e := range w.EventCheckers() {
124129
if event == e.Type {
125130
if !e.Has() {

templates/admin/navbar.tmpl

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,11 @@
1212
<a class="{{if .PageIsAdminRepositories}}active{{end}} item" href="{{AppSubUrl}}/admin/repos">
1313
{{.i18n.Tr "admin.repositories"}}
1414
</a>
15-
<a class="{{if or .PageIsAdminDefaultHooks .PageIsAdminSystemHooks}}active{{end}} item" href="{{AppSubUrl}}/admin/hooks">
16-
{{.i18n.Tr "admin.hooks"}}
17-
</a>
15+
{{if not DisableWebhooks}}
16+
<a class="{{if or .PageIsAdminDefaultHooks .PageIsAdminSystemHooks}}active{{end}} item" href="{{AppSubUrl}}/admin/hooks">
17+
{{.i18n.Tr "admin.hooks"}}
18+
</a>
19+
{{end}}
1820
<a class="{{if .PageIsAdminAuthentications}}active{{end}} item" href="{{AppSubUrl}}/admin/auths">
1921
{{.i18n.Tr "admin.authentication"}}
2022
</a>

templates/org/settings/navbar.tmpl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,11 @@
44
<a class="{{if .PageIsSettingsOptions}}active{{end}} item" href="{{.OrgLink}}/settings">
55
{{.i18n.Tr "org.settings.options"}}
66
</a>
7+
{{if not DisableWebhooks}}
78
<a class="{{if .PageIsSettingsHooks}}active{{end}} item" href="{{.OrgLink}}/settings/hooks">
89
{{.i18n.Tr "repo.settings.hooks"}}
910
</a>
11+
{{end}}
1012
<a class="{{if .PageIsOrgSettingsLabels}}active{{end}} item" href="{{.OrgLink}}/settings/labels">
1113
{{.i18n.Tr "repo.labels"}}
1214
</a>

templates/repo/settings/nav.tmpl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@
55
<li {{if .PageIsSettingsOptions}}class="current"{{end}}><a href="{{.RepoLink}}/settings">{{.i18n.Tr "repo.settings.options"}}</a></li>
66
<li {{if .PageIsSettingsCollaboration}}class="current"{{end}}><a href="{{.RepoLink}}/settings/collaboration">{{.i18n.Tr "repo.settings.collaboration"}}</a></li>
77
<li {{if .PageIsSettingsBranches}}class="current"{{end}}><a href="{{.RepoLink}}/settings/branches">{{.i18n.Tr "repo.settings.branches"}}</a></li>
8+
{{if not DisableWebhooks}}
89
<li {{if .PageIsSettingsHooks}}class="current"{{end}}><a href="{{.RepoLink}}/settings/hooks">{{.i18n.Tr "repo.settings.hooks"}}</a></li>
10+
{{end}}
911
{{if or .SignedUser.AllowGitHook .SignedUser.IsAdmin}}
1012
<li {{if .PageIsSettingsGitHooks}}class="current"{{end}}><a href="{{.RepoLink}}/settings/hooks/git">{{.i18n.Tr "repo.settings.githooks"}}</a></li>
1113
{{end}}

templates/repo/settings/navbar.tmpl

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,11 @@
1111
{{.i18n.Tr "repo.settings.branches"}}
1212
</a>
1313
{{end}}
14-
<a class="{{if .PageIsSettingsHooks}}active{{end}} item" href="{{.RepoLink}}/settings/hooks">
15-
{{.i18n.Tr "repo.settings.hooks"}}
16-
</a>
14+
{{if not DisableWebhooks}}
15+
<a class="{{if .PageIsSettingsHooks}}active{{end}} item" href="{{.RepoLink}}/settings/hooks">
16+
{{.i18n.Tr "repo.settings.hooks"}}
17+
</a>
18+
{{end}}
1719
{{if .SignedUser.CanEditGitHook}}
1820
<a class="{{if .PageIsSettingsGitHooks}}active{{end}} item" href="{{.RepoLink}}/settings/hooks/git">
1921
{{.i18n.Tr "repo.settings.githooks"}}

0 commit comments

Comments
 (0)