Implement Registration Spam Prevention #999
Labels
No labels
automated
code-quality
component: admin dashboard
component: backend
component: billing
component: content management
component: faqs
component: game genres
component: game lists
component: game reviews
component: game search
component: games
component: internal notifications
component: platforms
component: security
component: tests
component: user api
component: user badges
component: user blogs
component: user consoles
component: user favorites
component: user friends
component: user notifications
component: user profiles
component: user site notifications
component: user wishlists
component: web design
dependencies
javascript
php
priority
high
priority
low
priority
medium
security-hotspot
source: codex
source: sonarqube
status
awaiting feedback
status
backlog
status
done
status
in progress
status
in queue
status
in review
status
needs codex review
status
needs investigation
status
wontfix
type: bug
type: documentation
type: feature
type: improvement
type: regression
type: task
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
MyVideoGameList/myvideogamelist.com#999
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Registration should prevent automated spam accounts while keeping account creation straightforward and accessible for legitimate members.
The current Fortify registration flow already limits attempts to three per IP address per hour and records suspicious registrations for review. Add preventative protection before account creation, complementing those controls. Evaluate CAPTCHA and alternatives such as a honeypot, submission timing checks, or risk-based challenges; select and document an approach based on effectiveness, accessibility, privacy, reliability, and user friction rather than requiring a specific vendor upfront.
Scope
Acceptance Criteria
Test Coverage Required
tests/Feature/Auth/RegistrationTest.phpor add focused registration spam prevention coverage.tests/Feature/SuspiciousRegistrationTest.phpbehavior.vendor/bin/pint --dirty --format agentandcomposer stanif PHP changes; runnpm run buildif shared frontend assets change.Progress Checklist
Issue structure follows #853.
Acceptance review — November 5, 2026
Implementation and local verification meet the acceptance criteria and required test coverage. The checklist above records implementation completion; it does not claim production deployment or a live Cloudflare verification test.
CreateNewUserinvokesRegistrationSpamVerifierafter the existing throttle and account-field validation but before the account transaction, related records, suspicious-registration audit, Fider provisioning, and Fortify registration events. Direct POST and JSON requests cannot bypass verification.register, and an environment-backed exact hostname allowlist are required. Missing/malformed tokens, invalid/expired/replayed tokens, context mismatches, provider errors, malformed responses, redirects, timeouts, and missing configuration fail closed. HTTP requests use the fixed Siteverify endpoint, three-second connection and five-second overall timeouts, with no automatic retry. Siteverify owns single-use and expiry enforcement.Verification completed on the local
codex/issue-999-registration-spam-preventionbranch:--env=testingand provider fakes.--env=testing -d memory_limit=1G. The default 128 MB CLI limit was insufficient for full-suite discovery. Existing duplicate-constant warnings in unrelated tests remain; the clean sequential full run has no failures.vendor/bin/pint --dirty --format agent, explicit Pint checks for new PHP files,composer stan,npm run build, andgit diff --check: passed.The administrative checklist condition is already satisfied: the issue is labeled
status/in progressand has no Codex-review status to remove. It remains open and assigned to Codex. Changes remain local and uncommitted; no PR or deployment has been created. Production environment values and a live widget/registration check remain deployment-time verification steps.Follow-up acceptance review — November 5, 2026
A second review found and corrected a diagnostic privacy gap: Sentry captures the full request URL and query string independently of the request body. The original body filter could therefore retain a password or challenge token submitted in a registration query string; referrer headers could also repeat those values. Registration request diagnostics now retain only the query-free URL and HTTP method, excluding bodies, query strings, headers, and cookies. Matching follows Laravel's decoded/trailing-slash-normalized path and honors Fortify's configured registration path and prefix. Unrelated request diagnostics retain their existing behavior.
The new regression initially failed against the old implementation. Eight added cases now pass across Sentry events/transactions and canonical, trailing-slash, encoded, and configured registration paths. The README documents this policy. Fresh verification: 127 focused tests passed, 1,547 full-suite tests passed with 2 skipped, Pint, PHPStan, and whitespace checks passed. The full suite used the temporary 1 GB test-process memory limit and ran sequentially. Frontend assets and behavior were unchanged in this follow-up; the previously recorded 20 browser checks and successful asset build remain applicable.
All 11 implementation checklist items remain complete. No further implementation gaps were found. The issue remains open and in progress; no PR or deployment was created, and live Cloudflare verification remains a deployment-time check.
Stack-trace privacy acceptance review — November 5, 2026
An additional review reproduced another diagnostic leak using the installed Sentry SDK's real stack-trace builder: registration input arrays were retained as frame argument values, including passwords and challenge tokens. Filtering request metadata alone does not remove those arguments.
RegistrationDiagnosticsnow clears argument values from the event's primary stack trace and every chained exception stack trace for registration requests, preserving the frames and their file/line/function information. Unrelated-route stack traces keep their existing argument behavior. The README documents this policy.The regression failed before the fix and passes for both event and transaction callbacks afterward. Fresh verification: 129 focused PHP tests passed; the sequential full suite passed 1,549 tests with 2 skipped (1,551 total) using the temporary 1 GB test-process memory limit. Pint, PHPStan, and whitespace checks passed. No frontend behavior or assets changed in this review, so the previously recorded 20 passing browser checks and successful asset build remain applicable.
All 11 implementation checklist items remain complete, with no other concrete gaps found against the issue's description, acceptance criteria, and required coverage. The issue remains open and in progress. No PR, deployment, dependency change, or production-data change was made; live Cloudflare verification remains a deployment-time check.
Merged in PR #1015 as
15d76c01d5fafc587b6ee33c20a89ffdc6ed76e8(implementation commit2b1dc55c). All 11 implementation checklist items are complete.Registration now requires managed Turnstile verified server-side before account creation, related records, Fider provisioning, or registration delivery. Existing validation, throttling, auditing, and provisioning remain covered. The form supports accessible retries, expiration/failure recovery, responsive sizing, themes, and Livewire navigation. Registration diagnostics exclude sensitive request metadata and stack arguments. Verification-email resends are limited per account to one per minute and five per hour; verification links remain challenge-free.
Verification: 129 focused PHP tests and 20 browser checks passed. The latest full PHP suite passed 1,549 tests with 2 skipped using a temporary 1 GB process memory limit. Pint, PHPStan, asset build, and whitespace checks passed. No migrations or new dependencies are required for this change.
Deployment notes: configure
TURNSTILE_SITE_KEY,TURNSTILE_SECRET_KEY, andTURNSTILE_ALLOWED_HOSTNAMESindependently in each environment before rollout. Use Managed mode with pre-clearance disabled. Verification fails closed when configuration or the provider is unavailable. Rebuild application configuration and assets, then check the live registration widget. Setup, operations, and rollback are documented in README.md.Closing as requested. Dev and production deployment is starting; verified deployment results and backup locations will follow in a separate comment. No production deployment is claimed by this closeout note.
Deployed PR #1015 to dev and production from merged source revision
15d76c01d5fafc587b6ee33c20a89ffdc6ed76e8.The established checksum-guarded patch procedure applied 16 runtime files/assets. Config, route, and view caches were rebuilt. Deployment receipts append
+pr1015-15d76c01to each environment's existing release history, accurately preserving its prior patched-release lineage. Unrelated runtime files, dependencies, lockfiles, existing assets, and environment settings were preserved. No migrations or account/domain-data writes were performed.Dev was missing the Turnstile settings. Only the three Turnstile values already configured in the workstation's
.env.localwere applied to the dev environment, with its original environment file backed up privately. Production used its existing settings. No keys or secrets are included in these notes.Verified on both environments:
The managed widget requested human checkbox interaction in the automated browser. That challenge was not automated, no registration was submitted, and no email was sent. A human-completed end-to-end registration remains the final manual smoke test; no successful live Siteverify token exchange is claimed.
Backups:
/home/mvgldev/deploy-backups/pr1015-15d76c01-olmgo7jr/home/mvgl/deploy-backups/pr1015-15d76c01-j1zkv2u7/home/mvgldev/deploy-backups/pr1015-dev-config-1tvvcl26The guarded deployment/rollback runner is
~/deploy-stage/pr1015-15d76c01/deploy.pyunder each respective account. To roll back code/assets, run it withrollback <the-account-specific-backup-path>from the application directory; it restores previous files/release metadata and refreshes caches. Reverting removes preventative challenge enforcement and should be an explicit operational decision. The private dev environment backup is separate.Issue #999 remains closed with
status/doneand all 11 implementation checklist items checked.