Skip to content

Commit

Permalink
support secret token in gitlab changehook
Browse files Browse the repository at this point in the history
  • Loading branch information
sbidoul committed Mar 21, 2017
1 parent 282d9ef commit dc0b909
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 3 deletions.
@@ -0,0 +1 @@
:py:class: `~buildbot.status.web.hooks.gitlab` now supports authentication with the secret token
31 changes: 31 additions & 0 deletions master/buildbot/test/unit/test_www_hooks_gitlab.py
Expand Up @@ -26,6 +26,7 @@
import buildbot.www.change_hook as change_hook
from buildbot.test.fake.web import FakeRequest
from buildbot.test.fake.web import fakeMasterForHooks
from buildbot.www.hooks.gitlab import _HEADER_GITLAB_TOKEN


# Sample GITHUB commit payload from http://help.github.com/post-receive-hooks/
Expand Down Expand Up @@ -218,3 +219,33 @@ def check_changes(r):

d.addCallback(check_changes)
return d


class TestChangeHookConfiguredWithSecret(unittest.TestCase):

_SECRET = 'thesecret'

def setUp(self):
self.changeHook = change_hook.ChangeHookResource(
dialects={'gitlab': {'secret': self._SECRET}},
master=fakeMasterForHooks())

@defer.inlineCallbacks
def test_missing_secret(self):
self.request = FakeRequest(content=gitJsonPayloadTag)
self.request.uri = "/change_hook/gitlab"
self.request.args = {'codebase': ['MyCodebase']}
self.request.method = "POST"
yield self.request.test_render(self.changeHook)
expected = b'Invalid secret'
self.assertEqual(self.request.written, expected)
self.assertEqual(len(self.changeHook.master.addedChanges), 0)

@defer.inlineCallbacks
def test_valid_secret(self):
self.request = FakeRequest(content=gitJsonPayload)
self.request.received_headers[_HEADER_GITLAB_TOKEN] = self._SECRET
self.request.uri = "/change_hook/gitlab"
self.request.method = "POST"
yield self.request.test_render(self.changeHook)
self.assertEqual(len(self.changeHook.master.addedChanges), 2)
8 changes: 8 additions & 0 deletions master/buildbot/www/hooks/gitlab.py
Expand Up @@ -24,6 +24,9 @@
from twisted.python import log


_HEADER_GITLAB_TOKEN = b'X-Gitlab-Token'


def _process_change(payload, user, repo, repo_url, project, codebase=None):
"""
Consumes the JSON as a python object and actually starts the build.
Expand Down Expand Up @@ -90,6 +93,11 @@ def getChanges(request, options=None):
request
the http request object
"""
expected_secret = isinstance(options, dict) and options.get('secret')
if expected_secret:
received_secret = request.getHeader(_HEADER_GITLAB_TOKEN)
if received_secret != expected_secret:
raise ValueError("Invalid secret")
try:
payload = json.load(request.content)
except Exception as e:
Expand Down
12 changes: 9 additions & 3 deletions master/docs/manual/cfg-wwwhooks.rst
Expand Up @@ -242,7 +242,11 @@ The GitLab hook is as simple as GitHub one and it also takes no options.
::

c['www'] = dict(...,
change_hook_dialects={ 'gitlab' : True }
change_hook_dialects={
'gitlab' : {
'secret': '...',
},
},
)

When this is setup you should add a `POST` service pointing to ``/change_hook/gitlab`` relative to the root of the web status.
Expand All @@ -259,8 +263,10 @@ These parameters will be passed along to the scheduler.
As in the previous case, the incoming HTTP requests for this hook are not authenticated by default.
Anyone who can access the web status can "fake" a request from your GitLab server, potentially causing the buildmaster to run arbitrary code.

To protect URL against unauthorized access you should use :ref:`Change-Hooks-Auth` option.
Then, create a GitLab service hook (see ``https://your.gitlab.server/help/web_hooks``) with a WebHook URL like ``https://user:password@builds.example.com/bbot/change_hook/gitlab``.
To protect URL against unauthorized access you should either

* set secret token in the configuration above, then set it in the GitLab service hook declaration, or
* use the :ref:`Change-Hooks-Auth` option. Then, create a GitLab service hook (see ``https://your.gitlab.server/help/web_hooks``) with a WebHook URL like ``https://user:password@builds.example.com/bbot/change_hook/gitlab``.

Note that as before, not using ``change_hook_auth`` can expose you to security risks.

Expand Down

0 comments on commit dc0b909

Please sign in to comment.