---
title: Spam Protection
---
# Spam Protection
Protect your forms from spam submissions and abuse.
## Built-in Protection
The package includes two spam protection mechanisms:
1. **Honeypot Field** - A hidden field that bots typically fill out
2. **Rate Limiting** - Limits submissions per IP address
## Honeypot Protection
### How It Works
A hidden field is added to forms. Legitimate users don't see it, but bots automatically fill it out. Submissions with this field filled are rejected.
### Configuration
```php
// config/artisanpack/forms.php
'spam_protection' => [
'honeypot' => [
'enabled' => true,
'field_name' => 'website_url', // Appealing name for bots
],
],
```
### Implementation
The honeypot field is automatically added to forms:
```blade
{{-- Hidden from users with CSS --}}
```
### Validation
```php
// In FormRenderer component
protected function validateHoneypot(): bool
{
if (!config('artisanpack.forms.spam_protection.honeypot.enabled')) {
return true;
}
$fieldName = config('artisanpack.forms.spam_protection.honeypot.field_name');
// If honeypot is filled, it's likely a bot
if (!empty($this->formData[$fieldName] ?? null)) {
Log::warning('Honeypot triggered', [
'form_id' => $this->form->id,
'ip' => request()->ip(),
]);
return false;
}
return true;
}
```
## Rate Limiting
### How It Works
Limits the number of submissions from a single IP address within a time window.
### Configuration
```php
// config/artisanpack/forms.php
'spam_protection' => [
'rate_limit' => [
'enabled' => true,
'attempts' => 5, // Max submissions
'decay' => 60, // Time window in seconds
],
],
```
### Implementation
```php
use Illuminate\Support\Facades\RateLimiter;
protected function checkRateLimit(): bool
{
if (!config('artisanpack.forms.spam_protection.rate_limit.enabled')) {
return true;
}
$key = 'form-submit:' . $this->form->id . ':' . request()->ip();
$attempts = config('artisanpack.forms.spam_protection.rate_limit.attempts');
$decay = config('artisanpack.forms.spam_protection.rate_limit.decay');
if (RateLimiter::tooManyAttempts($key, $attempts)) {
Log::warning('Rate limit exceeded', [
'form_id' => $this->form->id,
'ip' => request()->ip(),
]);
return false;
}
RateLimiter::hit($key, $decay);
return true;
}
```
### User Feedback
When rate limited:
```blade
@if ($rateLimited)
Too many submissions. Please try again later.
@endif
```
## reCAPTCHA Integration
For additional protection, integrate Google reCAPTCHA:
### Installation
```bash
composer require google/recaptcha
```
### Configuration
Add to `.env`:
```env
RECAPTCHA_SITE_KEY=your-site-key
RECAPTCHA_SECRET_KEY=your-secret-key
```
### Form Integration
```blade
{{-- In form view --}}
```
### Validation
```php
use function addFilter;
addFilter('forms.validation_rules', function ($rules, $form) {
if ($form->settings['recaptcha_enabled'] ?? false) {
$rules['g-recaptcha-response'] = 'required|recaptcha';
}
return $rules;
});
// Custom validation rule
Validator::extend('recaptcha', function ($attribute, $value) {
$recaptcha = new \ReCaptcha\ReCaptcha(config('services.recaptcha.secret_key'));
$response = $recaptcha->verify($value, request()->ip());
return $response->isSuccess();
});
```
## hCaptcha Integration
Alternative to reCAPTCHA:
### Configuration
```env
HCAPTCHA_SITE_KEY=your-site-key
HCAPTCHA_SECRET_KEY=your-secret-key
```
### Form Integration
```blade
```
## Custom Spam Checks
Add custom spam detection:
```php
use function addFilter;
// Check for spam keywords
addFilter('forms.spam_check', function ($isSpam, $form, $data) {
$spamKeywords = ['casino', 'viagra', 'crypto'];
foreach ($data as $value) {
if (is_string($value)) {
foreach ($spamKeywords as $keyword) {
if (stripos($value, $keyword) !== false) {
return true; // Is spam
}
}
}
}
return $isSpam;
});
// Check against spam database
addFilter('forms.spam_check', function ($isSpam, $form, $data) {
$email = $data['email'] ?? null;
if ($email && SpamDatabase::isSpammer($email)) {
return true;
}
return $isSpam;
});
```
## Security Logging
Enable logging for security events:
```php
// config/artisanpack/forms.php
'security' => [
'logging_enabled' => true,
],
```
Logged events:
- Honeypot triggered
- Rate limit exceeded
- Invalid file uploads
- Suspicious submissions
### Log Format
```
[warning] Honeypot triggered {
"form_id": 1,
"ip": "192.168.1.100",
"user_agent": "Mozilla/5.0..."
}
```
## Best Practices
1. **Layer Protection**: Use multiple methods together
2. **Monitor Logs**: Review security logs regularly
3. **Adjust Limits**: Tune rate limits based on legitimate traffic
4. **Update Keywords**: Keep spam keyword lists current
5. **Use HTTPS**: Always serve forms over HTTPS
## Disabling Protection
For testing or trusted environments:
```php
// Disable all spam protection
'spam_protection' => [
'honeypot' => ['enabled' => false],
'rate_limit' => ['enabled' => false],
],
```
## Next Steps
- [Webhooks](./webhooks.md) - External integrations
- [Customization](./customization.md) - Extend protection
- [Configuration](../installation/configuration.md) - All settings