Protect Webhooks from replay attacks
<!--IssueSummary start--> <details> <summary> Everyone can contribute. [Help move this issue forward](https://handbook.gitlab.com/handbook/marketing/developer-relations/contributor-success/community-contributors-workflows/#contributor-links) while earning points, leveling up and collecting rewards. </summary> - [Close this issue](https://contributors.gitlab.com/manage-issue?action=close&projectId=278964&issueIid=587536) </details> <!--IssueSummary end--> ### Problem to solve <!-- What is the user problem you are trying to solve with this issue? --> GitLab provides the use of an optional secret token to be used with webhooks. The secret token is sent with the webhook request in the `X-Gitlab-Token` HTTP header. The webhook endpoint can use this token to verify the legitimacy of the request. Similarly, GitHub uses a sha256 hash to be sent in their `X-Hub-Signature-256` header. The receiving endpoint then uses the secret to generate a hash and compares the hash signature to confirm validity. This works well with the exception of a couple of use cases: - Where the secret is leaked and can be used by the attacker to spoof webhook calls. - Replay attacks where the entire URI is replayed with the `X-Gitlab-Token` HTTP header intact. While MITM attacks are rare, the increase of Evil Twin attacks, HTTPS Spoofing, and even AI/MCP leakage has increased scrutiny of webhook usage with enterprise customers - especially FinTec and HealthCare verticals. ### Proposal <!-- Use this section to explain the feature and how it will work. It can be helpful to add technical details, design proposals, and links to related epics or issues. --> Provide a feature which prevents replay attacks and URI spoofing. The feature could be in the form of an ephemeral JWT token (issued by a secrets management solution in the CI pipeline) or something as simple as a nonce to ensure each session is distinct and impervious to replay attack. A nonce solution could be combined with [this issue](https://gitlab.com/gitlab-org/gitlab/-/work_items/327441) incorporating a time stamp into the webhook payload Another upside to this kind of solution is the secret token is not store in the endpoint hash validation code. ### Intended users * [Delaney (Development Team Lead)](https://handbook.gitlab.com/handbook/product/personas/#delaney-development-team-lead) * [Priyanka (Platform Engineer)](https://handbook.gitlab.com/handbook/product/personas/#priyanka-platform-engineer) * [Sidney (Systems Administrator)](https://handbook.gitlab.com/handbook/product/personas/#sidney-systems-administrator) * [Ingrid (Infrastructure Operator)](https://handbook.gitlab.com/handbook/product/personas/#ingrid-infrastructure-operator) * [Amy (Application Security Engineer)](https://handbook.gitlab.com/handbook/product/personas/#amy-application-security-engineer) * [Alex (Security Operations Engineer)](https://handbook.gitlab.com/handbook/product/personas/#alex-security-operations-engineer) * [Cameron (Compliance Manager)](https://handbook.gitlab.com/handbook/product/personas/#cameron-compliance-manager) ### Does this feature require an audit event? <!--- Checkout these docs to know more https://docs.gitlab.com/ee/development/audit_event_guide/#what-are-audit-events https://docs.gitlab.com/administration/compliance/audit_event_reports/ ---> This feature should not change any existing audit events. It simply adds robustness to an existing GitLab feature.
issue