Skip to content
This repository has been archived by the owner on May 24, 2022. It is now read-only.

Commit

Permalink
check hmac signature
Browse files Browse the repository at this point in the history
  • Loading branch information
miguelmota committed May 6, 2019
1 parent 189b976 commit 7467359
Show file tree
Hide file tree
Showing 6 changed files with 214 additions and 8 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ start:

.PHONY: curl
curl:
@curl "http://localhost:8080/postreceive" -H 'X-Hub-Signature: mysecret'
@curl "http://localhost:8080/postreceive" -H 'X-Hub-Signature: sha1=33f9d709782f62b8b4a0178586c65ab098a39fe2'
.PHONY: release
release:
@rm -rf dist
Expand Down
15 changes: 10 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,25 @@
Installing from Go:

```bash
go get -u github.com/miguelmota/go-webhook-server/cmd/gws
$ go get -u github.com/miguelmota/go-webhook-server/cmd/gws
```

Installing pre-compiled binary:

```bash
$ wget https://github.com/miguelmota/go-webhook-server/releases/download/v0.0.4/gws_0.0.4_Linux_x86_64.tar.gz
$ tar -xvzf gws_0.0.4_Linux_x86_64.tar.gz gws
$ wget https://github.com/miguelmota/go-webhook-server/releases/download/v0.0.5/gws_0.0.5_Linux_x86_64.tar.gz
$ tar -xvzf gws_0.0.5_Linux_x86_64.tar.gz gws
$ chmod +x gws
$ sudo mv gws /usr/local/bin/gws
```

## Usage

```bash
$ gws --help
```

## Get started
## Getting started

```bash
$ export SECRET_TOKEN=mysecret
Expand All @@ -31,7 +36,7 @@ Listening on port 8080
```

```bash
$ curl "http://localhost:8080/postreceive" -X 'X-Hub-Signature: mysecret'
$ curl "http://localhost:8080/postreceive" -X 'X-Hub-Signature: sha1=33f9d709782f62b8b4a0178586c65ab098a39fe2'
hello world
```

Expand Down
26 changes: 24 additions & 2 deletions server/server.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
package server

import (
"crypto/hmac"
"crypto/sha1"
"fmt"
"io/ioutil"
"net/http"
"os/exec"
"strings"

"github.com/gorilla/mux"
)
Expand Down Expand Up @@ -47,8 +51,19 @@ func (s *Server) Start() {
// Handler ...
func (s *Server) Handler(w http.ResponseWriter, r *http.Request) {
if s.secret != "" {
secret := r.Header.Get("X-Hub-Signature")
if s.secret != secret {
headerSig := r.Header.Get("X-Hub-Signature")

b, err := ioutil.ReadAll(r.Body)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
fmt.Fprintf(w, err.Error())
return
}

sig := hmacSig(s.secret, []byte(strings.TrimSpace(string(b))))
expectedSig := fmt.Sprintf("sha1=%x", sig)
fmt.Println(expectedSig)
if headerSig != expectedSig {
w.WriteHeader(http.StatusUnauthorized)
fmt.Fprintf(w, http.StatusText(http.StatusUnauthorized))
return
Expand All @@ -65,3 +80,10 @@ func (s *Server) Handler(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
w.Write(out)
}

func hmacSig(secret string, message []byte) []byte {
hash := hmac.New(sha1.New, []byte(secret))
hash.Write(message)

return hash.Sum(nil)
}
148 changes: 148 additions & 0 deletions test/payload.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
{
"zen": "Encourage flow.",
"hook_id": 107611969,
"hook": {
"type": "Repository",
"id": 107611969,
"name": "web",
"active": true,
"events": [
"push"
],
"config": {
"content_type": "json",
"insecure_ssl": "0",
"url": "http://webhook.authereum.org/postreceive"
},
"updated_at": "2019-05-06T06:14:34Z",
"created_at": "2019-05-06T06:14:34Z",
"url": "https://api.github.com/repos/authereum/monorepo/hooks/107611969",
"test_url": "https://api.github.com/repos/authereum/monorepo/hooks/107611969/test",
"ping_url": "https://api.github.com/repos/authereum/monorepo/hooks/107611969/pings",
"last_response": {
"code": null,
"status": "unused",
"message": null
}
},
"repository": {
"id": 182465285,
"node_id": "MDEwOlJlcG9zaXRvcnkxODI0NjUyODU=",
"name": "monorepo",
"full_name": "authereum/monorepo",
"private": true,
"owner": {
"login": "authereum",
"id": 49746116,
"node_id": "MDEyOk9yZ2FuaXphdGlvbjQ5NzQ2MTE2",
"avatar_url": "https://avatars1.githubusercontent.com/u/49746116?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/authereum",
"html_url": "https://github.com/authereum",
"followers_url": "https://api.github.com/users/authereum/followers",
"following_url": "https://api.github.com/users/authereum/following{/other_user}",
"gists_url": "https://api.github.com/users/authereum/gists{/gist_id}",
"starred_url": "https://api.github.com/users/authereum/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/authereum/subscriptions",
"organizations_url": "https://api.github.com/users/authereum/orgs",
"repos_url": "https://api.github.com/users/authereum/repos",
"events_url": "https://api.github.com/users/authereum/events{/privacy}",
"received_events_url": "https://api.github.com/users/authereum/received_events",
"type": "Organization",
"site_admin": false
},
"html_url": "https://github.com/authereum/monorepo",
"description": "Authereum monorepo",
"fork": false,
"url": "https://api.github.com/repos/authereum/monorepo",
"forks_url": "https://api.github.com/repos/authereum/monorepo/forks",
"keys_url": "https://api.github.com/repos/authereum/monorepo/keys{/key_id}",
"collaborators_url": "https://api.github.com/repos/authereum/monorepo/collaborators{/collaborator}",
"teams_url": "https://api.github.com/repos/authereum/monorepo/teams",
"hooks_url": "https://api.github.com/repos/authereum/monorepo/hooks",
"issue_events_url": "https://api.github.com/repos/authereum/monorepo/issues/events{/number}",
"events_url": "https://api.github.com/repos/authereum/monorepo/events",
"assignees_url": "https://api.github.com/repos/authereum/monorepo/assignees{/user}",
"branches_url": "https://api.github.com/repos/authereum/monorepo/branches{/branch}",
"tags_url": "https://api.github.com/repos/authereum/monorepo/tags",
"blobs_url": "https://api.github.com/repos/authereum/monorepo/git/blobs{/sha}",
"git_tags_url": "https://api.github.com/repos/authereum/monorepo/git/tags{/sha}",
"git_refs_url": "https://api.github.com/repos/authereum/monorepo/git/refs{/sha}",
"trees_url": "https://api.github.com/repos/authereum/monorepo/git/trees{/sha}",
"statuses_url": "https://api.github.com/repos/authereum/monorepo/statuses/{sha}",
"languages_url": "https://api.github.com/repos/authereum/monorepo/languages",
"stargazers_url": "https://api.github.com/repos/authereum/monorepo/stargazers",
"contributors_url": "https://api.github.com/repos/authereum/monorepo/contributors",
"subscribers_url": "https://api.github.com/repos/authereum/monorepo/subscribers",
"subscription_url": "https://api.github.com/repos/authereum/monorepo/subscription",
"commits_url": "https://api.github.com/repos/authereum/monorepo/commits{/sha}",
"git_commits_url": "https://api.github.com/repos/authereum/monorepo/git/commits{/sha}",
"comments_url": "https://api.github.com/repos/authereum/monorepo/comments{/number}",
"issue_comment_url": "https://api.github.com/repos/authereum/monorepo/issues/comments{/number}",
"contents_url": "https://api.github.com/repos/authereum/monorepo/contents/{+path}",
"compare_url": "https://api.github.com/repos/authereum/monorepo/compare/{base}...{head}",
"merges_url": "https://api.github.com/repos/authereum/monorepo/merges",
"archive_url": "https://api.github.com/repos/authereum/monorepo/{archive_format}{/ref}",
"downloads_url": "https://api.github.com/repos/authereum/monorepo/downloads",
"issues_url": "https://api.github.com/repos/authereum/monorepo/issues{/number}",
"pulls_url": "https://api.github.com/repos/authereum/monorepo/pulls{/number}",
"milestones_url": "https://api.github.com/repos/authereum/monorepo/milestones{/number}",
"notifications_url": "https://api.github.com/repos/authereum/monorepo/notifications{?since,all,participating}",
"labels_url": "https://api.github.com/repos/authereum/monorepo/labels{/name}",
"releases_url": "https://api.github.com/repos/authereum/monorepo/releases{/id}",
"deployments_url": "https://api.github.com/repos/authereum/monorepo/deployments",
"created_at": "2019-04-20T23:52:32Z",
"updated_at": "2019-05-05T21:11:39Z",
"pushed_at": "2019-05-06T00:12:26Z",
"git_url": "git://github.com/authereum/monorepo.git",
"ssh_url": "[email protected]:authereum/monorepo.git",
"clone_url": "https://github.com/authereum/monorepo.git",
"svn_url": "https://github.com/authereum/monorepo",
"homepage": "",
"size": 669,
"stargazers_count": 2,
"watchers_count": 2,
"language": "TypeScript",
"has_issues": true,
"has_projects": true,
"has_downloads": true,
"has_wiki": true,
"has_pages": false,
"forks_count": 0,
"mirror_url": null,
"archived": false,
"disabled": false,
"open_issues_count": 1,
"license": {
"key": "mit",
"name": "MIT License",
"spdx_id": "MIT",
"url": "https://api.github.com/licenses/mit",
"node_id": "MDc6TGljZW5zZTEz"
},
"forks": 0,
"open_issues": 1,
"watchers": 2,
"default_branch": "master"
},
"sender": {
"login": "miguelmota",
"id": 168240,
"node_id": "MDQ6VXNlcjE2ODI0MA==",
"avatar_url": "https://avatars1.githubusercontent.com/u/168240?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/miguelmota",
"html_url": "https://github.com/miguelmota",
"followers_url": "https://api.github.com/users/miguelmota/followers",
"following_url": "https://api.github.com/users/miguelmota/following{/other_user}",
"gists_url": "https://api.github.com/users/miguelmota/gists{/gist_id}",
"starred_url": "https://api.github.com/users/miguelmota/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/miguelmota/subscriptions",
"organizations_url": "https://api.github.com/users/miguelmota/orgs",
"repos_url": "https://api.github.com/users/miguelmota/repos",
"events_url": "https://api.github.com/users/miguelmota/events{/privacy}",
"received_events_url": "https://api.github.com/users/miguelmota/received_events",
"type": "User",
"site_admin": false
}
}
1 change: 1 addition & 0 deletions test/payload.min.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"zen":"Encourage flow.","hook_id":107611969,"hook":{"type":"Repository","id":107611969,"name":"web","active":true,"events":["push"],"config":{"content_type":"json","insecure_ssl":"0","url":"http://webhook.authereum.org/postreceive"},"updated_at":"2019-05-06T06:14:34Z","created_at":"2019-05-06T06:14:34Z","url":"https://api.github.com/repos/authereum/monorepo/hooks/107611969","test_url":"https://api.github.com/repos/authereum/monorepo/hooks/107611969/test","ping_url":"https://api.github.com/repos/authereum/monorepo/hooks/107611969/pings","last_response":{"code":null,"status":"unused","message":null}},"repository":{"id":182465285,"node_id":"MDEwOlJlcG9zaXRvcnkxODI0NjUyODU=","name":"monorepo","full_name":"authereum/monorepo","private":true,"owner":{"login":"authereum","id":49746116,"node_id":"MDEyOk9yZ2FuaXphdGlvbjQ5NzQ2MTE2","avatar_url":"https://avatars1.githubusercontent.com/u/49746116?v=4","gravatar_id":"","url":"https://api.github.com/users/authereum","html_url":"https://github.com/authereum","followers_url":"https://api.github.com/users/authereum/followers","following_url":"https://api.github.com/users/authereum/following{/other_user}","gists_url":"https://api.github.com/users/authereum/gists{/gist_id}","starred_url":"https://api.github.com/users/authereum/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/authereum/subscriptions","organizations_url":"https://api.github.com/users/authereum/orgs","repos_url":"https://api.github.com/users/authereum/repos","events_url":"https://api.github.com/users/authereum/events{/privacy}","received_events_url":"https://api.github.com/users/authereum/received_events","type":"Organization","site_admin":false},"html_url":"https://github.com/authereum/monorepo","description":"Authereum monorepo","fork":false,"url":"https://api.github.com/repos/authereum/monorepo","forks_url":"https://api.github.com/repos/authereum/monorepo/forks","keys_url":"https://api.github.com/repos/authereum/monorepo/keys{/key_id}","collaborators_url":"https://api.github.com/repos/authereum/monorepo/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/authereum/monorepo/teams","hooks_url":"https://api.github.com/repos/authereum/monorepo/hooks","issue_events_url":"https://api.github.com/repos/authereum/monorepo/issues/events{/number}","events_url":"https://api.github.com/repos/authereum/monorepo/events","assignees_url":"https://api.github.com/repos/authereum/monorepo/assignees{/user}","branches_url":"https://api.github.com/repos/authereum/monorepo/branches{/branch}","tags_url":"https://api.github.com/repos/authereum/monorepo/tags","blobs_url":"https://api.github.com/repos/authereum/monorepo/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/authereum/monorepo/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/authereum/monorepo/git/refs{/sha}","trees_url":"https://api.github.com/repos/authereum/monorepo/git/trees{/sha}","statuses_url":"https://api.github.com/repos/authereum/monorepo/statuses/{sha}","languages_url":"https://api.github.com/repos/authereum/monorepo/languages","stargazers_url":"https://api.github.com/repos/authereum/monorepo/stargazers","contributors_url":"https://api.github.com/repos/authereum/monorepo/contributors","subscribers_url":"https://api.github.com/repos/authereum/monorepo/subscribers","subscription_url":"https://api.github.com/repos/authereum/monorepo/subscription","commits_url":"https://api.github.com/repos/authereum/monorepo/commits{/sha}","git_commits_url":"https://api.github.com/repos/authereum/monorepo/git/commits{/sha}","comments_url":"https://api.github.com/repos/authereum/monorepo/comments{/number}","issue_comment_url":"https://api.github.com/repos/authereum/monorepo/issues/comments{/number}","contents_url":"https://api.github.com/repos/authereum/monorepo/contents/{+path}","compare_url":"https://api.github.com/repos/authereum/monorepo/compare/{base}...{head}","merges_url":"https://api.github.com/repos/authereum/monorepo/merges","archive_url":"https://api.github.com/repos/authereum/monorepo/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/authereum/monorepo/downloads","issues_url":"https://api.github.com/repos/authereum/monorepo/issues{/number}","pulls_url":"https://api.github.com/repos/authereum/monorepo/pulls{/number}","milestones_url":"https://api.github.com/repos/authereum/monorepo/milestones{/number}","notifications_url":"https://api.github.com/repos/authereum/monorepo/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/authereum/monorepo/labels{/name}","releases_url":"https://api.github.com/repos/authereum/monorepo/releases{/id}","deployments_url":"https://api.github.com/repos/authereum/monorepo/deployments","created_at":"2019-04-20T23:52:32Z","updated_at":"2019-05-05T21:11:39Z","pushed_at":"2019-05-06T00:12:26Z","git_url":"git://github.com/authereum/monorepo.git","ssh_url":"[email protected]:authereum/monorepo.git","clone_url":"https://github.com/authereum/monorepo.git","svn_url":"https://github.com/authereum/monorepo","homepage":"","size":669,"stargazers_count":2,"watchers_count":2,"language":"TypeScript","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"disabled":false,"open_issues_count":1,"license":{"key":"mit","name":"MIT License","spdx_id":"MIT","url":"https://api.github.com/licenses/mit","node_id":"MDc6TGljZW5zZTEz"},"forks":0,"open_issues":1,"watchers":2,"default_branch":"master"},"sender":{"login":"miguelmota","id":168240,"node_id":"MDQ6VXNlcjE2ODI0MA==","avatar_url":"https://avatars1.githubusercontent.com/u/168240?v=4","gravatar_id":"","url":"https://api.github.com/users/miguelmota","html_url":"https://github.com/miguelmota","followers_url":"https://api.github.com/users/miguelmota/followers","following_url":"https://api.github.com/users/miguelmota/following{/other_user}","gists_url":"https://api.github.com/users/miguelmota/gists{/gist_id}","starred_url":"https://api.github.com/users/miguelmota/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/miguelmota/subscriptions","organizations_url":"https://api.github.com/users/miguelmota/orgs","repos_url":"https://api.github.com/users/miguelmota/repos","events_url":"https://api.github.com/users/miguelmota/events{/privacy}","received_events_url":"https://api.github.com/users/miguelmota/received_events","type":"User","site_admin":false}}
30 changes: 30 additions & 0 deletions test/test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package main

import (
"crypto/hmac"
"crypto/sha1"
"encoding/hex"
"fmt"
"io/ioutil"
"strings"
)

// TODO: proper tests

func main() {
data, err := ioutil.ReadFile("test/payload.min.json")
if err != nil {
panic(err)
}

secret := []byte("authereum")
message := []byte(strings.TrimSpace(string(data)))

hash := hmac.New(sha1.New, secret)
hash.Write(message)

fmt.Println(hex.EncodeToString(hash.Sum(nil)))
expected := "de05ddb9b629dabf1617f99fc6bcc74ca188a0d3"
fmt.Println(expected)
// "X-Hub-Signature: sha1=de05ddb9b629dabf1617f99fc6bcc74ca188a0d3"
}

0 comments on commit 7467359

Please sign in to comment.