Skip to content

Commit bae852c

Browse files
committed
add secret check
1 parent 8d445a4 commit bae852c

19 files changed

+3856
-3801
lines changed

gitea/gitea.go

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
package gitea
22

33
import (
4+
"crypto/hmac"
5+
"crypto/sha256"
6+
"encoding/hex"
47
"encoding/json"
58
"errors"
69
"fmt"
@@ -11,10 +14,12 @@ import (
1114

1215
// parse errors
1316
var (
14-
ErrEventNotSpecifiedToParse = errors.New("no Event specified to parse")
15-
ErrInvalidHTTPMethod = errors.New("invalid HTTP Method")
16-
ErrMissingGiteaEventHeader = errors.New("missing X-Gitea-Event Header")
17-
ErrParsingPayload = errors.New("error parsing payload")
17+
ErrEventNotSpecifiedToParse = errors.New("no Event specified to parse")
18+
ErrInvalidHTTPMethod = errors.New("invalid HTTP Method")
19+
ErrMissingGiteaEventHeader = errors.New("missing X-Gitea-Event Header")
20+
ErrMissingGiteaSignatureHeader = errors.New("missing X-Gitea-Signature Header")
21+
ErrParsingPayload = errors.New("error parsing payload")
22+
ErrHMACVerificationFailed = errors.New("HMAC verification failed")
1823
)
1924

2025
// Gitea hook types
@@ -102,6 +107,21 @@ func (hook Webhook) Parse(r *http.Request, events ...Event) (interface{}, error)
102107
return nil, ErrParsingPayload
103108
}
104109

110+
// If we have a Secret set, we should check the MAC
111+
if len(hook.secret) > 0 {
112+
signature := r.Header.Get("X-Gitea-Signature")
113+
if len(signature) == 0 {
114+
return nil, ErrMissingGiteaSignatureHeader
115+
}
116+
sig256 := hmac.New(sha256.New, []byte(hook.secret))
117+
_, _ = io.Writer(sig256).Write([]byte(payload))
118+
expectedMAC := hex.EncodeToString(sig256.Sum(nil))
119+
120+
if !hmac.Equal([]byte(signature), []byte(expectedMAC)) {
121+
return nil, ErrHMACVerificationFailed
122+
}
123+
}
124+
105125
// https://github.com/go-gitea/gitea/blob/33fca2b537d36cf998dd27425b2bb8ed5b0965f3/services/webhook/payloader.go#L27
106126
switch giteaEvent {
107127
case CreateEvent:

gitea/gitea_test.go

Lines changed: 52 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,24 @@ func TestBadRequests(t *testing.T) {
7979
"X-Gitea-Event": []string{"push"},
8080
},
8181
},
82+
{
83+
name: "BadSignatureLength",
84+
event: PushEvent,
85+
payload: bytes.NewBuffer([]byte("{}")),
86+
headers: http.Header{
87+
"X-Github-Event": []string{"push"},
88+
"X-Gitea-Signature": []string{""},
89+
},
90+
},
91+
{
92+
name: "BadSignatureMatch",
93+
event: PushEvent,
94+
payload: bytes.NewBuffer([]byte("{}")),
95+
headers: http.Header{
96+
"X-Github-Event": []string{"push"},
97+
"X-Gitea-Signature": []string{"111"},
98+
},
99+
},
82100
}
83101

84102
for _, tt := range tests {
@@ -119,7 +137,8 @@ func TestWebhooks(t *testing.T) {
119137
typ: CreatePayload{},
120138
filename: "../testdata/gitea/create-event.json",
121139
headers: http.Header{
122-
"X-Gitea-Event": []string{"create"},
140+
"X-Gitea-Event": []string{"create"},
141+
"X-Gitea-Signature": []string{"6f250ac7a090096574758e31bd31770eab63dfd0459404f0c18431f1c6b9024a"},
123142
},
124143
},
125144
{
@@ -128,7 +147,8 @@ func TestWebhooks(t *testing.T) {
128147
typ: DeletePayload{},
129148
filename: "../testdata/gitea/delete-event.json",
130149
headers: http.Header{
131-
"X-Gitea-Event": []string{"delete"},
150+
"X-Gitea-Event": []string{"delete"},
151+
"X-Gitea-Signature": []string{"84307b509e663cd897bc719b2a564e64fa4af8716fda389488f18369139e0fdd"},
132152
},
133153
},
134154
{
@@ -137,7 +157,8 @@ func TestWebhooks(t *testing.T) {
137157
typ: ForkPayload{},
138158
filename: "../testdata/gitea/fork-event.json",
139159
headers: http.Header{
140-
"X-Gitea-Event": []string{"fork"},
160+
"X-Gitea-Event": []string{"fork"},
161+
"X-Gitea-Signature": []string{"b7750f34adeaf333ac83a1fadcda4cbac097c8587e8dda297c3e7f059012215f"},
141162
},
142163
},
143164
{
@@ -146,7 +167,8 @@ func TestWebhooks(t *testing.T) {
146167
typ: IssuePayload{},
147168
filename: "../testdata/gitea/issues-event.json",
148169
headers: http.Header{
149-
"X-Gitea-Event": []string{"issues"},
170+
"X-Gitea-Event": []string{"issues"},
171+
"X-Gitea-Signature": []string{"98c44fd0ae42ca4208eac6f81e59b436837740abc8693bf828366b32d33b1cbc"},
150172
},
151173
},
152174
{
@@ -155,7 +177,8 @@ func TestWebhooks(t *testing.T) {
155177
typ: IssuePayload{},
156178
filename: "../testdata/gitea/issue-assign-event.json",
157179
headers: http.Header{
158-
"X-Gitea-Event": []string{"issue_assign"},
180+
"X-Gitea-Event": []string{"issue_assign"},
181+
"X-Gitea-Signature": []string{"7d2adaf2fb3dc3769294c737ff48da003b7c3660b4f917b85c2c25dabd34a13c"},
159182
},
160183
},
161184
{
@@ -164,7 +187,8 @@ func TestWebhooks(t *testing.T) {
164187
typ: IssuePayload{},
165188
filename: "../testdata/gitea/issue-label-event.json",
166189
headers: http.Header{
167-
"X-Gitea-Event": []string{"issue_label"},
190+
"X-Gitea-Event": []string{"issue_label"},
191+
"X-Gitea-Signature": []string{"3611415860ed5904c87dd589a7c5fa7e87d2a72b0b2a92ea149ba9691ba8c785"},
168192
},
169193
},
170194
{
@@ -173,7 +197,8 @@ func TestWebhooks(t *testing.T) {
173197
typ: IssuePayload{},
174198
filename: "../testdata/gitea/issue-milestone-event.json",
175199
headers: http.Header{
176-
"X-Gitea-Event": []string{"issue_milestone"},
200+
"X-Gitea-Event": []string{"issue_milestone"},
201+
"X-Gitea-Signature": []string{"4b782b02035ca264c8e7782b8f2eb9d64e4a61344a1bc3a08fa85d7eed1e77b5"},
177202
},
178203
},
179204
{
@@ -182,7 +207,8 @@ func TestWebhooks(t *testing.T) {
182207
typ: IssueCommentPayload{},
183208
filename: "../testdata/gitea/issue-comment-event.json",
184209
headers: http.Header{
185-
"X-Gitea-Event": []string{"issue_comment"},
210+
"X-Gitea-Event": []string{"issue_comment"},
211+
"X-Gitea-Signature": []string{"690180a8c853460cba88f9b09911a531d449e9f63ed6b1ff0a0def3b972ca744"},
186212
},
187213
},
188214
{
@@ -191,7 +217,8 @@ func TestWebhooks(t *testing.T) {
191217
typ: PushPayload{},
192218
filename: "../testdata/gitea/push-event.json",
193219
headers: http.Header{
194-
"X-Gitea-Event": []string{"push"},
220+
"X-Gitea-Event": []string{"push"},
221+
"X-Gitea-Signature": []string{"60fe446c74fa0cb9474f98cc557db79e10c7aaf22cf324ad65239600b9e4d915"},
195222
},
196223
},
197224
{
@@ -200,7 +227,8 @@ func TestWebhooks(t *testing.T) {
200227
typ: PullRequestPayload{},
201228
filename: "../testdata/gitea/pull-request-event.json",
202229
headers: http.Header{
203-
"X-Gitea-Event": []string{"pull_request"},
230+
"X-Gitea-Event": []string{"pull_request"},
231+
"X-Gitea-Signature": []string{"65c18a212efc7bde0f336acaec87f596fe20e80b2a0e7e51a790dd38393ff771"},
204232
},
205233
},
206234
{
@@ -209,7 +237,8 @@ func TestWebhooks(t *testing.T) {
209237
typ: PullRequestPayload{},
210238
filename: "../testdata/gitea/pull-request-assign-event.json",
211239
headers: http.Header{
212-
"X-Gitea-Event": []string{"pull_request_assign"},
240+
"X-Gitea-Event": []string{"pull_request_assign"},
241+
"X-Gitea-Signature": []string{"6e96f0515898d427d87fc022cef60e4a02695739e8eae05f8cccd79b2ce4809a"},
213242
},
214243
},
215244
{
@@ -218,7 +247,8 @@ func TestWebhooks(t *testing.T) {
218247
typ: PullRequestPayload{},
219248
filename: "../testdata/gitea/pull-request-label-event.json",
220249
headers: http.Header{
221-
"X-Gitea-Event": []string{"pull_request_label"},
250+
"X-Gitea-Event": []string{"pull_request_label"},
251+
"X-Gitea-Signature": []string{"c52fa035b8d9ac4d94449349b16bac5892bc59faa72be19ff39f33b6bc24315a"},
222252
},
223253
},
224254
{
@@ -227,7 +257,8 @@ func TestWebhooks(t *testing.T) {
227257
typ: PullRequestPayload{},
228258
filename: "../testdata/gitea/pull-request-milestone-event.json",
229259
headers: http.Header{
230-
"X-Gitea-Event": []string{"pull_request_milestone"},
260+
"X-Gitea-Event": []string{"pull_request_milestone"},
261+
"X-Gitea-Signature": []string{"38b2cf88e15b15795371517cb4121a92c7db1116f83eba57c13c192a7e0730dc"},
231262
},
232263
},
233264
{
@@ -236,7 +267,8 @@ func TestWebhooks(t *testing.T) {
236267
typ: IssueCommentPayload{},
237268
filename: "../testdata/gitea/pull-request-comment-event.json",
238269
headers: http.Header{
239-
"X-Gitea-Event": []string{"pull_request_comment"},
270+
"X-Gitea-Event": []string{"pull_request_comment"},
271+
"X-Gitea-Signature": []string{"8b38bf221adbaef2ce01cfa810c6d9cb977414fec306895973aea61e10e8d5a8"},
240272
},
241273
},
242274
{
@@ -245,7 +277,8 @@ func TestWebhooks(t *testing.T) {
245277
typ: PullRequestPayload{},
246278
filename: "../testdata/gitea/pull-request-review-event.json",
247279
headers: http.Header{
248-
"X-Gitea-Event": []string{"pull_request_review"},
280+
"X-Gitea-Event": []string{"pull_request_review"},
281+
"X-Gitea-Signature": []string{"5d5c315cc199807a23da81b788dcf7874299a223ba81fc77d76ab248fdab4d1c"},
249282
},
250283
},
251284
{
@@ -254,7 +287,8 @@ func TestWebhooks(t *testing.T) {
254287
typ: RepositoryPayload{},
255288
filename: "../testdata/gitea/repository-event.json",
256289
headers: http.Header{
257-
"X-Gitea-Event": []string{"repository"},
290+
"X-Gitea-Event": []string{"repository"},
291+
"X-Gitea-Signature": []string{"52ca39cfb873254a9cbbda10f8a878f9df16216da6ae92267fc81352ac685d97"},
258292
},
259293
},
260294
{
@@ -263,7 +297,8 @@ func TestWebhooks(t *testing.T) {
263297
typ: ReleasePayload{},
264298
filename: "../testdata/gitea/release-event.json",
265299
headers: http.Header{
266-
"X-Gitea-Event": []string{"release"},
300+
"X-Gitea-Event": []string{"release"},
301+
"X-Gitea-Signature": []string{"847fcef001c2e59dadac3fa5fa01ca26c9985a5faa10e48a9868a8ad98e9dd18"},
267302
},
268303
},
269304
}

0 commit comments

Comments
 (0)