Skip to content

Don't assume github.com for the repo origin for GitHub Webhooks #639

@wmikita

Description

@wmikita

Problem

GitHub is not the only code forge that implements GitHub-style webhooks, yet ContentDB insists that it is with some very silly string concatenation:

@bp.route("/github/webhook/", methods=["POST"])
@csrf.exempt
def github_webhook():
json = request.json
header_signature = request.headers.get('X-Hub-Signature')
if header_signature is None:
return error(403, "Expected payload signature")
token = _find_api_token(header_signature)
packages = get_packages_for_vcs_and_token(token, "github.com/" + json["repository"]["full_name"])

This prevents e.g. Forgejo users (and that Codeberg share is growing by the day) from using webhooks, having to rely instead on CDB update detection, which is slower and had some breakages in the past.

Image

On the above screenshot, the bottom delivery used a token bound to rudzik8/mcl_emerald_stuff; the top one used an unbound token.

Solutions

Just pull the repo URL from JSON, which in this case would be https://codeberg.org/rudzik8/mcl_emerald_stuff and would match the one in the delivery.

Alternatives

Make a separate Forgejo webhook, which seems redundant to me, unless some compatibility issues arise from just lifting this silly github.com limitation.

Additional context

1st delivery with package-bound token

Headers:

Request URL: https://content.luanti.org/github/webhook/
Request method: POST
Content-Type: application/json
X-Forgejo-Delivery: 6732acc6-2487-4b33-ad1a-5980d44bfe9c
X-Forgejo-Event: push
X-Forgejo-Event-Type: push
X-Forgejo-Signature: 95615c3d66c76aa76edbd0a038e4884637759269b8044acf285c7d34eb804a26
X-GitHub-Delivery: 6732acc6-2487-4b33-ad1a-5980d44bfe9c
X-GitHub-Event: push
X-GitHub-Event-Type: push
X-Gitea-Delivery: 6732acc6-2487-4b33-ad1a-5980d44bfe9c
X-Gitea-Event: push
X-Gitea-Event-Type: push
X-Gitea-Signature: 95615c3d66c76aa76edbd0a038e4884637759269b8044acf285c7d34eb804a26
X-Gogs-Delivery: 6732acc6-2487-4b33-ad1a-5980d44bfe9c
X-Gogs-Event: push
X-Gogs-Event-Type: push
X-Gogs-Signature: 95615c3d66c76aa76edbd0a038e4884637759269b8044acf285c7d34eb804a26
X-Hub-Signature: sha1=27774980684c659f89f65b614046342a3744e4c6
X-Hub-Signature-256: sha256=95615c3d66c76aa76edbd0a038e4884637759269b8044acf285c7d34eb804a26

Content:

{
  "ref": "refs/heads/main",
  "before": "203bdfeb76fd9cc34f2cc6f920f2c07c87cdf1fb",
  "after": "4e189eeae39e99e30e8c41fb16def73d4b450b1d",
  "compare_url": "https://codeberg.org/rudzik8/mcl_emerald_stuff/compare/203bdfeb76fd9cc34f2cc6f920f2c07c87cdf1fb...4e189eeae39e99e30e8c41fb16def73d4b450b1d",
  "commits": [
    {
      "id": "4e189eeae39e99e30e8c41fb16def73d4b450b1d",
      "message": "Update mod.conf\n",
      "url": "https://codeberg.org/rudzik8/mcl_emerald_stuff/commit/4e189eeae39e99e30e8c41fb16def73d4b450b1d",
      "author": {
        "name": "Mikita Wiśniewski",
        "email": "rudzik8@protonmail.com",
        "username": "rudzik8"
      },
      "committer": {
        "name": "Mikita Wiśniewski",
        "email": "rudzik8@protonmail.com",
        "username": "rudzik8"
      },
      "verification": null,
      "timestamp": "2026-03-14T13:37:51+07:00",
      "added": [],
      "removed": [],
      "modified": [
        "mod.conf"
      ]
    }
  ],
  "total_commits": 1,
  "head_commit": {
    "id": "4e189eeae39e99e30e8c41fb16def73d4b450b1d",
    "message": "Update mod.conf\n",
    "url": "https://codeberg.org/rudzik8/mcl_emerald_stuff/commit/4e189eeae39e99e30e8c41fb16def73d4b450b1d",
    "author": {
      "name": "Mikita Wiśniewski",
      "email": "rudzik8@protonmail.com",
      "username": "rudzik8"
    },
    "committer": {
      "name": "Mikita Wiśniewski",
      "email": "rudzik8@protonmail.com",
      "username": "rudzik8"
    },
    "verification": null,
    "timestamp": "2026-03-14T13:37:51+07:00",
    "added": [],
    "removed": [],
    "modified": [
      "mod.conf"
    ]
  },
  "repository": {
    "id": 108009,
    "owner": {
      "id": 70442,
      "login": "rudzik8",
      "login_name": "",
      "source_id": 0,
      "full_name": "Mikita Wiśniewski",
      "email": "rudzik8@protonmail.com",
      "avatar_url": "https://codeberg.org/avatars/52fc6869117fce7599f54d289d10670e9f478fcb09a8782bc45349b849dc46f0",
      "html_url": "https://codeberg.org/rudzik8",
      "language": "",
      "is_admin": false,
      "last_login": "0001-01-01T00:00:00Z",
      "created": "2022-11-06T12:14:25+01:00",
      "restricted": false,
      "active": false,
      "prohibit_login": false,
      "location": "pos: (-1726.8, 9.3, 423.2)",
      "pronouns": "he/him",
      "website": "https://rudzik8.bearblog.dev/",
      "description": "Siberian 17yo FOSS gamedev enthusiast, Luanti player and modder, Voxelgarden maintainer and a Mineclonia developer",
      "visibility": "public",
      "followers_count": 6,
      "following_count": 20,
      "starred_repos_count": 11,
      "username": "rudzik8"
    },
    "name": "mcl_emerald_stuff",
    "full_name": "rudzik8/mcl_emerald_stuff",
    "description": "Adds emerald tools and armor to VoxeLibre (ex. MineClone2)",
    "empty": false,
    "private": false,
    "fork": false,
    "template": false,
    "parent": null,
    "mirror": false,
    "size": 265,
    "language": "",
    "languages_url": "https://codeberg.org/api/v1/repos/rudzik8/mcl_emerald_stuff/languages",
    "html_url": "https://codeberg.org/rudzik8/mcl_emerald_stuff",
    "url": "https://codeberg.org/api/v1/repos/rudzik8/mcl_emerald_stuff",
    "link": "",
    "ssh_url": "ssh://git@codeberg.org/rudzik8/mcl_emerald_stuff.git",
    "clone_url": "https://codeberg.org/rudzik8/mcl_emerald_stuff.git",
    "original_url": "https://git.minetest.land/rudzik8/mcl_emerald_stuff.git",
    "website": "",
    "stars_count": 0,
    "forks_count": 3,
    "watchers_count": 1,
    "open_issues_count": 0,
    "open_pr_counter": 0,
    "release_counter": 0,
    "default_branch": "main",
    "archived": false,
    "created_at": "2023-04-23T13:17:26+02:00",
    "updated_at": "2026-03-14T07:27:52+01:00",
    "archived_at": "1970-01-01T01:00:00+01:00",
    "permissions": {
      "admin": true,
      "push": true,
      "pull": true
    },
    "has_issues": true,
    "internal_tracker": {
      "enable_time_tracker": true,
      "allow_only_contributors_to_track_time": true,
      "enable_issue_dependencies": true
    },
    "has_wiki": true,
    "wiki_branch": "master",
    "globally_editable_wiki": false,
    "has_pull_requests": true,
    "has_projects": true,
    "has_releases": true,
    "has_packages": true,
    "has_actions": false,
    "ignore_whitespace_conflicts": false,
    "allow_merge_commits": true,
    "allow_rebase": true,
    "allow_rebase_explicit": true,
    "allow_squash_merge": true,
    "allow_fast_forward_only_merge": false,
    "allow_rebase_update": true,
    "default_delete_branch_after_merge": false,
    "default_merge_style": "merge",
    "default_allow_maintainer_edit": false,
    "default_update_style": "merge",
    "avatar_url": "",
    "internal": false,
    "mirror_interval": "",
    "object_format_name": "sha1",
    "mirror_updated": "0001-01-01T00:00:00Z",
    "repo_transfer": null,
    "topics": [
      "minetest",
      "mcl",
      "mcl2"
    ]
  },
  "pusher": {
    "id": 70442,
    "login": "rudzik8",
    "login_name": "",
    "source_id": 0,
    "full_name": "Mikita Wiśniewski",
    "email": "rudzik8@noreply.codeberg.org",
    "avatar_url": "https://codeberg.org/avatars/52fc6869117fce7599f54d289d10670e9f478fcb09a8782bc45349b849dc46f0",
    "html_url": "https://codeberg.org/rudzik8",
    "language": "",
    "is_admin": false,
    "last_login": "0001-01-01T00:00:00Z",
    "created": "2022-11-06T12:14:25+01:00",
    "restricted": false,
    "active": false,
    "prohibit_login": false,
    "location": "pos: (-1726.8, 9.3, 423.2)",
    "pronouns": "he/him",
    "website": "https://rudzik8.bearblog.dev/",
    "description": "Siberian 17yo FOSS gamedev enthusiast, Luanti player and modder, Voxelgarden maintainer and a Mineclonia developer",
    "visibility": "public",
    "followers_count": 6,
    "following_count": 20,
    "starred_repos_count": 11,
    "username": "rudzik8"
  },
  "sender": {
    "id": 70442,
    "login": "rudzik8",
    "login_name": "",
    "source_id": 0,
    "full_name": "Mikita Wiśniewski",
    "email": "rudzik8@noreply.codeberg.org",
    "avatar_url": "https://codeberg.org/avatars/52fc6869117fce7599f54d289d10670e9f478fcb09a8782bc45349b849dc46f0",
    "html_url": "https://codeberg.org/rudzik8",
    "language": "",
    "is_admin": false,
    "last_login": "0001-01-01T00:00:00Z",
    "created": "2022-11-06T12:14:25+01:00",
    "restricted": false,
    "active": false,
    "prohibit_login": false,
    "location": "pos: (-1726.8, 9.3, 423.2)",
    "pronouns": "he/him",
    "website": "https://rudzik8.bearblog.dev/",
    "description": "Siberian 17yo FOSS gamedev enthusiast, Luanti player and modder, Voxelgarden maintainer and a Mineclonia developer",
    "visibility": "public",
    "followers_count": 6,
    "following_count": 20,
    "starred_repos_count": 11,
    "username": "rudzik8"
  }
}
2nd delivery with an unbound token

Headers:

Headers
Request URL: https://content.luanti.org/github/webhook/
Request method: POST
Content-Type: application/json
X-Forgejo-Delivery: 2537a1a3-e4e4-4cc8-8cc3-1a2bc9c1f753
X-Forgejo-Event: push
X-Forgejo-Event-Type: push
X-Forgejo-Signature: 806a52807e724f63775b41d04da79e0ea1d25d24f94312a31f5e7b58a052f09a
X-GitHub-Delivery: 2537a1a3-e4e4-4cc8-8cc3-1a2bc9c1f753
X-GitHub-Event: push
X-GitHub-Event-Type: push
X-Gitea-Delivery: 2537a1a3-e4e4-4cc8-8cc3-1a2bc9c1f753
X-Gitea-Event: push
X-Gitea-Event-Type: push
X-Gitea-Signature: 806a52807e724f63775b41d04da79e0ea1d25d24f94312a31f5e7b58a052f09a
X-Gogs-Delivery: 2537a1a3-e4e4-4cc8-8cc3-1a2bc9c1f753
X-Gogs-Event: push
X-Gogs-Event-Type: push
X-Gogs-Signature: 806a52807e724f63775b41d04da79e0ea1d25d24f94312a31f5e7b58a052f09a
X-Hub-Signature: sha1=54ff1ec47821461375d8e6abf128823864c678f0
X-Hub-Signature-256: sha256=806a52807e724f63775b41d04da79e0ea1d25d24f94312a31f5e7b58a052f09a

Content:

{
  "ref": "refs/heads/main",
  "before": "4e189eeae39e99e30e8c41fb16def73d4b450b1d",
  "after": "10991448516f4c8a9ce69081d9a401485ff286f0",
  "compare_url": "https://codeberg.org/rudzik8/mcl_emerald_stuff/compare/4e189eeae39e99e30e8c41fb16def73d4b450b1d...10991448516f4c8a9ce69081d9a401485ff286f0",
  "commits": [
    {
      "id": "10991448516f4c8a9ce69081d9a401485ff286f0",
      "message": "Empty commit\n",
      "url": "https://codeberg.org/rudzik8/mcl_emerald_stuff/commit/10991448516f4c8a9ce69081d9a401485ff286f0",
      "author": {
        "name": "Mikita Wiśniewski",
        "email": "rudzik8@protonmail.com",
        "username": "rudzik8"
      },
      "committer": {
        "name": "Mikita Wiśniewski",
        "email": "rudzik8@protonmail.com",
        "username": "rudzik8"
      },
      "verification": null,
      "timestamp": "2026-03-14T13:41:11+07:00",
      "added": [],
      "removed": [],
      "modified": []
    }
  ],
  "total_commits": 1,
  "head_commit": {
    "id": "10991448516f4c8a9ce69081d9a401485ff286f0",
    "message": "Empty commit\n",
    "url": "https://codeberg.org/rudzik8/mcl_emerald_stuff/commit/10991448516f4c8a9ce69081d9a401485ff286f0",
    "author": {
      "name": "Mikita Wiśniewski",
      "email": "rudzik8@protonmail.com",
      "username": "rudzik8"
    },
    "committer": {
      "name": "Mikita Wiśniewski",
      "email": "rudzik8@protonmail.com",
      "username": "rudzik8"
    },
    "verification": null,
    "timestamp": "2026-03-14T13:41:11+07:00",
    "added": [],
    "removed": [],
    "modified": []
  },
  "repository": {
    "id": 108009,
    "owner": {
      "id": 70442,
      "login": "rudzik8",
      "login_name": "",
      "source_id": 0,
      "full_name": "Mikita Wiśniewski",
      "email": "rudzik8@protonmail.com",
      "avatar_url": "https://codeberg.org/avatars/52fc6869117fce7599f54d289d10670e9f478fcb09a8782bc45349b849dc46f0",
      "html_url": "https://codeberg.org/rudzik8",
      "language": "",
      "is_admin": false,
      "last_login": "0001-01-01T00:00:00Z",
      "created": "2022-11-06T12:14:25+01:00",
      "restricted": false,
      "active": false,
      "prohibit_login": false,
      "location": "pos: (-1726.8, 9.3, 423.2)",
      "pronouns": "he/him",
      "website": "https://rudzik8.bearblog.dev/",
      "description": "Siberian 17yo FOSS gamedev enthusiast, Luanti player and modder, Voxelgarden maintainer and a Mineclonia developer",
      "visibility": "public",
      "followers_count": 6,
      "following_count": 20,
      "starred_repos_count": 11,
      "username": "rudzik8"
    },
    "name": "mcl_emerald_stuff",
    "full_name": "rudzik8/mcl_emerald_stuff",
    "description": "Adds emerald tools and armor to VoxeLibre (ex. MineClone2)",
    "empty": false,
    "private": false,
    "fork": false,
    "template": false,
    "parent": null,
    "mirror": false,
    "size": 267,
    "language": "",
    "languages_url": "https://codeberg.org/api/v1/repos/rudzik8/mcl_emerald_stuff/languages",
    "html_url": "https://codeberg.org/rudzik8/mcl_emerald_stuff",
    "url": "https://codeberg.org/api/v1/repos/rudzik8/mcl_emerald_stuff",
    "link": "",
    "ssh_url": "ssh://git@codeberg.org/rudzik8/mcl_emerald_stuff.git",
    "clone_url": "https://codeberg.org/rudzik8/mcl_emerald_stuff.git",
    "original_url": "https://git.minetest.land/rudzik8/mcl_emerald_stuff.git",
    "website": "",
    "stars_count": 0,
    "forks_count": 3,
    "watchers_count": 1,
    "open_issues_count": 0,
    "open_pr_counter": 0,
    "release_counter": 0,
    "default_branch": "main",
    "archived": false,
    "created_at": "2023-04-23T13:17:26+02:00",
    "updated_at": "2026-03-14T07:37:55+01:00",
    "archived_at": "1970-01-01T01:00:00+01:00",
    "permissions": {
      "admin": true,
      "push": true,
      "pull": true
    },
    "has_issues": true,
    "internal_tracker": {
      "enable_time_tracker": true,
      "allow_only_contributors_to_track_time": true,
      "enable_issue_dependencies": true
    },
    "has_wiki": true,
    "wiki_branch": "master",
    "globally_editable_wiki": false,
    "has_pull_requests": true,
    "has_projects": true,
    "has_releases": true,
    "has_packages": true,
    "has_actions": false,
    "ignore_whitespace_conflicts": false,
    "allow_merge_commits": true,
    "allow_rebase": true,
    "allow_rebase_explicit": true,
    "allow_squash_merge": true,
    "allow_fast_forward_only_merge": false,
    "allow_rebase_update": true,
    "default_delete_branch_after_merge": false,
    "default_merge_style": "merge",
    "default_allow_maintainer_edit": false,
    "default_update_style": "merge",
    "avatar_url": "",
    "internal": false,
    "mirror_interval": "",
    "object_format_name": "sha1",
    "mirror_updated": "0001-01-01T00:00:00Z",
    "repo_transfer": null,
    "topics": [
      "minetest",
      "mcl",
      "mcl2"
    ]
  },
  "pusher": {
    "id": 70442,
    "login": "rudzik8",
    "login_name": "",
    "source_id": 0,
    "full_name": "Mikita Wiśniewski",
    "email": "rudzik8@noreply.codeberg.org",
    "avatar_url": "https://codeberg.org/avatars/52fc6869117fce7599f54d289d10670e9f478fcb09a8782bc45349b849dc46f0",
    "html_url": "https://codeberg.org/rudzik8",
    "language": "",
    "is_admin": false,
    "last_login": "0001-01-01T00:00:00Z",
    "created": "2022-11-06T12:14:25+01:00",
    "restricted": false,
    "active": false,
    "prohibit_login": false,
    "location": "pos: (-1726.8, 9.3, 423.2)",
    "pronouns": "he/him",
    "website": "https://rudzik8.bearblog.dev/",
    "description": "Siberian 17yo FOSS gamedev enthusiast, Luanti player and modder, Voxelgarden maintainer and a Mineclonia developer",
    "visibility": "public",
    "followers_count": 6,
    "following_count": 20,
    "starred_repos_count": 11,
    "username": "rudzik8"
  },
  "sender": {
    "id": 70442,
    "login": "rudzik8",
    "login_name": "",
    "source_id": 0,
    "full_name": "Mikita Wiśniewski",
    "email": "rudzik8@noreply.codeberg.org",
    "avatar_url": "https://codeberg.org/avatars/52fc6869117fce7599f54d289d10670e9f478fcb09a8782bc45349b849dc46f0",
    "html_url": "https://codeberg.org/rudzik8",
    "language": "",
    "is_admin": false,
    "last_login": "0001-01-01T00:00:00Z",
    "created": "2022-11-06T12:14:25+01:00",
    "restricted": false,
    "active": false,
    "prohibit_login": false,
    "location": "pos: (-1726.8, 9.3, 423.2)",
    "pronouns": "he/him",
    "website": "https://rudzik8.bearblog.dev/",
    "description": "Siberian 17yo FOSS gamedev enthusiast, Luanti player and modder, Voxelgarden maintainer and a Mineclonia developer",
    "visibility": "public",
    "followers_count": 6,
    "following_count": 20,
    "starred_repos_count": 11,
    "username": "rudzik8"
  }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions