Security

v1.19.0 Abonnement annuel Mis à jour le 17 sept. 2026

Security

Bloque bots, sondage d'endpoints, scraping, card testing et credential stuffing depuis l'application, avant la saturation du pool php-fpm.
Compatible Hyvä Magento 2.4.4 Magento 2.4.5 Magento 2.4.6 Magento 2.4.7 Mage-OS 2.0 Mage-OS 2.1
99,00 €
Essayer la démo en ligne
  • Mises à jour et support inclus pendant 12 mois
  • Clé de licence livrée immédiatement par email
  • Garantie satisfait ou remboursé 30 jours
  • Documentation complète incluse
  • Compatible avec les thèmes Hyvä
  • Installation prête pour Composer

Wimakeit Security

Votre admin Magento et votre boutique sont ciblés quotidiennement — des bots inondent les routes de recherche, sondent les endpoints REST et GraphQL, scrape votre contenu, testent des numéros de carte volés et bouclent sur des listes de credentials. Une attaque soutenue sature votre pool php-fpm et met tout le site hors ligne. Ce module arrête ça, entièrement à l'intérieur de l'application — sans accès à la configuration du serveur web, sans changement d'infrastructure.

Il a été conçu à partir d'un incident réel : un botnet distribué de ~2 000 IPs, chacune envoyant une requête de recherche par minute, a saturé un pool de 52 workers php-fpm et provoqué une panne complète. Le module traite maintenant ce scénario en quelques millisecondes par requête bloquée, avant même que le moteur de recherche soit instancié.

À qui ça s'adresse

  • Marchands sur un hébergement mutualisé ou managé où la configuration nginx/Apache est verrouillée — toute la protection s'exécute au niveau PHP.
  • Boutiques ayant subi des floods de recherche, du sondage d'endpoints REST (scrapers de pages CMS), des bots de carding sur le checkout invité, ou des tentatives de brute force sur la page de login admin.
  • Agences qui veulent un module configurable couvrant toutes les menaces courantes liées aux bots et la sécurité admin, avec intégration fail2ban et export de configuration edge inclus.
  • Équipes ops qui ont besoin de logs actionnables et d'une checklist de sécurité — pas seulement d'une règle firewall.

Bénéfices clés

  • Protection contre les floods de recherche — rate limiting par IP (30 req/60s par défaut) plus un circuit breaker sitewide : quand le taux global de recherche dépasse un seuil, seuls les vrais navigateurs (cookie form_key lié à une session) sont servis. La seule défense qui fonctionne contre les botnets distribués à ~1 requête/IP. La recherche peut aussi être limitée aux systèmes d'écriture dans lesquels la boutique vend, ce qui arrête les campagnes de parasitage de mots-clés qui font indexer des pages de résultats en langue étrangère.
  • Guards REST & GraphQL — throttle ou blocage total sur le sondage d'endpoints CMS et sur tout le trafic GraphQL ; les décisions interviennent avant le routing, l'authentification et l'analyse de la requête. Les routes de commande sont laissées libres par défaut : un client n'est jamais bloqué par une limite de débit.
  • Bad Bot Guard — bannit par User-Agent sur toutes les routes frontend : scanners malveillants (sqlmap, nikto…), harvesters d'emails, scrapers SEO agressifs et crawlers IA. Quatre catégories indépendantes avec un mode dry-run pour valider les listes avant de les activer.
  • Customer Registration Guard — refuse la création de compte qui correspond à une signature de bot : un domaine email refusé, une URL dans les champs nom, ou (en option) un prénom identique au nom. Le visiteur voit un message neutre qui ne nomme aucune règle ; la règle déclenchée est journalisée.
  • Payment Failure Mail Guard — plus d'emails « Payment Transaction Failed » pour des refus de paiement forgés sur un panier vide, effet de bord des campagnes qui sondent les endpoints de paiement. Les vrais échecs au checkout restent notifiés.
  • Admin Email OTP — après un login par mot de passe réussi, un code à 6 chiffres est envoyé à l'adresse email de l'admin. Des credentials volés seuls ne permettent pas d'accéder à l'admin — ni à l'endpoint de token de l'API REST, fermé aux tokens par mot de passe tant que l'OTP est actif. Aucune app d'authentification requise, aucun QR code à scanner. Un test en un clic prouve que le code est réellement délivré avant d'armer le second facteur, et tout échec d'envoi laisse passer l'admin avec une ligne de log plutôt que de bloquer toute l'équipe dehors. Sur une copie locale (localhost, *.local), le code est sauté automatiquement — décidé à partir de l'URL admin configurée, jamais de la requête.
  • Admin Login Guard — journalise chaque tentative de connexion, banne automatiquement les IPs qui dépassent le seuil d'échecs (TTL progressif : 5 min → 1h → 24h), envoie des alertes en cas de brute force.
  • Gestion des bans IP — liste de bans persistante avec grid admin (filtrable, mass-unban), exports toutes les 5 minutes au format nginx / Apache / plain pour un blocage au niveau edge. Intégration fail2ban complète incluse.
  • Security Checker — audit en 17 points (credentials admin, 2FA, HTTPS, cache, fichiers exposés, configuration SMTP, statut OTP…) disponible dans l'UI admin, via CLI (wimakeit:security:check), et en cron quotidien.
  • Honeypot — lien footer invisible qui banne tout crawler qui le suit, à un coût quasi nul sur le trafic légitime.
  • Verrou de préproduction — une case à cocher et un mot de passe suffisent à rendre une préprod invisible aux robots et à quiconque n'a pas le mot de passe. Les requêtes verrouillées reçoivent un HTTP 503 avec en-têtes noindex et le robots.txt devient un Disallow: / global — c'est ce qui empêche réellement l'indexation, là où une page « bientôt disponible » en HTTP 200 est précisément ce qui se fait indexer. Couvre aussi REST et GraphQL, sans .htaccess ni accès au serveur web. En mode developer, il s'active tout seul, mot de passe compris — une préprod fraîchement clonée est protégée avant même qu'on pense à la configurer.

Compatibilité

  • Magento 2.4.x / Mage-OS
  • PHP 8.1, 8.2, 8.3, 8.4
  • Nécessite wimakeit/module-core ^3.0
  • Suggère wimakeit/module-smtp pour une livraison fiable de l'Admin Email OTP (fonctionne aussi avec les paramètres SMTP natifs de Magento et les extensions SMTP tierces)
  • Compatible avec Redis, OpenSearch, Varnish Full Page Cache
  • Fonctionne avec les frontends Luma et Hyvä

Installez ce module via Composer. Assurez-vous que votre auth.json est configuré avec vos identifiants Wimakeit.

Terminal
$ composer require wimakeit/module-security:^1.19.0
$ bin/magento setup:upgrade
$ bin/magento setup:di:compile

Installation notes

The standard composer require + setup:upgrade + setup:di:compile flow applies. The points below cover what's specific to this module.

Required dependency

This module requires wimakeit/module-core ^3.0. Composer will pull it automatically from the Wimakeit registry as long as the registry is declared in your project's composer.json.

Recommended dependency

For reliable Admin Email OTP delivery, install wimakeit/module-smtp. The module works with native Magento SMTP settings too (Stores → Configuration → Advanced → System → Mail Sending Settings), and with third-party SMTP extensions (Amasty, Mageplaza, MagePal, Ebizmarts).

Whichever you use, prove delivery before enabling the OTP — see Admin Login OTP below. If the code cannot be delivered the module lets the login through rather than locking anyone out, but the second factor then protects nothing.

ACL permissions

Six ACL resources are created under System → Permissions → User Roles:

ResourceDefault
Wimakeit_Security::overview (Security Overview page)Administrator only
Wimakeit_Security::stress (Under Attack mode — arm/release)Administrator only
Wimakeit_Security::bans (IP Bans grid + mass unban)Administrator only
Wimakeit_Security::login_log (Admin Login Log grid)Administrator only
Wimakeit_Security::checker (Security Checker page)Administrator only
Wimakeit_Security::config (module configuration)Administrator only

Configuration

All config is under Stores → Configuration → Wimakeit → Security. Defaults are safe for production — change only what you need.

General

SettingDefault
Enable Search GuardYes
IP Whitelist(empty) — one entry per line, supports exact IP, wildcard (203.0.113.*), IPv4/IPv6 CIDR
Trust Verified Search Engine BotsYes — Googlebot, Bingbot, etc. are exempt after forward-confirmed reverse DNS
Enable Debug LoggingNo — leave off in production; blocked requests always log to wimakeit_security.log

Preproduction Lock

Off by default in production. Turn it on to keep a staging store invisible to crawlers and to anyone without the access password — no .htaccess, no vhost access needed.

In developer mode it switches itself on, since a developer-mode store is by definition not a production store. Only developer mode — never default mode, and never production, so upgrading a live store changes nothing. With no password configured, one is derived from the environment's encryption key and shown on the Security Overview, in the admin banner and by bin/magento wimakeit:security:preprod-lock; the admin panel is never locked, so it stays readable.

To unlock a developer-mode store, set Auto-Lock in Developer Mode to No — the Enable Preproduction Lock checkbox alone is not enough:

bin/magento config:set wimakeit_security/preprod_lock/auto_dev_mode 0
bin/magento cache:clean config full_page

Conversely, putting a live store into developer mode to debug something will lock the storefront.

SettingDefault
Enable Preproduction LockNo
Auto-Lock in Developer ModeYes — the lock engages on its own when Magento runs in developer mode
Access Password(empty) — the lock stays inert until one is set, so it can never lock everyone out (in developer mode, a derived one is used instead). Shown in clear so it can be sent to the client; stored as-is in core_config_data, so use a throwaway password
Access Duration (days)7 — how long a visitor stays unlocked after entering the password
Also Lock REST & GraphQLYes — left open, /graphql keeps answering anonymously and the catalog stays scrapable
Whitelisted IPs Bypass the LockYes — reuses the General group's IP whitelist
Always Allowed Paths/static/, /media/ — add payment callbacks, webhooks and health checks here
Gate Title / Message / Logo URL(empty) — the gate page is self-contained (inline CSS, no script, no theme)

Locked requests answer HTTP 503 + X-Robots-Tag: noindex, nofollow, noarchive and /robots.txt becomes a blanket Disallow: /. The admin panel is never locked.

> The robots.txt override applies when Magento serves robots.txt itself. A physical pub/robots.txt is returned by the web server without reaching PHP and shadows it (as well as your admin Search Engine Robots setting) — the Security Checker flags this. The 503 keeps every URL out of the index regardless.

After enabling, flush the full page cache (and Varnish, if any) — pages cached before the lock went on are served without reaching PHP.

Ways in: the password page (sets a signed cookie), Authorization: Basic with any username (curl, uptime monitors, CI), a shareable ?wsec_unlock=<password> link, or a whitelisted IP. Changing the password instantly revokes every access already handed out.

CLI escape hatch:

bin/magento wimakeit:security:preprod-lock                       # status + current password
bin/magento wimakeit:security:preprod-lock --enable -p 'secret'
bin/magento wimakeit:security:preprod-lock --disable             # before go-live

Per-IP Rate Limit

SettingDefault
EnableYes
Max Requests per Window30
Window (seconds)60

Sitewide Circuit Breaker (Stress Mode)

SettingDefault
EnableYes
Global Threshold (requests/minute)120 — total search requests across all IPs
Stress Mode Duration (seconds)600 — auto-extended while the flood lasts
Alert Email(empty) — leave empty to disable alert emails

REST API Guard

SettingDefault
EnableYes
Guarded Path Fragments/V1/cmsPage, /V1/cmsBlock, /V1/guest-carts
Block Guarded Paths EntirelyNo — throttle mode (note: full-block on /V1/guest-carts breaks guest checkout)
Max Requests per Window (per IP)20
Window (seconds)60

GraphQL Guard

SettingDefault
EnableYes
Max Requests per Window (per IP)60 — generous for headless/PWA storefronts
Window (seconds)60

Auto-Ban

SettingDefault
EnableYes
Violations Before Ban3
Violation Window (seconds)600

Honeypot

SettingDefault
EnableNo — add Disallow: /wsecurity/ to robots.txt before enabling

Admin Login Guard

SettingDefault
EnableYes
Max Failed Attempts5
Window (seconds)600

Admin Login OTP

SettingDefault
Enable Admin Email OTPYes
Code Validity (seconds)300 (5 minutes)
Max Invalid Attempts (dropdown: 3 / 5 / 10)5
Bypass OTP for Whitelisted IPsYes

To use Admin Email OTP, each admin user must have a valid email address set in System → Permissions → All Users. Users without an email address will be logged in normally (with a warning in the security log) rather than being locked out.

Verify email delivery first. Click Send Test OTP Email in the same configuration group (leave the field empty to send to your own admin address), or run:

bin/magento wimakeit:security:otp-test-mail --to=you@example.com

Both send a real message through the same template and transport a genuine login uses, and report the actual transport error when it fails. No configuration screen can answer this on its own: each SMTP extension stores its settings elsewhere, and wrong credentials look exactly like right ones. Once a test succeeds, the Security Checker reports the date it was proven; until then an admin banner asks for it.

One setting deserves attention: Advanced → System → Mail Sending Settings → Disable Email Communications. When it is Yes, Magento discards every message without raising an error — including through third-party SMTP extensions, which replace the transport rather than that check. The module detects it, refuses to report a successful test, and skips the OTP instead of arming a code nobody will receive.

The module always fails open — no email address on file, mail sending disabled, transport error or cache failure all let the admin in with a line in var/log/wimakeit_security.log naming the cause. Should a lock-out happen anyway, note that a new code is issued on each login, so the way back in is the CLI:

bin/magento config:set wimakeit_security/admin_otp/enabled 0
bin/magento cache:flush

On a local copy the OTP is skipped automatically: when the configured admin URL (admin/url/custom if enabled, otherwise web/secure/base_url) is localhost, .localhost or .local, a correct password logs the admin in and reason=local_host is logged. The request's Host header is never consulted, so a live store cannot be made to skip it.

While Admin Email OTP is enabled, password-based admin API tokens are refused (POST /rest/V1/integration/admin/token) — otherwise a leaked password would yield full API access without OTP. Machine / API clients (external apps, scripts, monitoring) must authenticate with a Magento Integration (consumer key / secret) created under System → Extensions → Integrations, which is not password-derived and therefore not subject to OTP.

Bad Bot Guard

SettingDefault
EnableYes
Block Malicious ScannersYes — sqlmap, nikto, nmap, masscan…
Block Email/Content HarvestersYes — apache-badbots list
Block Aggressive Scrapers / SEO BotsNo — AhrefsBot, SemrushBot, MJ12bot…
Block AI CrawlersNo — GPTBot, ClaudeBot, CCBot…
Custom User-Agent Patterns(empty) — one substring per line
Dry-Run (log only, do not ban)No

Query Validation

SettingDefault
EnableYes
Max Query Length (characters)128 — set 0 to disable
Max Word Count12 — set 0 to disable
Allowed Writing Systems(empty) — no filtering. Comma-separated Unicode script names (e.g. Latin); a query containing a character from any other script is answered HTTP 400. Digits, punctuation and accents always pass. Set per project

Customer Registration Guard

SettingDefault
Enable Registration GuardYes
Refused Mail Domains(empty) — one per line, without @; exact match, subdomains not covered
Refuse a URL in the name fieldsYes
Refuse identical first and last nameNo — also refuses customers genuinely named "Martin Martin"

Stores migrating from a project-level registration antispam module must re-enter their refused domains: the list ships empty.

Payment Failure Mail Guard

SettingDefault
Suppress failure emails for empty cartsYes — a real payment failure always concerns a cart with items

Cron jobs (registered automatically)

JobSchedulePurpose
wimakeit_security_export_bansevery 5 minExport active bans to var/wimakeit_security/ (nginx / Apache / plain)
wimakeit_security_daily_checkdaily 4 AMRun security checklist, log degraded items
wimakeit_security_daily_maintenancedaily 3:30 AMPurge login log and stats older than 90 days; delete expired ban rows

No setup needed — just make sure Magento cron is running.

Optional: fail2ban integration

A ready-to-use fail2ban filter and jail example are included in docs/fail2ban/. fail2ban tails var/log/wimakeit_security.log and bans attacking IPs at the iptables/nftables level before they hit PHP. Recommended when the module's in-application bans are insufficient (e.g. the attacking IP has already consumed a full php-fpm slot before being blocked).

Optional: edge configuration export

Run bin/magento wimakeit:security:edge-config to generate nginx / .htaccess snippets that mirror the current module configuration (banned IPs, guarded paths, honeypot route). Paste these into your vhost for kernel-level enforcement independent of PHP.

Version
v1.19.0
Licence
Abonnement annuel
Support
12 mois
Dernière mise à jour
17 sept. 2026
Magento
Magento 2.4.4 Magento 2.4.5 Magento 2.4.6 Magento 2.4.7 Mage-OS 2.0 Mage-OS 2.1
PHP
PHP 8.1 PHP 8.2 PHP 8.3
Hyvä
Compatible
Package
wimakeit/module-security

Vérifier la compatibilité

Indiquez votre stack pour vérifier la compatibilité du module.

Changelog

Categories: Security, Feature, Fix, Perf, Admin, Deps.

[1.17.0] - 2026-09-15

Feature

  • Sur une copie locale (localhost, .localhost, .local), le code de connexion admin n'est plus demandé : aucun email ne peut y arriver, et plus besoin de couper l'OTP à la main sur chaque clone.
  • La décision se fonde sur l'URL admin configurée, jamais sur l'en-tête de la requête : une boutique en ligne ne peut pas être amenée à sauter le second facteur.

[1.16.0] - 2026-09-14

Security

  • Plus d'emails « Payment Transaction Failed » pour un panier vide ou absent : ils étaient l'effet de bord des campagnes qui sondent les endpoints de paiement. Actif par défaut.
  • Une vraie erreur de paiement concerne toujours un panier avec des articles : aucune alerte réelle n'est perdue. Les tentatives filtrées vont dans le log de sécurité.
  • Un appel de paiement PayPal sans panier ne provoque plus d'erreur 500 ni de rapport d'erreur.

[1.15.0] - 2026-08-31

Security

  • Nouveau garde à l'inscription client : refus des comptes aux domaines email interdits, avec une URL dans le nom ou (en option) un prénom identique au nom.
  • Le visiteur refusé voit un message neutre qui ne dit pas quelle règle l'a bloqué ; la règle déclenchée est journalisée. Les IPs en liste blanche sont exemptées.
  • La liste de domaines refusés est vide par défaut : un domaine de bots pour une boutique est une clientèle réelle pour une autre. À renseigner par projet.
  • Corrige trois défauts de l'ancien antispam d'inscription qu'il remplace : une URL en tout début de prénom passait, un nom contenant le prénom était refusé, une adresse mal formée provoquait une erreur.

[1.14.0] - 2026-08-31

Security

  • La recherche peut être limitée aux systèmes d'écriture de la boutique (ex. Latin) : une requête en cyrillique, japonais ou arabe reçoit une erreur 400 avant le moteur de recherche.
  • Arrête les campagnes de parasitage de mots-clés qui font indexer des pages de résultats en langue étrangère. Chiffres, ponctuation et accents passent toujours.
  • Vide par défaut, y compris après mise à jour. Le Security Checker signale quand les recherches récentes montrent une campagne en cours.

[1.13.0] - 2026-08-19

Fix

  • Le test d'envoi du code de connexion dit désormais ce qui manque au lieu de relayer le message du fournisseur de messagerie. Quand l'adresse d'expéditeur de la boutique n'a jamais été renseignée, Magento utilise en silence l'adresse d'exemple livrée par défaut, et le serveur de messagerie refuse l'envoi au nom d'une adresse qui n'est pas la vôtre. Le message d'erreur venait alors du fournisseur, dans ses termes, sans jamais nommer la cause réelle : un champ resté vide.
  • Le contrôle a lieu avant toute tentative d'envoi, et indique précisément quel réglage est vide, invalide ou encore sur la valeur d'exemple d'origine.
  • Les autres adresses d'expéditeur de la boutique sont vérifiées en même temps. Réparer le code de connexion vous signale donc aussi, dans la foulée, que vos confirmations de commande et vos réinitialisations de mot de passe échouent pour la même raison — ce que rien d'autre ne remontait.
  • Si un module d'envoi SMTP est installé, l'adresse qu'il utilise est proposée directement : c'est la seule que votre fournisseur acceptera à coup sûr.

[1.12.1] - 2026-08-18

Fix

  • Des clients pouvaient être bloqués pendant leur commande. La protection surveillait le panier avec un seuil trop bas et bannissait l'adresse après quelques dépassements : quelques secondes de navigation normale suffisaient à couper le tunnel d'achat.
  • Le panier n'est plus surveillé par défaut, et un simple dépassement de débit ne provoque plus de bannissement — la requête est ralentie puis repart d'elle-même.
  • Seuils relevés pour laisser passer un bureau ou une connexion mobile partagée sans jamais gêner un visiteur.

[1.12.0] - 2026-08-07

Fix

  • The Admin Email OTP could leave the browser bouncing between two admin pages until it gave up. The verification form appears in the short window between a correct password and a usable admin session, and on some stores Magento's own security-key check rejected the form before it could render, sending the browser to the admin start page — which the OTP guard sent straight back to the form. The result was ERR_TOO_MANY_REDIRECTS and an administrator locked out, holding a perfectly valid code. The form is now exempt from that check, exactly as Magento's own Forgot password and Reset password pages are. Submitting the code stays as protected as before.
  • A redirect the administrator cannot satisfy now gives up. If the verification form fails to appear five times in a row, the second factor stands down for that login and lets the administrator in, with the reason written to the security log. It joins the situations the module already resolves in the administrator's favour — no email on file, email sending switched off, cache unavailable — on the same principle: being locked out of your own store is the worse outcome. The safeguard disarms itself the moment the form appears once, so normal use never triggers it.
  • Logging in now clears whatever the previous login left behind, so a session can no longer be held against a code that has already expired.

[1.11.0] - 2026-08-03

Feature

  • The preproduction lock now switches itself on in developer mode. A store running in developer mode is not a production store, and leaving it publicly reachable is exactly what the lock exists to prevent — so it no longer waits for someone to remember the checkbox on every new staging clone. Only developer mode triggers it, never default or production, so a live store is never affected by the upgrade.
  • If no password is set, one is derived from the environment's encryption key and shown on the Security Overview, in the admin banner and by the CLI. Nothing to configure, nothing stored, and the admin panel is never locked so it stays readable.
  • Turning it off is one switch — Auto-Lock in Developer Mode — spelled out in the admin banner and the CLI output, because a store that will not unlock is worse than one that never locked.

[1.10.0] - 2026-08-03

Fix

  • The Admin Email OTP could lock every administrator out when email sending was switched off. With Disable Email Communications set to Yes, Magento discards outgoing mail silently — no send, and no error either. The module believed the code had gone out, put the session in "awaiting code" state, and every admin page redirected to a form waiting on a code nobody would ever receive. Logging out did not help: the next login issued another undeliverable code. The only way back in was the command line. Delivery is now checked before the second factor is armed, and the login goes through with a log line naming the cause — joining the three other failure paths that already let the admin in rather than out.
  • That setting also silences third-party SMTP extensions (Amasty, Mageplaza, wimakeit/module-smtp…), so a perfectly configured SMTP module did not protect against it.

Feature

  • Prove OTP email delivery before turning the OTP on. A Send Test OTP Email button in the configuration, and bin/magento wimakeit:security:otp-test-mail --to=you@example.com on the command line, send a real message through the same template and transport a genuine login uses, and report the actual error when it fails. No configuration screen can answer "will the code arrive?" — each SMTP extension keeps its settings elsewhere, and wrong credentials look exactly like right ones.
  • The result is remembered: the Security Checker now states "Delivery proven by a real send on <date>" instead of guessing from settings, and an admin banner stands until delivery has been proven on that environment.

Admin

  • The SMTP checklist item no longer mistakes a working setup for a broken one. It previously recognised only wimakeit/module-smtp and warned on healthy Amasty and Mageplaza installs, while passing a host whose credentials were wrong. It now recognises the five common SMTP extensions, fails outright when mail sending is off while the OTP is on, and passes only on delivery actually proven.

[1.9.0] - 2026-08-03

Feature

  • Preproduction Lock — one checkbox and one password field keep a staging store invisible to crawlers and to anyone without the password. Locked requests answer HTTP 503 with noindex headers and robots.txt becomes a blanket Disallow: /, which is what actually keeps a preprod out of search results — a "coming soon" page returning HTTP 200 is exactly what gets indexed. No .htaccess, no web server access required.
  • The lock covers the storefront, REST and GraphQL, so the catalog is not left scrapable through /graphql while the storefront is locked. Payment callbacks, webhooks and health checks stay reachable through a configurable allow-list.
  • Access is granted by a signed cookie after entering the password, or through Authorization: Basic (for curl, uptime monitors and CI), a shareable one-click link, or a whitelisted IP. Changing the password instantly revokes every access already handed out.
  • The password page is fully self-contained — no stylesheet, no script, no theme — so a locked store shrugs off a bot flood and the page renders even if the storefront theme is broken. Title, message and logo are configurable.

Admin

  • The Security Checker also warns when a physical pub/robots.txt is present: the web server returns it without reaching PHP, shadowing both the lock's blanket Disallow: / and the admin's own Search Engine Robots setting.
  • A standing banner while the lock is on, a badge on the Security Overview, and a new Security Checker item catching both failure directions: a staging store left publicly indexable, and a production store shipped with the lock still enabled.
  • CLI escape hatch: bin/magento wimakeit:security:preprod-lock --enable|--disable|--password=….

Fix

  • Blocked-event statistics were silently losing data. A column-type issue made the database rewrite each hourly counter's timestamp on every increment, which broke the row's unique key and dropped the event. The Security Overview chart and 7-day totals therefore under-reported blocked traffic. Fixed, and existing counters are repaired automatically on upgrade — no data is lost.

Security

  • Wrong passwords feed the existing auto-ban machinery, so brute forcing the gate ends in a ban.
  • Verified search engine bots are deliberately not exempted from the lock, unlike everywhere else in the module.

[1.8.0] - 2026-06-16

Security

  • Admin Email OTP now also covers the API, not just the browser login. The standard admin token endpoint (POST /rest/V1/integration/admin/token) previously issued a full admin API token on username + password alone — bypassing OTP entirely. Password-based admin tokens are now refused while Admin OTP is enabled; machine/API clients use a Magento Integration (consumer key / secret) instead.

Admin

  • The Admin OTP email is now a branded, styled HTML message (header bar, prominent code box, footer) instead of unstyled text. It is deliberately self-contained so that a rendering failure can never block delivery and silently let a login through without a code.

[1.7.1] - 2026-06-15

Fix

  • The Admin OTP verification page now displays as a clean, centered login card. It previously rendered with a broken layout and an on-screen error because it loaded the full admin dashboard chrome on a mid-login page.

[1.7.0] - 2026-06-15

Feature

  • Admin Email OTP is now enabled by default, with code validity shortened to 5 minutes (was off / 10 minutes) — new installs get post-login email verification out of the box, provided a working SMTP transport is configured.

Admin

  • Max Invalid Attempts is now a dropdown (3 / 5 / 10) instead of a free-text field. Shipped defaults: OTP enabled, code validity 300s, max attempts 5.

Fix

  • Admin OTP verification form could not be displayed: it failed with a fatal error on every load, so an admin with OTP enabled could never enter their code. The verification form now renders correctly, including the "incorrect code" message on a wrong attempt.

[1.6.0] - 2026-06-15

Feature

  • Admin Email OTP: after a correct password login, a 6-digit code is emailed to the admin's registered address before access is granted. Stolen credentials alone can no longer access the admin panel — the attacker would also need the admin's mailbox.
  • Code is cryptographically random, stored SHA-256-hashed with a configurable TTL (default 10 min). After a configurable number of wrong attempts (default 3), the code is invalidated and the admin is logged out.
  • Whitelisted IPs (General → IP Whitelist) can optionally bypass OTP, useful for trusted office networks.
  • Admin users without a registered email address are logged in normally with a warning — no lock-out scenario.

Admin

  • New config group Stores → Configuration → Wimakeit → Security → Admin Login OTP: enable toggle, code validity (seconds), max invalid attempts, whitelist bypass option.
  • Security Checker gains two new items: Admin Email OTP enabled (WARN when off) and SMTP configured (WARN when OTP is active but no SMTP transport is detected).

[1.5.2] - 2026-06-12

Security

  • ACL privilege separation: the Under Attack mode (stress enable/disable) and the Overview page now have dedicated ACL resources, so a sub-permission no longer implicitly grants the ability to arm or release stress mode.

Fix

  • Search route double-block fixed: a bad-bot User-Agent on a search URL was blocked by the Bad Bot Guard and then again by the Search Guard, overwriting the response and double-counting the ban hit.
  • "Blocked While Banned" hit counter now only increments against currently active bans, not expired rows.
  • Log sanitizer applied consistently to the action= field and caught DB exception messages.

Admin

  • Bad Bot Guard config group now has a unique sortOrder; removed the misleading "(UTC)" suffix from IP Bans grid date columns (the UI already renders them in the admin timezone).

[1.5.1] - 2026-06-12

Admin

  • Security Overview page rebuilt with native Magento admin components: status pills (grid-severity-*), admin__page-section blocks, message notices, and data-grid tables instead of inline-styled custom HTML.
  • Security Checker and Admin Login Log status badges now use native PASS/WARN/FAIL pills.

[1.5.0] - 2026-06-12

Feature

  • IP Bans grid: replaced the static bans table with a full Magento UI component listing — per-column filters (IP, provenance, date ranges), sorting, pagination, column controls, bookmarks, and a mass Unban action (CSRF-safe via UI framework). Expired bans are now visible too, with an active/expired status column.
  • Provenance column: shows the ban reason (search throttle, REST/GraphQL, admin brute force, honeypot, bad-bot category) as a filterable select.
  • Blocked While Banned counter: a persistent hit count per ban row, incremented each time an already-banned IP is rejected — shows how hard a banned IP keeps hammering.

[1.4.0] - 2026-06-12

Feature

  • Bad Bot Guard: site-wide predispatch guard across all frontend routes that bans bots by User-Agent. Four switchable categories: malicious scanners (sqlmap, nikto, nmap…), email/content harvesters (apache-badbots list, modernised), aggressive SEO scrapers (AhrefsBot, SemrushBot, MJ12bot…), AI crawlers (GPTBot, ClaudeBot, CCBot…). Each category is an independent admin toggle.
  • Scanners are banned 24h immediately; other categories use the progressive TTL. Bans feed into the existing export pipeline and fail2ban log.
  • Custom User-Agent substrings (one per line) on top of built-in categories.
  • Dry-Run mode: logs matches (BAD-BOT-DRYRUN) without blocking — validate a list against real traffic before arming it.
  • Verified search engines and whitelisted IPs are never banned regardless of User-Agent.

[1.3.2] - 2026-06-12

Fix

  • Hotfix: setup:di:compile failed because Block classes redeclared a $formKey property already defined in Magento\Backend\Block\Template. Removed the redundant injection; the base class already provides getFormKey().

[1.3.1] - 2026-06-11

Security

  • Log-injection / fail2ban spoofing fixed: CR/LF in a search query, user agent, or username was written verbatim into the fail2ban-parsed log, letting an attacker forge a log line and have fail2ban ban an arbitrary IP. All logged fields now pass through a sanitizer; query validation rejects control characters (HTTP 400).
  • Array request params (?q[]=) handled: array values are now treated as empty instead of casting to the string "Array" and bypassing validation.
  • CSRF hardening: the Under Attack enable/disable and IP Unban actions are now POST + form key instead of GET links.
  • Email alert escaping: attacker-supplied username in the brute-force alert email is HTML-escaped.
  • Honeypot abuse mitigated: embedded sub-resource requests (Sec-Fetch-Dest: image) no longer trigger a ban, preventing a third-party <img> tag from banning your visitors.

Perf

  • No session start on the guard hot path: the trusted-client check no longer forces a session, avoiding a Redis session-write storm under flood and fixing breakage in the stateless GraphQL area.
  • Reverse-DNS flood protection: a per-minute budget caps blocking DNS lookups so spoofed-crawler floods cannot tie up workers.
  • AlertMailer is now lazy-loaded via Proxy so the mail stack is not instantiated on every guarded request.

Fix

  • banned_until column changed to datetime (removes the year-2038 ceiling on ban expiry).
  • GraphQL now returns 403 (not 429) for banned IPs, matching the semantics of the other guards.
  • Admin login ban now triggers on the configured Nth failure (was N+1).
  • Expired-ban purge moved to the daily maintenance cron (was the 5-minute export cron).

[1.3.0] - 2026-06-11

Feature

  • GraphQL Guard: plugin on the GraphQL front controller (before query parsing and schema generation) — per-IP rate limit on all /graphql requests (default 60/60s), auto-ban on repeat offenders. Search-shaped products(search:) queries also feed the sitewide circuit breaker and are rejected during stress mode.
  • Advanced search guarded: predispatch observer added on catalogsearch/advanced/result (same engine cost as standard search, obvious fallback target).
  • Carding protection: /V1/guest-carts added to the REST API Guard default paths — bots loop on payment-information to test stolen card numbers. Default API limit raised to 20/60s so a legitimate guest checkout never trips it.
  • IPv6 support: whitelist CIDR matching now handles IPv6 (binary comparison via inet_pton); verified-bot forward confirmation resolves AAAA records.
  • Client IP resolution checker: detects the proxy/CDN misconfiguration trap where per-IP limits and bans would target the proxy itself instead of the real client.

[1.2.0] - 2026-06-11

Feature

  • Admin Login Guard: every login attempt (success and failure) logged to a dedicated table, browsable under Wimakeit → Security → Admin Login Log. IPs exceeding the failure threshold (default 5 / 10 min) are auto-banned (progressive TTL) and blocked with HTTP 429 at predispatch. Alert email on ban. Whitelisted IPs are never banned.
  • Block statistics: hourly aggregated counters shown on the Security Overview page — 24h bar chart and 7-day totals by reason (throttled, stress-blocked, banned, REST/GraphQL, honeypot, admin brute force, bad-bot…).
  • Under Attack mode: one-click manual stress mode activation (1h) from the Overview page, before the automatic threshold trips; release button when active.

Admin

  • Daily maintenance cron purges the login log and statistics older than 90 days.

[1.1.0] - 2026-06-11

Feature

  • REST API Guard: throttles or fully blocks configured REST paths — defaults /V1/cmsPage and /V1/cmsBlock (recurring bot probing targets) — via a plugin on the webapi front controller, before routing, authentication, and deserialization.
  • Auto-ban: repeat throttle offenders get persistent bans with progressive TTL (5 min → 1h → 24h), stored in wimakeit_security_ban (cache-first hot path).
  • Ban exports (cron, every 5 min): var/wimakeit_security/banned_ips_nginx.conf, banned_ips_apache.conf, banned_ips.txt.
  • Honeypot (off by default): invisible rel="nofollow" footer link to /wsecurity/trap; followers are banned 24h. Verified bots and whitelisted IPs are exempt.
  • Security Checker: 13 checks covering admin usernames, 2FA, admin URL, secret keys, anonymous Web API access, template symlinks, production mode, cache types, HTTPS, HttpOnly cookies, search_query table bloat, exposed files, and guard status. Available in admin UI, CLI (wimakeit:security:check), and as a daily cron.
  • CLI wimakeit:security:edge-config: ready-to-paste nginx/.htaccess snippets matching the current module configuration.

[1.0.0] - 2026-06-11

Feature

  • Initial release — Search Guard designed after the 2026-06-10 botnet flood on catalogsearch/result.
  • Predispatch guard on the native search results page and Wimakeit Search autocomplete.
  • Per-IP rate limit (fixed window, cache-backed) with HTTP 429 and Retry-After.
  • Sitewide circuit breaker (stress mode): above a global req/min threshold, only clients with a session-bound form_key cookie are served — stops distributed botnets at ~1 request/IP.
  • Query validation (control characters, max length, max word count) with HTTP 400.
  • IP whitelist (exact IP, wildcard, IPv4 CIDR).
  • Verified search engine bot exemption (forward-confirmed reverse DNS, cached 24h).
  • Dedicated parsable log var/log/wimakeit_security.log (fail2ban-ready).
  • CRITICAL log entry and optional alert email on stress mode activation.

Vous avez trouvé un bug ? Faites-nous-en part.

Un court formulaire s'ouvre dans un nouvel onglet — le nom du module et votre langue sont déjà pré-remplis. Décrivez ce que vous avez tenté, ce qui n'a pas fonctionné, et nous vous répondrons sous un jour ouvré.

Signaler un bug pour Security
SKU module : wimakeit-module-security · Langue : fr_FR

Besoin d'aide ?

Notre équipe est disponible pour vous accompagner dans l'intégration.

Contactez-nous
Planifier un appel