Add registration bot traps #2

Merged
lambadalambda merged 1 commit from feature/registration-guard-v16 into v16.0/forgejo 2026-08-29 07:47:12 +00:00

Summary

  • add an optional instance-specific registration question with normalized accepted answers
  • add a honeypot and authenticated minimum-completion-time token to local signup
  • log privacy-safe passed/blocked outcomes without account data, submitted values, tokens, or IP addresses
  • document configuration, validation, replay limitations, and logging behavior

Security model

This is lightweight friction for opportunistic generic Forgejo signup automation, not a rate limiter. Signed form tokens are valid for 24 hours and can be replayed within that window.

Testing

  • go test -tags 'sqlite sqlite_unlock_notify' ./services/auth ./modules/setting ./routers/web/auth ./services/forms -count=1
  • go test -tags 'sqlite sqlite_unlock_notify' ./tests/integration -run '^TestSignup' -count=1
  • go run github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.11.4 run ./services/auth ./modules/setting ./routers/web/auth ./services/forms
  • make lint-locale lint-locale-usage lint-editorconfig
  • git diff --check

Full make lint-go remains blocked only by two pre-existing modernize findings in services/repository/files/suggestion.go.

## Summary - add an optional instance-specific registration question with normalized accepted answers - add a honeypot and authenticated minimum-completion-time token to local signup - log privacy-safe passed/blocked outcomes without account data, submitted values, tokens, or IP addresses - document configuration, validation, replay limitations, and logging behavior ## Security model This is lightweight friction for opportunistic generic Forgejo signup automation, not a rate limiter. Signed form tokens are valid for 24 hours and can be replayed within that window. ## Testing - `go test -tags 'sqlite sqlite_unlock_notify' ./services/auth ./modules/setting ./routers/web/auth ./services/forms -count=1` - `go test -tags 'sqlite sqlite_unlock_notify' ./tests/integration -run '^TestSignup' -count=1` - `go run github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.11.4 run ./services/auth ./modules/setting ./routers/web/auth ./services/forms` - `make lint-locale lint-locale-usage lint-editorconfig` - `git diff --check` Full `make lint-go` remains blocked only by two pre-existing `modernize` findings in `services/repository/files/suggestion.go`.
feat(auth): add registration bot traps
All checks were successful
opencode/review OpenCode execution completed
e2628ae0ad
Author
Owner

/oc review

/oc review
Owner

OpenCode Review

Execution completed for pleroma/forgejo-custom at e2628ae0ad49 (job #63).

Rating: 5/5

The PR adds three bot traps to local signup: an instance-specific challenge question, a hidden honeypot field, and an HMAC-authenticated issuance-timestamp token enforcing a minimum form-completion time. Implementation is sound: the token is domain-separated HMAC-SHA256 over the millisecond timestamp, verified with constant-time comparison, length-checked, overflow-guarded, and rejected when in the future or older than 24h; the honeypot is checked first and both honeypot/invalid-token failures return a generic message without leaking which trap fired; rejection logs contain no submitted values. The guard is wired only into the unauthenticated local signup POST (before captcha), while OAuth/OpenID/link-account paths that require prior external auth are excluded and the template correctly hides the fields in LinkAccountMode, so no bypass exists. Config parsing trims/filters answers, clamps invalid min-form-time to the default, and disables the guard with a startup warning when challenge/answers are empty (deliberate, test-asserted). Verified: services/auth unit tests, setting config tests, and integration tests (TestSignupRegistrationGuard plus existing signup/link-account/auth suites) all pass under go1.26.7 with sqlite tags; gofmt and go vet clean; working tree restored. Token reuse for up to 24h and the fail-open-on-misconfiguration behavior are explicitly documented design decisions, not defects. No blocking or medium-impact issues found; production-ready.

No findings were reported.

Well-implemented registration guard with correct HMAC token handling, sensible check ordering, no PII in logs, and thorough unit plus integration coverage. All relevant tests pass and static checks are clean. The known limitations (24h token reuse window, fail-open when misconfigured) are deliberate and documented in app.example.ini. No actionable defects introduced.


Last reviewed commit: e2628ae0ad49

<!-- opencode-review:v1:b98eb21825a0255ef81c9d35b6d41bdf --> <!-- opencode-reviewed-head:e2628ae0ad495a69f5ce3eb7a0385fc124253a83 --> ## OpenCode Review _Execution completed for `pleroma/forgejo-custom` at `e2628ae0ad49` (job #63)._ Rating: **5/5** The PR adds three bot traps to local signup: an instance-specific challenge question, a hidden honeypot field, and an HMAC-authenticated issuance-timestamp token enforcing a minimum form-completion time. Implementation is sound: the token is domain-separated HMAC-SHA256 over the millisecond timestamp, verified with constant-time comparison, length-checked, overflow-guarded, and rejected when in the future or older than 24h; the honeypot is checked first and both honeypot/invalid-token failures return a generic message without leaking which trap fired; rejection logs contain no submitted values. The guard is wired only into the unauthenticated local signup POST (before captcha), while OAuth/OpenID/link-account paths that require prior external auth are excluded and the template correctly hides the fields in LinkAccountMode, so no bypass exists. Config parsing trims/filters answers, clamps invalid min-form-time to the default, and disables the guard with a startup warning when challenge/answers are empty (deliberate, test-asserted). Verified: services/auth unit tests, setting config tests, and integration tests (TestSignupRegistrationGuard plus existing signup/link-account/auth suites) all pass under go1.26.7 with sqlite tags; gofmt and go vet clean; working tree restored. Token reuse for up to 24h and the fail-open-on-misconfiguration behavior are explicitly documented design decisions, not defects. No blocking or medium-impact issues found; production-ready. No findings were reported. Well-implemented registration guard with correct HMAC token handling, sensible check ordering, no PII in logs, and thorough unit plus integration coverage. All relevant tests pass and static checks are clean. The known limitations (24h token reuse window, fail-open when misconfigured) are deliberate and documented in app.example.ini. No actionable defects introduced. --- _Last reviewed commit: `e2628ae0ad49`_
lambadalambda merged commit 197e4febc6 into v16.0/forgejo 2026-08-29 07:47:12 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
pleroma/forgejo-custom!2
No description provided.