evolvestudio/spam-protection

Stateless anti-spam protection for Laravel forms.

Maintainers

Package info

gitlab.com/evolvestudio-oss/spam-protection

Issues

pkg:composer/evolvestudio/spam-protection

Transparency log

Statistics

Installs: 204

Dependents: 0

Suggesters: 0

Stars: 0

v0.1.1 2026-06-25 09:40 UTC

This package is auto-updated.

Last update: 2026-07-25 16:55:54 UTC


README

Laravel package for stateless anti-spam protection based on:

  • a honeypot field;
  • an encrypted timestamp token;
  • configurable minimum and maximum submission times;
  • granular logging for blocked submissions.

The package classifies submissions. The consuming application remains responsible for returning a simulated success response and for configuring rate limiting.

Requirements

  • PHP 8.1 or newer
  • Laravel 12 or 13, covered by the automated test matrix
  • Laravel 10 and 11 are accepted for legacy projects, but Composer may block fresh test environments because of upstream security advisories
  • Livewire 3.8 or 4.x for the optional Livewire integration
  • Livewire 2 is not currently guaranteed

Installation

Install the package through Packagist:

composer require evolvestudio/spam-protection

Optionally publish its configuration:

php artisan vendor:publish --tag=spam-protection-config

Blade forms

Render the package fields inside a classic POST form:

<x-spam-protection::fields />

Check the request before validation or side effects:

use EvolveStudio\SpamProtection\SpamProtectionService;

public function store(Request $request, SpamProtectionService $spamProtection)
{
    if ($spamProtection->isSpamSubmission($request)) {
        return back()->with('success', 'Richiesta inviata correttamente.');
    }

    // Validate and process the real submission.
}

Livewire

The optional trait provides the two public properties and token lifecycle:

use EvolveStudio\SpamProtection\Livewire\ProtectsAgainstSpam;

class ContactForm extends Component
{
    use ProtectsAgainstSpam;

    public function save(): void
    {
        if ($this->spamProtectionDetectsSpam()) {
            $this->reset();
            $this->resetSpamProtection();
            $this->dispatch('notify', message: __('generic.success'));

            return;
        }

        // Validate and process the real submission.
    }
}

Bind the properties in the component view:

<div aria-hidden="true" style="position:absolute;left:-10000px;width:1px;height:1px;overflow:hidden;">
    <input type="text" wire:model="websiteNoSpam" tabindex="-1" autocomplete="off">
</div>

The trait initializes the encrypted token automatically through Livewire's trait-prefixed mountProtectsAgainstSpam() lifecycle hook. The token property is locked against client-side updates, so it does not need a hidden input. The trait intentionally does not dispatch success events or reset application fields because those behaviors belong to the consuming component.

Rate limiting

Rate limiting is intentionally not installed globally by this package. Add a route throttle for classic POST forms or a targeted limiter in the consuming application. When the application is behind a proxy, verify that $request->ip() returns the real client IP.

Development

composer install
composer test