fix: Enforce webhook signature for Forgejo#2421
Conversation
🔍 PR Lint Feedback
|
Summary of ChangesHello @chmouel, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request significantly improves the security posture of Gitea and Forgejo webhook integrations by introducing robust signature validation. By requiring and verifying cryptographic signatures on incoming webhook payloads, the system can now confidently ascertain that requests originate from trusted sources and have not been tampered with. This change hardens the application against potential spoofing attacks and ensures data integrity, backed by extensive test cases. Highlights
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Code Review
This pull request introduces a critical security feature by enforcing webhook signature validation for Gitea and Forgejo, ensuring the authenticity of incoming requests. The implementation is robust, correctly using HMAC-SHA256 and constant-time comparison to prevent timing attacks. The error handling for missing signatures or secrets is clear and improves security posture. The changes are well-supported by a comprehensive set of unit tests that cover various success and failure scenarios. The updates to the E2E test framework to accommodate webhook secrets are also appropriate. I have one suggestion to improve the idempotency of the test setup.
There was a problem hiding this comment.
Pull request overview
This PR implements webhook signature validation for Gitea and Forgejo providers to enhance security by ensuring only authenticated webhook requests are processed. The implementation uses HMAC-SHA256 for signature verification and makes webhook secrets mandatory for all Gitea/Forgejo webhooks.
Changes:
- Added signature validation logic in the Gitea provider's Validate method using HMAC-SHA256
- Updated test infrastructure to support webhook secrets through environment variables
- Added comprehensive unit tests covering multiple validation scenarios
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| pkg/provider/gitea/gitea.go | Implements webhook signature validation using HMAC-SHA256 with constant-time comparison, enforcing mandatory webhook secrets |
| pkg/provider/gitea/gitea_test.go | Adds comprehensive test coverage for validation scenarios including valid/invalid signatures, missing secrets, and malformed inputs |
| test/pkg/gitea/test.go | Updates TestPR to retrieve webhook secret from TEST_EL_WEBHOOK_SECRET environment variable |
| test/pkg/gitea/scm.go | Extends CreateGiteaRepo signature to accept webhookSecret parameter and configures it in webhook creation |
| test/pkg/gitea/crd.go | Creates webhook-secret Kubernetes secret from TEST_EL_WEBHOOK_SECRET and configures it in the Repository CR |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| webhookSecret, _ := os.LookupEnv("TEST_EL_WEBHOOK_SECRET") | ||
| if err := secret.Create(ctx, topts.ParamsRun, map[string]string{"secret": webhookSecret}, ns, "webhook-secret"); err != nil { | ||
| return err | ||
| } |
There was a problem hiding this comment.
When TEST_EL_WEBHOOK_SECRET environment variable is not set, LookupEnv will return an empty string. This means the secret will be created with an empty value, and the webhook secret reference will still be set in the GitProvider spec. This could lead to confusing behavior where a secret is configured but empty. Consider checking if the webhook secret is empty and handling that case appropriately, or add a check to ensure TEST_EL_WEBHOOK_SECRET is set before proceeding.
| func (v *Provider) Validate(_ context.Context, _ *params.Run, event *info.Event) error { | ||
| signature := event.Request.Header.Get(ForgejoSignatureHeader) | ||
| if signature == "" { | ||
| signature = event.Request.Header.Get(GiteaSignatureHeader) | ||
| } | ||
| if signature == "" { | ||
| return fmt.Errorf("no signature has been detected, for security reason we are not allowing webhooks without a secret") | ||
| } | ||
|
|
||
| secret := event.Provider.WebhookSecret | ||
| if secret == "" { | ||
| return fmt.Errorf("no webhook secret has been set, in repository CR or secret") | ||
| } | ||
|
|
||
| return validateSignature(signature, event.Request.Payload, []byte(secret)) |
There was a problem hiding this comment.
The documentation in docs/content/docs/dev/_index.md (lines 86-88) states that "Pipelines-as-Code detects a Gitea install and lets the user set an empty webhook secret (by default it's enforced)." However, this implementation now requires webhook secrets for all Gitea/Forgejo webhooks and returns an error if either the signature or secret is missing. This is a breaking change from the documented behavior. The documentation should be updated to reflect that webhook secrets are now mandatory for Gitea/Forgejo, or the implementation should be modified to match the documented behavior of allowing empty webhook secrets.
There was a problem hiding this comment.
this will be fixed in subsequent pr after #2420
a5641cd to
f79d333
Compare
|
/compliance --pr_compliance.enable_ticket_labels=true |
PR Compliance Guide 🔍(Compliance updated until commit f79d333)Below is a summary of compliance checks for this PR:
Compliance status legend🟢 - Fully Compliant🟡 - Partial Compliant 🔴 - Not Compliant ⚪ - Requires Further Human Verification 🏷️ - Compliance label Previous compliance checksCompliance check up to commit f79d333
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
❌ PR-Agent failed to apply 'global' repo settings The configuration file needs to be a valid TOML, please fix it. Error message: Configuration content:[github_app]
pr_commands = [ "/review" ]
[pr_reviewer]
enable_review_labels_security = true
enable_chat_in_code_suggestions=false
enable_chat_in_code_suggestions = false
enable_summary=false
enable_help_text=false
[pr_description]
publish_description_as_comment = true
[pr_code_suggestions]
commitable_code_suggestions = true
[pr_test]
num_tests = 0 |
|
/retest |
|
/test go-testing |
|
PR-Agent: could not fine a component named |
bfed013 to
400ce4f
Compare
|
/retest |
Implemented signature validation for Gitea and Forgejo webhooks to ensure the authenticity of incoming requests. This involves checking the `X-Forgejo-Signature` and `X-Gitea-Signature` headers against a computed HMAC-SHA256 hash of the request payload using a configured webhook secret. The validation ensures that only requests originating from a trusted source with the correct secret are processed, enhancing the security of webhook integrations. This change also includes necessary test cases to verify the correct functioning of the validation logic. Jira: https://issues.redhat.com/browse/SRVKP-10609 Signed-off-by: Chmouel Boudjnah <chmouel@redhat.com>
ac20034 to
e492f7b
Compare
|
/retest |
Auto-created Ticket
#2422
Implemented signature validation for Gitea and Forgejo webhooks to ensure the authenticity of incoming requests. This involves checking the
X-Forgejo-SignatureandX-Gitea-Signatureheaders against a computed HMAC-SHA256 hash of the request payload using a configured webhook secret.The validation enforce that only requests originating from a trusted source with the correct secret are processed, enhancing the security of webhook integrations. This change also includes necessary test cases to verify the correct functioning of the validation logic.
This is not a breaking change, since user were not supposed to use gitea other than for local testing before 🙃
📝 Description of the Change
👨🏻 Linked Jira
Jira: https://issues.redhat.com/browse/SRVKP-10609
🔗 Linked GitHub Issue
Fixes #
🚀 Type of Change
fix:)feat:)feat!:,fix!:)docs:)chore:)refactor:)enhance:)deps:)🧪 Testing Strategy
🤖 AI Assistance
If you have used AI assistance, please provide the following details:
Which LLM was used?
Extent of AI Assistance:
Important
If the majority of the code in this PR was generated by an AI, please add a
Co-authored-bytrailer to your commit message.For example:
Co-authored-by: Gemini gemini@google.com
Co-authored-by: ChatGPT noreply@chatgpt.com
Co-authored-by: Claude noreply@anthropic.com
Co-authored-by: Cursor noreply@cursor.com
Co-authored-by: Copilot Copilot@users.noreply.github.com
**💡You can use the script
./hack/add-llm-coauthor.shto automatically addthese co-author trailers to your commits.
✅ Submitter Checklist
fix:,feat:) matches the "Type of Change" I selected above.make testandmake lintlocally to check for and fix anyissues. For an efficient workflow, I have considered installing
pre-commit and running
pre-commit installtoautomate these checks.
...(truncated)