Skip to content

Anti-spam strategy 2.0 #419

Description

@experimatt

Some ideas from Claude...


Anti-Spam Strategy for Sessionizer

Context

Spam accounts and sessions are still getting through despite email confirmation gating and a honeypot field. A community member is advocating for better fraud handling workflows (soft-delete instead of hard-delete). This plan covers both prevention (stop spam from getting in) and handling (deal with spam that gets through).


Phase 1: Quick Fixes

1. Server-side guard on session creation

The email confirmation check only exists in the view template (sessions/new.html.erb). A direct POST to /sessions bypasses it entirely.

2. Fix participant-session association

Hard-deleting a participant currently orphans their sessions (broken participant_id FK). Add dependent: :restrict_with_error so Rails prevents destroying a participant who still has sessions.


Phase 2: Soft-Delete / Suspension for Participants

3. Unified soft-delete system for participants

Combine the soft-delete and suspension concepts into one mechanism. Add a discarded_at column to participants, following the same pattern as the existing canceled_at on sessions. When a participant is discarded:

  • They cannot log in
  • Their sessions are auto-canceled (using the existing canceled_at mechanism)
  • They are filtered from public queries via default scope
  • The action is reversible (undiscard restores the participant and their sessions)

Implementation:

  • Migration: add discarded_at (datetime, indexed) to participants
  • Model: add kept, discarded, with_discarded scopes + default_scope { kept } + discarded? method
  • Block login for discarded participants via Authlogic session validation
  • On discard: auto-cancel all active sessions belonging to that participant
  • On undiscard: auto-uncancel those sessions
  • Admin: add discard/undiscard member actions and action items, add scope tabs (Active/Discarded/All) - modeled after existing session cancel/uncancel pattern in sessions.rb
  • Files: new migration, participant.rb, participants.rb, Authlogic session model

Phase 3: reCAPTCHA v3

4. reCAPTCHA v3 on signup (and optionally session creation)

Invisible, score-based bot detection. Config keys already exist in recaptcha_config.rb but the gem isn't installed.

  • Add recaptcha gem
  • Configure with environment variables (replace the hardcoded keys in recaptcha_config.rb)
  • Add invisible reCAPTCHA v3 to registration form
  • Validate score in ParticipantsController#create (reject below threshold, e.g. 0.5)
  • Optionally add to session creation form as well
  • Files: Gemfile, recaptcha_config.rb, new.html.erb, participants_controller.rb

Phase 4: Future Considerations

5. Disposable email domain blocking

Block registrations from known throwaway email services with a curated YAML blocklist and custom validation.

6. Community spam reporting

Let confirmed users flag suspicious sessions. Auto-hide after N reports pending admin review. Best tackled after prevention measures are in place.

  • New spam_reports table, model, controller, view integration, admin dashboard widget

Verification

  • Phase 1: Run existing test suite, manually test POST to /sessions as unconfirmed user (should be rejected), verify destroying a participant with sessions is blocked
  • Phase 2: Test discard/undiscard round-trip in admin, verify discarded participant can't log in, verify their sessions are auto-canceled and restored on undiscard
  • Phase 3: Test reCAPTCHA in development mode, verify low-score submissions are rejected, verify fallback when reCAPTCHA service is unavailable

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions