PHPackages                             wsm/form-spamshield - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Validation &amp; Sanitization](/categories/validation)
4. /
5. wsm/form-spamshield

ActiveTypo3-cms-extension[Validation &amp; Sanitization](/categories/validation)

wsm/form-spamshield
===================

Adds a bot detection via JavaScript and a Validator to EXT:form, GDPR compliant without a captcha.

2.2.2(3mo ago)656.1k↓12.7%3[3 issues](https://github.com/krausandre/wsm-form-spamshield/issues)1GPL-2.0-or-laterPHPPHP &gt;=8.2,&lt;8.5

Since Mar 21Pushed 2mo ago1 watchersCompare

[ Source](https://github.com/krausandre/wsm-form-spamshield)[ Packagist](https://packagist.org/packages/wsm/form-spamshield)[ Docs](https://www.website-mensch.de/)[ RSS](/packages/wsm-form-spamshield/feed)WikiDiscussions main Synced 1mo ago

READMEChangelogDependencies (2)Versions (19)Used By (1)

Form Spamshield
===============

[](#form-spamshield)

Adds a bot detection via JavaScript and a Validator to EXT:form, GDPR compliant without a captcha.

How it works
------------

[](#how-it-works)

This shield works with two components:

The first component is a JavaScript, which checks the browser and checks if there are signs that the current user is a human. Simple things like browser width, whether the user pressed a key, whether the user moved the mouse, and so on. No personal data. But JavaScript must be enabled otherwise, the spam shield will detect the user as a bot.

The second component is a validator, which checks the result of the JavaScript. You can configure a security level from 1 to 10 in your form field definition, which the validator respects. 1 means 10% of the security checks have to be successful, and 10 means 100% have to be successful.

Recommendation: Set the security level to 7 or 8 for a good balance between security and usability.

Please remember accessibility, that there are some people e.g. who can not use a mouse. So setting the security level to 9 or 10 might not be accessible for some people.

There is the option to set a form timeout. This is a value in seconds, which defines a timeout before the form submission is accepted. E.g. robots are very fast, so a human needs more time to fill out a form. You can set a custom value based on what you think is the minimum number of seconds humans need to fill out the form. (Remember that browser autofill can be very fast.)

There is a strict mode, which can be disabled for some special use cases.

There is also a "require whitespace" option (enabled by default), which requires users to press the spacebar at least once. This is effective against bots that submit forms with random strings without spaces. Disable this option for forms without free text fields, e.g. multiple choice forms.

How to install
--------------

[](#how-to-install)

You can install this extension via composer:

```
composer req wsm/form-spamshield
```

You can also install this extension via TER.

After installation flush TYPO3 and PHP caches.

How to use
----------

[](#how-to-use)

Add the security check field with validator to your formdefinition like this:

```
-
    type: SecureCheck
    identifier: securitycheck
    label: 'Security check against robots'
    validators:
        -
            identifier: SpamSecurityCheck
            options:
                securityLevel: 7
                formTimeout: 10
                strictMode: true
                requireWhitespace: true
    properties:
        secureCheckSuccessMessage: 'Validation passed'
        validationErrorMessages:
            -
                code: 1221559976
                message: 'Sorry, the security check identified you as a robot. To pass the security check, you must perform more actions on this page that are typical for a human visitor. And JavaScript must be enabled.'
```

You can also add the security check field with a validator to your formdefinition via the form editor. This could be helpful in some cases.

How to translate messages
-------------------------

[](#how-to-translate-messages)

The example above with translated messages:

```
-
    type: SecureCheck
    identifier: securitycheck
    label: 'Security check against robots'
    validators:
        -
            identifier: SpamSecurityCheck
            options:
                securityLevel: 7
                formTimeout: 10
                strictMode: true
                requireWhitespace: true
    properties:
        secureCheckSuccessMessage: 'LLL:EXT:my_extension/Resources/Private/Language/locallang.xlf:form-validation-success-message'
        validationErrorMessages:
            -
                code: 1221559976
                message: 'LLL:EXT:my_extension/Resources/Private/Language/locallang.xlf:form-validation-error-message'
```

###  Health Score

54

—

FairBetter than 97% of packages

Maintenance75

Regular maintenance activity

Popularity37

Limited adoption so far

Community16

Small or concentrated contributor base

Maturity71

Established project with proven stability

 Bus Factor1

Top contributor holds 91.5% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~70 days

Recently: every ~52 days

Total

16

Last Release

105d ago

Major Versions

1.4.0 → 2.0.02025-03-26

1.5.0 → 2.1.02025-04-24

1.5.1 → 2.1.12025-07-10

1.6.1 → 2.2.12025-12-31

PHP version history (5 changes)1.1.0PHP &gt;=7.0,&lt;8.2

1.2.0PHP &gt;=7.0,&lt;8.3

1.3.3PHP &gt;=7.0,&lt;8.4

2.0.0PHP &gt;=8.2,&lt;8.5

1.4.1PHP &gt;=7.0,&lt;8.5

### Community

Maintainers

![](https://www.gravatar.com/avatar/95fdcd294651f1b0970313b3bcdd61cc7c3bddf160034d2d5db1c6db3f3c2163?d=identicon)[andrekraus](/maintainers/andrekraus)

---

Top Contributors

[![krausandre](https://avatars.githubusercontent.com/u/42275455?v=4)](https://github.com/krausandre "krausandre (75 commits)")[![ManuS3009](https://avatars.githubusercontent.com/u/43109656?v=4)](https://github.com/ManuS3009 "ManuS3009 (3 commits)")[![passionweb-manuel-schnabel](https://avatars.githubusercontent.com/u/120183093?v=4)](https://github.com/passionweb-manuel-schnabel "passionweb-manuel-schnabel (2 commits)")[![s-leger](https://avatars.githubusercontent.com/u/7442572?v=4)](https://github.com/s-leger "s-leger (2 commits)")

---

Tags

recaptchaspamcaptchaFormsnocaptchaTYPO3 CMSgdprdsgvoSpamshield

### Embed Badge

![Health badge](/badges/wsm-form-spamshield/health.svg)

```
[![Health](https://phpackages.com/badges/wsm-form-spamshield/health.svg)](https://phpackages.com/packages/wsm-form-spamshield)
```

###  Alternatives

[karser/karser-recaptcha3-bundle

Google ReCAPTCHA v3 for Symfony

1862.4M7](/packages/karser-karser-recaptcha3-bundle)[aryehraber/statamic-captcha

Protect your Statamic forms using a Captcha service

16194.4k](/packages/aryehraber-statamic-captcha)[undefinedoffset/silverstripe-nocaptcha

A spam protector and form field using Google's reCAPTCHA v2 or optionally a foundation v3 implementation

33471.6k16](/packages/undefinedoffset-silverstripe-nocaptcha)[uestla/recaptcha-control

reCAPTCHA control for Nette Framework forms

26572.0k1](/packages/uestla-recaptcha-control)[abanoubnassem/filament-grecaptcha-field

Provides a Google reCaptcha V2 field for the Filament Forms

27116.1k2](/packages/abanoubnassem-filament-grecaptcha-field)[fruitcakestudio/recaptcha

reCAPTCHA library

1625.5k1](/packages/fruitcakestudio-recaptcha)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
