Skip to content

Commit e90358e

Browse files
committed
Verify git checkout path is in site directory
This is unlikely, as we verify inputs come from GitHub using signatures, but it's best to be safe about this.
1 parent 61de8b0 commit e90358e

File tree

2 files changed

+14
-1
lines changed

2 files changed

+14
-1
lines changed

test_webhook.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,14 @@ async def test_github_webhook_errors(aiohttp_client, monkeypatch):
121121
assert resp.status == 400
122122
assert 'incorrect repository' in await resp.text()
123123

124+
# Fields provided, but invalid.
125+
resp = await client.post(
126+
'/gh/non-existent-repo', headers=valid_headers,
127+
data='{"sender": {"login": "QuLogic"}, "repository":'
128+
' {"name": "..", "owner": {"login": "matplotlib"}}}')
129+
assert resp.status == 400
130+
assert 'incorrect repository' in await resp.text()
131+
124132
# Problem on our side.
125133
resp = await client.post(
126134
'/gh/non-existent',

webhook.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,12 @@ async def github_webhook(request: web.Request):
156156
delivery, ref, expected_branch)
157157
return web.Response(status=200)
158158

159-
checkout = Path(os.environ.get('SITE_DIR', 'sites'), repository)
159+
site_dir = Path(os.environ.get('SITE_DIR', 'sites')).resolve()
160+
checkout = (site_dir / repository).resolve()
161+
if not checkout.is_relative_to(site_dir):
162+
raise web.HTTPBadRequest(
163+
reason=(f'{delivery}: Checkout for {organization}/{repository} '
164+
'does not exist'))
160165
if not (checkout / '.git').is_dir():
161166
raise web.HTTPInternalServerError(
162167
reason=(f'{delivery}: Checkout for {organization}/{repository} '

0 commit comments

Comments
 (0)