{"id":312997,"date":"2026-05-26T08:56:42","date_gmt":"2026-05-26T08:56:42","guid":{"rendered":"https:\/\/es.wordpress.org\/plugins\/ipguardian-brute-force-firewall-para-abuseipdb\/"},"modified":"2026-10-19T06:14:53","modified_gmt":"2026-10-19T06:14:53","slug":"grantech-ip-firewall-for-abuseipdb","status":"publish","type":"plugin","link":"https:\/\/tah.wordpress.org\/plugins\/grantech-ip-firewall-for-abuseipdb\/","author":23499663,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"1.4.1","stable_tag":"1.4.1","tested":"7.1.4","requires":"6.0","requires_php":"8.0","requires_plugins":null,"header_name":"GranTech IP Firewall for AbuseIPDB","header_author":"Marc Gran","header_description":"Protect your WordPress site by detecting, blocking and reporting malicious IPs using the AbuseIPDB API. Includes brute-force protection on wp-login.php and XML-RPC.","assets_banners_color":"0b2028","last_updated":"2026-10-19 06:14:53","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"https:\/\/wordpress.org\/plugins\/grantech-ip-firewall-for-abuseipdb\/","header_author_uri":"https:\/\/grantech.es","rating":5,"author_block_rating":0,"active_installs":50,"downloads":1258,"num_ratings":2,"support_threads":1,"support_threads_resolved":1,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"1.0.0":{"tag":"1.0.0","author":"marcgran","date":"2026-05-26 09:17:48","revision":3548816},"1.0.1":{"tag":"1.0.1","author":"marcgran","date":"2026-05-28 13:35:35","revision":3552244},"1.0.2":{"tag":"1.0.2","author":"marcgran","date":"2026-06-08 19:36:21","revision":3565107},"1.0.3":{"tag":"1.0.3","author":"marcgran","date":"2026-06-08 20:11:17","revision":3565159},"1.0.5":{"tag":"1.0.5","author":"marcgran","date":"2026-08-01 15:51:13","revision":3631123},"1.1.0":{"tag":"1.1.0","author":"marcgran","date":"2026-08-14 10:56:41","revision":3647169},"1.2.0":{"tag":"1.2.0","author":"marcgran","date":"2026-08-17 20:10:04","revision":3651675},"1.3.0":{"tag":"1.3.0","author":"marcgran","date":"2026-10-03 19:59:42","revision":3726666},"1.4.0":{"tag":"1.4.0","author":"marcgran","date":"2026-10-18 09:28:13","revision":3752816},"1.4.1":{"tag":"1.4.1","author":"marcgran","date":"2026-10-19 06:14:53","revision":3754090}},"upgrade_notice":{"1.4.1":"<p>Urgent fix: version 1.4.0 could cause a fatal error after updating because some files were missing. Update now.<\/p>","1.4.0":"<p>New protections that use no API quota (404 scan detection, bot trap, username enumeration protection), a monitor mode and webhooks. All new features are off by default.<\/p>","1.3.1":"<p>Fixes untranslated text after updates (e.g. the &quot;What&#039;s new&quot; notice appearing in English).<\/p>","1.3.0":"<p>Adds the AbuseIPDB contributor badge, opt-in comment spam reporting, better report categories, accessible confirmations and a Catalan translation.<\/p>","1.2.0":"<p>Adds report evidence in the IP checker, a CIDR range scanner, a tool to withdraw your own reports, and configurable history window and blacklist size.<\/p>","1.1.0":"<p>Brand-new redesigned interface plus Tor blocking, API quota indicator, one-click block from the log, configurable retention and smarter API usage. Recommended update.<\/p>","1.0.5":"<p>Clickable IPs linking to AbuseIPDB and a new opt-in option to report XML-RPC attacks.<\/p>","1.0.4":"<p>Major security, privacy and feature update: fixes IP spoofing via proxy headers, stops exposing site URL\/usernames in public AbuseIPDB reports, adds email alerts, dashboard widget, IPv6 whitelist support and significant caching. Update strongly recommended.<\/p>","1.0.3":"<p>Minor fix: removes .gitignore file. Update recommended.<\/p>","1.0.2":"<p>Full internationalization \u2014 plugin now works correctly in any WordPress language. Update recommended.<\/p>","1.0.1":"<p>Fixes a bug where the blocklist page showed empty even when IPs were being blocked. Update recommended.<\/p>","1.0.0":"<p>First stable release. No previous versions exist.<\/p>"},"ratings":{"1":0,"2":0,"3":0,"4":0,"5":2},"assets_icons":{"icon-128x128.png":{"filename":"icon-128x128.png","revision":3726669,"resolution":"128x128","location":"assets","locale":"","width":128,"height":128},"icon-256x256.png":{"filename":"icon-256x256.png","revision":3726669,"resolution":"256x256","location":"assets","locale":"","width":256,"height":256}},"assets_banners":{"banner-1544x500.jpg":{"filename":"banner-1544x500.jpg","revision":3726669,"resolution":"1544x500","location":"assets","locale":"","width":1544,"height":500},"banner-772x250.jpg":{"filename":"banner-772x250.jpg","revision":3726669,"resolution":"772x250","location":"assets","locale":"","width":772,"height":250}},"assets_blueprints":{},"all_blocks":[],"tagged_versions":["1.0.0","1.0.1","1.0.2","1.0.3","1.0.5","1.1.0","1.2.0","1.3.0","1.4.0","1.4.1"],"block_files":[],"assets_screenshots":{"screenshot-1.png":{"filename":"screenshot-1.png","revision":3651678,"resolution":"1","location":"assets","locale":"","width":1074,"height":766},"screenshot-2.png":{"filename":"screenshot-2.png","revision":3651678,"resolution":"2","location":"assets","locale":"","width":1065,"height":775},"screenshot-3.png":{"filename":"screenshot-3.png","revision":3651678,"resolution":"3","location":"assets","locale":"","width":1068,"height":767},"screenshot-4.png":{"filename":"screenshot-4.png","revision":3651678,"resolution":"4","location":"assets","locale":"","width":1072,"height":766},"screenshot-5.png":{"filename":"screenshot-5.png","revision":3651678,"resolution":"5","location":"assets","locale":"","width":1069,"height":767}},"screenshots":{"1":"Dashboard: protection status, remaining AbuseIPDB API quota and 30-day security statistics.","2":"Live IP checker: abuse score, usage type, hostnames and the community's own recent reports as evidence.","3":"Blocklist: blocked IPs with score, source and expiry, plus one-click removal.","4":"Event log: full filterable history by IP and event type.","5":"Settings: sectioned options with toggle switches, plus the IP range scanner and report tools."}},"plugin_section":[262246],"plugin_tags":[264439,2439,1174,1951,600],"plugin_category":[54],"plugin_contributors":[264440],"plugin_business_model":[],"class_list":["post-312997","plugin","type-plugin","status-publish","hentry","plugin_section-dashboard-widgets","plugin_tags-abuseipdb","plugin_tags-brute-force","plugin_tags-firewall","plugin_tags-ip-blocker","plugin_tags-security","plugin_category-security-and-spam-protection","plugin_contributors-marcgran","plugin_committers-marcgran"],"banners":{"banner":"https:\/\/ps.w.org\/grantech-ip-firewall-for-abuseipdb\/assets\/banner-772x250.jpg?rev=3726669","banner_2x":"https:\/\/ps.w.org\/grantech-ip-firewall-for-abuseipdb\/assets\/banner-1544x500.jpg?rev=3726669","banner_rtl":false,"banner_2x_rtl":false},"icons":{"svg":false,"icon":"https:\/\/ps.w.org\/grantech-ip-firewall-for-abuseipdb\/assets\/icon-128x128.png?rev=3726669","icon_2x":"https:\/\/ps.w.org\/grantech-ip-firewall-for-abuseipdb\/assets\/icon-256x256.png?rev=3726669","generated":false},"screenshots":[{"src":"https:\/\/ps.w.org\/grantech-ip-firewall-for-abuseipdb\/assets\/screenshot-1.png?rev=3651678","caption":"Dashboard: protection status, remaining AbuseIPDB API quota and 30-day security statistics."},{"src":"https:\/\/ps.w.org\/grantech-ip-firewall-for-abuseipdb\/assets\/screenshot-2.png?rev=3651678","caption":"Live IP checker: abuse score, usage type, hostnames and the community's own recent reports as evidence."},{"src":"https:\/\/ps.w.org\/grantech-ip-firewall-for-abuseipdb\/assets\/screenshot-3.png?rev=3651678","caption":"Blocklist: blocked IPs with score, source and expiry, plus one-click removal."},{"src":"https:\/\/ps.w.org\/grantech-ip-firewall-for-abuseipdb\/assets\/screenshot-4.png?rev=3651678","caption":"Event log: full filterable history by IP and event type."},{"src":"https:\/\/ps.w.org\/grantech-ip-firewall-for-abuseipdb\/assets\/screenshot-5.png?rev=3651678","caption":"Settings: sectioned options with toggle switches, plus the IP range scanner and report tools."}],"raw_content":"<!--section=description-->\n<p><strong>GranTech IP Firewall for AbuseIPDB<\/strong> connects your WordPress installation to the community-driven <a href=\"https:\/\/www.abuseipdb.com\/\">AbuseIPDB<\/a> database to automatically detect, block, and report abusive IP addresses before they can cause damage \u2014 now with a completely redesigned interface and proactive blacklist protection.<\/p>\n\n<h4>Key Features<\/h4>\n\n<ul>\n<li><strong>Real-time IP checks<\/strong> \u2014 Queries the AbuseIPDB API only on sensitive endpoints (wp-login.php, wp-admin, xmlrpc.php, comment submissions, and the JWT\/users REST routes) and blocks IPs exceeding your abuse score threshold. Regular page views and front-end traffic never trigger an API call.<\/li>\n<li><strong>Daily blacklist sync<\/strong> \u2014 Optionally downloads the 10,000 worst-reputation IPs once a day and blocks them instantly, without spending any check quota. Proactive protection before the first attack.<\/li>\n<li><strong>Brute-force protection<\/strong> \u2014 Detects attacks on wp-login.php and XML-RPC and blocks the offending IP after N failed attempts.<\/li>\n<li><strong>Automatic reporting<\/strong> \u2014 Reports attacking IPs to AbuseIPDB (Brute-Force + Web App Attack categories) with a fully customizable, privacy-safe public comment: your site URL and usernames are never exposed by default. Optionally reports comment spammers too (Blog Spam category) when a comment is marked as spam.<\/li>\n<li><strong>False-positive protection<\/strong> \u2014 IPs on the official AbuseIPDB whitelist (Googlebot, Bingbot, major CDNs) are never blocked.<\/li>\n<li><strong>Vulnerability scan detection<\/strong> \u2014 Blocks IPs that request many non-existent pages in a short time, as scanners do when probing for files like \/.env. No API quota used.<\/li>\n<li><strong>Bot trap (honeypot)<\/strong> \u2014 A hidden link that people never see and robots.txt tells search engines to ignore; bots that follow it anyway are blocked.<\/li>\n<li><strong>Username enumeration protection<\/strong> \u2014 Hides your usernames from anonymous visitors (?author=N, REST API users list, users sitemap, login error messages).<\/li>\n<li><strong>Monitor mode<\/strong> \u2014 Try every protection safely: nothing is blocked or reported, and what would have been blocked is logged.<\/li>\n<li><strong>Webhooks<\/strong> \u2014 Send blocks and attacks to n8n, Make, Zapier, Slack or Microsoft Teams, optionally signed with HMAC-SHA256.<\/li>\n<li><strong>Tor blocking<\/strong> \u2014 Optionally block Tor exit nodes on sensitive endpoints regardless of score.<\/li>\n<li><strong>Email alerts<\/strong> \u2014 Get notified when a brute-force attack is blocked (throttled to one email per attacking IP per hour).<\/li>\n<li><strong>Redesigned admin interface<\/strong> \u2014 Modern dashboard with status hero, light &amp; dark themes, API quota indicator, rich IP checker (usage type, distinct reporters, last report), 30-day activity chart and top offenders.<\/li>\n<li><strong>Investigation tools<\/strong> \u2014 See the community's own reports behind any score, scan whole CIDR ranges for reported addresses, and withdraw your own reports if an IP was flagged by mistake.<\/li>\n<li><strong>One-click actions<\/strong> \u2014 Block any IP straight from the event log or from a range scan; every IP links to its AbuseIPDB page for instant investigation.<\/li>\n<li><strong>Dashboard widget<\/strong> \u2014 Key security stats at a glance on the main WordPress dashboard.<\/li>\n<li><strong>Contributor badge<\/strong> \u2014 Display your AbuseIPDB contributor badge with the <code>[granipfi_badge]<\/code> shortcode or a widget; sites that link to AbuseIPDB can request \"supporter\" status, which comes with higher daily API limits.<\/li>\n<li><strong>Event log<\/strong> \u2014 Full filterable history, with configurable retention period.<\/li>\n<li><strong>Whitelist support<\/strong> \u2014 Exempt IPs or CIDR ranges (IPv4 and IPv6) from checks.<\/li>\n<li><strong>Smart quota management<\/strong> \u2014 Response caching, automatic backoff when the daily quota is exhausted, and no API calls for trusted logged-in users.<\/li>\n<li><strong>Reverse proxy support<\/strong> \u2014 Optional trusted-proxy mode for Cloudflare and load balancers (disabled by default to prevent IP spoofing).<\/li>\n<li><strong>Accessibility<\/strong> \u2014 WCAG-conscious interface: AA contrast in both themes, keyboard navigation, screen reader support, reduced-motion and high-contrast modes.<\/li>\n<\/ul>\n\n<h4>How It Works<\/h4>\n\n<ol>\n<li>Once a day (optional), the plugin syncs the AbuseIPDB blacklist locally \u2014 the worst 10,000 IPs are blocked instantly with zero API cost.<\/li>\n<li>When any other IP accesses a sensitive endpoint (login, XML-RPC, comment submission), the plugin queries the AbuseIPDB API.<\/li>\n<li>If the abuse confidence score meets or exceeds your threshold (default 50\/100), the IP is blocked automatically. Whitelisted crawlers like Googlebot are always allowed.<\/li>\n<li>If multiple failed login attempts are detected from the same IP, it is blocked and reported back to AbuseIPDB, and you can receive an email alert.<\/li>\n<li>Everything is recorded in a redesigned dashboard with real-time statistics.<\/li>\n<\/ol>\n\n<h4>API Requirements<\/h4>\n\n<p>A free account at <a href=\"https:\/\/www.abuseipdb.com\/register\">abuseipdb.com<\/a> is required.\nThe free plan includes <strong>1,000 checks per day<\/strong> plus daily blacklist downloads \u2014 more than enough for most sites when combined with the built-in caching, blacklist sync and smart quota management.<\/p>\n\n<h3>External Services<\/h3>\n\n<p>This plugin connects to the <strong>AbuseIPDB<\/strong> API (https:\/\/api.abuseipdb.com\/api\/v2\/) to check and report IP addresses.<\/p>\n\n<p><strong>What is AbuseIPDB?<\/strong>\nAbuseIPDB is a community-driven project that maintains a database of IP addresses reported for abusive behavior (spam, hacking, brute-force attacks, etc.). This plugin uses their public API to protect your WordPress site.<\/p>\n\n<p><strong>What data is sent and when?<\/strong><\/p>\n\n<ul>\n<li><strong>IP address check:<\/strong> When a visitor accesses a sensitive endpoint (wp-login.php, xmlrpc.php, comment submission), the visitor's IP address is sent to AbuseIPDB to retrieve its abuse confidence score. This only happens when the endpoint is accessed \u2014 not on regular page visits.<\/li>\n<li><strong>IP address report:<\/strong> When a brute-force attack is detected (configurable number of failed login attempts), the offending IP address is reported to AbuseIPDB along with a generic description of the attack. For privacy, your site URL and usernames are NOT included by default (the comment template is customizable). Reporting can be disabled in the plugin settings.<\/li>\n<li><strong>Blacklist download:<\/strong> If the daily blacklist sync option is enabled, the plugin downloads the AbuseIPDB blacklist once a day. No visitor data is sent in this request.<\/li>\n<li><strong>Comment spam report (optional, off by default):<\/strong> When enabled, the IP address of a comment classified as spam (by an anti-spam filter or by a moderator) is reported to AbuseIPDB with a generic description. The comment text and author details are never sent, and comments from registered users are never reported.<\/li>\n<li><strong>Scan and bot reports (optional, off by default):<\/strong> When enabled, IPs blocked by the 404 scan detection or the bot trap are reported to AbuseIPDB (categories Web App Attack and Bad Web Bot) with a generic, privacy-safe description.<\/li>\n<li><strong>Contributor badge (optional):<\/strong> If you enter your AbuseIPDB user ID and place the <code>[granipfi_badge]<\/code> shortcode or widget, your visitors' browsers load the badge image from abuseipdb.com (https:\/\/www.abuseipdb.com\/contributor\/). Nothing is loaded unless you place the shortcode or widget yourself.<\/li>\n<\/ul>\n\n<p><strong>No personal data<\/strong> other than IP addresses is ever transmitted to AbuseIPDB.<\/p>\n\n<p><strong>Webhooks (optional, off by default):<\/strong> If you enter a webhook URL, security events (event type, IP address, score, country, ISP, site URL and time) are sent to that URL \u2014 and only to that URL, which you choose. Nothing is sent while the webhook URL is empty.<\/p>\n\n<ul>\n<li>AbuseIPDB Terms of Service and Privacy Policy: https:\/\/www.abuseipdb.com\/legal<\/li>\n<\/ul>\n\n<h3>Privacy Policy<\/h3>\n\n<p>This plugin stores visitor IP addresses in the local WordPress database for the purpose of security logging and blocking. IP addresses are personal data under GDPR.<\/p>\n\n<ul>\n<li><strong>What is stored:<\/strong> IP addresses, associated ISP, country, and event type (e.g. blocked, failed login).<\/li>\n<li><strong>Why:<\/strong> To protect the site from malicious activity and brute-force attacks.<\/li>\n<li><strong>How long:<\/strong> Log entries are automatically deleted after a configurable retention period (90 days by default, minimum 7). Block entries expire based on the configured duration.<\/li>\n<li><strong>Third parties:<\/strong> IP addresses may be sent to AbuseIPDB (https:\/\/www.abuseipdb.com) for reputation checks and reporting. See the External Services section for details.<\/li>\n<li><strong>User rights:<\/strong> Site administrators can view and delete all stored data from the plugin's admin panel or by uninstalling the plugin.<\/li>\n<\/ul>\n\n<!--section=installation-->\n<ol>\n<li>Upload the <code>grantech-ip-firewall-for-abuseipdb<\/code> folder to the <code>\/wp-content\/plugins\/<\/code> directory.<\/li>\n<li>Activate the plugin through the <strong>Plugins<\/strong> menu in WordPress.<\/li>\n<li>Go to <strong>IP Shield \u2192 Settings<\/strong> in the WordPress admin menu and paste your AbuseIPDB API key.<\/li>\n<li>Adjust the score threshold and brute-force parameters to suit your needs.<\/li>\n<li>Done \u2014 your site is now protected.<\/li>\n<\/ol>\n\n<h4>Recommended Settings<\/h4>\n\n<ul>\n<li><strong>Block threshold:<\/strong> 50 (blocks IPs with &gt;50% abuse probability)<\/li>\n<li><strong>Block duration:<\/strong> 24 hours<\/li>\n<li><strong>Attempts before block:<\/strong> 5<\/li>\n<li><strong>Time window:<\/strong> 10 minutes<\/li>\n<li><strong>API cache:<\/strong> 60 minutes<\/li>\n<li><strong>Report brute-force:<\/strong> Enabled<\/li>\n<\/ul>\n\n<!--section=faq-->\n<dl>\n<dt id=\"do%20i%20need%20a%20paid%20abuseipdb%20account%3F\"><h3>Do I need a paid AbuseIPDB account?<\/h3><\/dt>\n<dd><p>No. The free plan includes 1,000 checks per day, which is more than enough for most sites when the caching system is enabled.<\/p><\/dd>\n<dt id=\"will%20it%20block%20legitimate%20users%3F\"><h3>Will it block legitimate users?<\/h3><\/dt>\n<dd><p>It is unlikely. The plugin only queries the API on sensitive endpoints, never on regular page views. IPs on the official AbuseIPDB whitelist (Googlebot, Bingbot, major CDNs) are never blocked, and logged-in users with editing capabilities are skipped entirely, so you cannot lock yourself out of wp-admin. You can also add your own IPs or CIDR ranges to the plugin whitelist \u2014 recommended before activating.<\/p><\/dd>\n<dt id=\"what%20if%20my%20ip%20gets%20blocked%3F\"><h3>What if my IP gets blocked?<\/h3><\/dt>\n<dd><p>You can log into the admin panel and remove the IP from <strong>IP Shield \u2192 Blocklist<\/strong>. If you cannot access the admin panel, add your IP to the whitelist directly in the database: <code>UPDATE wp_options SET option_value = 'a:1:{i:0;s:X:\"YOUR.IP.HERE\";}' WHERE option_name = 'granipfi_whitelist';<\/code><\/p><\/dd>\n<dt id=\"is%20it%20compatible%20with%20cloudflare%3F\"><h3>Is it compatible with Cloudflare?<\/h3><\/dt>\n<dd><p>Yes. Enable the \"Trust proxy headers\" option in Settings and the plugin will read the CF-Connecting-IP header to obtain the real visitor IP. It is disabled by default for security (proxy headers can be spoofed on sites that are not behind a proxy).<\/p><\/dd>\n<dt id=\"can%20i%20block%20ips%20manually%3F\"><h3>Can I block IPs manually?<\/h3><\/dt>\n<dd><p>Yes. From <strong>IP Shield \u2192 Blocklist<\/strong> you can add any IP with a custom reason. Manual blocks are permanent by default.<\/p><\/dd>\n<dt id=\"how%20do%20i%20uninstall%20cleanly%3F\"><h3>How do I uninstall cleanly?<\/h3><\/dt>\n<dd><p>Deactivate and delete the plugin from the WordPress admin panel. All database tables (<code>wp_abuseipdb_log<\/code>, <code>wp_abuseipdb_blocklist<\/code> and <code>wp_granipfi_blacklist<\/code>) and options are removed automatically via <code>uninstall.php<\/code>.<\/p><\/dd>\n<dt id=\"for%20developers\"><h3>For Developers<\/h3><\/dt>\n<dd><p>The plugin exposes the following hooks:<\/p>\n\n<ul>\n<li><code>granipfi_report_comment<\/code> (filter) \u2014 Modify the public comment sent to AbuseIPDB. Receives the comment, the targeted username and the attempt count.<\/li>\n<li><code>granipfi_block_message<\/code> (filter) \u2014 Replace the HTML shown on the 403 block page.<\/li>\n<li><code>granipfi_brute_force_detected<\/code> (action) \u2014 Fires when a brute-force attack is blocked. Receives the IP, username and attempt count.<\/li>\n<li><code>granipfi_access_denied<\/code> (action) \u2014 Fires just before a request is denied. Receives the IP and the internal reason.<\/li>\n<li><code>granipfi_event_logged<\/code> (action) \u2014 Fires after every security event is logged. Receives the IP, event name, score, country, ISP and JSON extra data.<\/li>\n<li><code>granipfi_comment_spam_report<\/code> (filter) \u2014 Modify the public comment sent to AbuseIPDB for comment spam reports. Receives the text and the comment ID.<\/li>\n<\/ul><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>1.4.1<\/h4>\n\n<ul>\n<li>Fix: The 1.4.0 package published on WordPress.org was missing five new files, which caused a fatal error (\"Class GranIPFI\\Scan_Detector not found\") after updating. This release contains every file.<\/li>\n<li>Safety: The plugin now checks that all its files are present before starting. If an installation is ever incomplete, the plugin stays inactive and shows an admin notice instead of breaking the site.<\/li>\n<\/ul>\n\n<h4>1.4.0<\/h4>\n\n<ul>\n<li>New: Vulnerability scan detection \u2014 blocks IPs that trigger many 404 errors in a short time (configurable), ignoring missing images, styles and scripts. Uses no API quota.<\/li>\n<li>New: Bot trap (honeypot) \u2014 a hidden link, disallowed in robots.txt, that only bad bots follow.<\/li>\n<li>New: Username enumeration protection \u2014 blocks ?author=N, the REST API users list and the users sitemap for anonymous visitors, and makes login errors generic.<\/li>\n<li>New: Monitor mode \u2014 nothing is blocked or reported; every block that would have happened is logged as monitor_would_block. Clearly shown on the Dashboard.<\/li>\n<li>New: Webhooks in generic JSON, Slack or Microsoft Teams format, throttled and optionally signed (X-GranIPFI-Signature), with a \"Send test message\" button.<\/li>\n<li>New: Optional reporting of detected scanners (Web App Attack) and trapped bots (Bad Web Bot) to AbuseIPDB.<\/li>\n<li>New: granipfi_event_logged action for developers.<\/li>\n<li>New: Each bar of the activity chart now links to the event log filtered by that day, and the chart always shows the full 30 days (days without events included). The bars are keyboard and screen reader accessible.<\/li>\n<li>New: Date filter in the event log.<\/li>\n<li>Fix: Pagination in the event log no longer drops the active IP and event filters.<\/li>\n<li>Fix: The admin styles and scripts are now always refreshed after an update, instead of browsers or page caches serving an outdated copy.<\/li>\n<li>Safety: the new detections never block whitelisted IPs, logged-in editors, search engine crawlers or IPs on the official AbuseIPDB whitelist. All of them are off by default.<\/li>\n<\/ul>\n\n<h4>1.3.1<\/h4>\n\n<ul>\n<li>Fix: The translations bundled with the plugin are now loaded as a fallback, so new strings appear translated immediately instead of in English until they are approved on translate.wordpress.org. Approved language packs from WordPress.org still take priority.<\/li>\n<li>Improvement: The \"What's new\" notice is shown only for new feature releases, not again after small maintenance updates.<\/li>\n<li>Accessibility: Light-theme text colours now meet WCAG AA contrast (links, IP addresses and status chips were below 4.5:1).<\/li>\n<li>Accessibility: Correct heading hierarchy on every admin page (h1 \u2192 h2 \u2192 h3, no skipped levels).<\/li>\n<li>Accessibility: The activity chart now has a text alternative for screen readers, and links that open a new tab announce it.<\/li>\n<li>Fix: The IP checker verdicts (High risk, Suspicious, Clean, Tor exit node) were hardcoded in English; they are now translatable, and their decorative icons are hidden from screen readers.<\/li>\n<li>Security hardening: Translated strings are now escaped before being inserted into the page by JavaScript.<\/li>\n<\/ul>\n\n<h4>1.3.0<\/h4>\n\n<ul>\n<li>New: AbuseIPDB contributor badge \u2014 show it with the <code>[granipfi_badge]<\/code> shortcode or the \"AbuseIPDB Contributor Badge\" widget. Sites that link to AbuseIPDB can request \"supporter\" status (with higher daily API limits) by contacting AbuseIPDB; it is not granted automatically. Fully opt-in: nothing is shown until you enter your user ID and place the shortcode or widget.<\/li>\n<li>New: Opt-in reporting of comment spammers to AbuseIPDB (Blog Spam category). Only comments actually classified as spam are reported \u2014 on submission by an anti-spam filter such as Akismet, or when a moderator marks them as spam. Registered users and private IP ranges are never reported, and the comment text is never sent.<\/li>\n<li>Improvement: Login brute-force reports now use categories 18 + 21 (Brute-Force + Web App Attack), as AbuseIPDB recommends for attacks on WordPress.<\/li>\n<li>Improvement: Destructive actions (remove from blocklist, block a whole range, withdraw reports) now use accessible inline confirmations instead of native browser dialogs. This also removes the remaining inline JavaScript handlers and translates a confirmation message that was hardcoded in English.<\/li>\n<li>New: Catalan (ca) translation.<\/li>\n<\/ul>\n\n<h4>1.2.0<\/h4>\n\n<ul>\n<li>New: The live IP checker now shows the evidence behind a score \u2014 the community's own recent reports (date, reporter country and comment) in a collapsible panel, plus the resolved hostnames.<\/li>\n<li>New: IP range scanner (Tools) \u2014 check a whole subnet against AbuseIPDB (up to \/24 on the free plan), see every reported address sorted by score, and block them individually or all at once with a single button. Blocks respect your configured block duration, skip whitelisted IPs, and you stay on the scan results after blocking.<\/li>\n<li>New: \"Withdraw my reports\" tool \u2014 deletes the reports your own account submitted for an IP, useful when an address was reported by mistake (e.g. after a proxy misconfiguration).<\/li>\n<li>New: Configurable report history window (1-365 days, default 90) \u2014 lower values focus on currently active threats and reduce false positives.<\/li>\n<li>New: Configurable blacklist size (100-10,000 IPs) for the daily sync, so small hosting plans can keep the local table light.<\/li>\n<li>Fix: Removed the WooCommerce <code>wc-ajax<\/code> endpoint from firewall checks \u2014 store traffic no longer consumes API quota.<\/li>\n<li>Fix: Readme accuracy \u2014 corrected the admin menu name (IP Shield), the full list of protected endpoints, and documented all four public hooks for developers.<\/li>\n<\/ul>\n\n<h4>1.1.0<\/h4>\n\n<ul>\n<li>New: One-time dismissible \"What's new\" banner on the plugin Dashboard after each update, summarizing the highlights.<\/li>\n<li>New: Daily AbuseIPDB blacklist sync (opt-in) \u2014 downloads the worst-reputation IPs (up to 10,000) once a day into a local table and blocks them instantly on sensitive endpoints, without spending check quota.<\/li>\n<li>New: The official AbuseIPDB whitelist is now respected \u2014 whitelisted IPs (search engine crawlers, major CDNs) are never blocked, preventing false positives like blocking Googlebot.<\/li>\n<li>New: Richer live IP check \u2014 now shows usage type, domain, distinct reporters, last-reported date and whitelist\/Tor badges.<\/li>\n<li>New: Completely redesigned admin interface \u2014 modern dual theme (light by default, dark via system preference), GranTech brand identity (teal + navy), status hero on the Dashboard, toggle switches, Dashicons instead of emojis, section navigation in Settings, and refined tables, cards and charts.<\/li>\n<li>Accessibility: All WCAG improvements preserved and extended \u2014 AA contrast verified in both themes, teal focus rings, forced-colors and reduced-motion support, 40px+ touch targets.<\/li>\n<li>Fix: Live IP check was broken by a JavaScript syntax error \u2014 now working again.<\/li>\n<li>Security: The AbuseIPDB API key is no longer printed in the Settings page HTML source; leave the field empty to keep the saved key.<\/li>\n<li>Security: Numeric settings are now clamped server-side (e.g. a score threshold of 0 \u2014 which would block every visitor \u2014 can no longer be saved).<\/li>\n<li>Fix: Multi-line report comment templates no longer lose their line breaks when saved.<\/li>\n<li>New: Option to block Tor exit nodes on sensitive endpoints (opt-in), using the isTor flag already returned by the AbuseIPDB API.<\/li>\n<li>New: AbuseIPDB daily API quota indicator on the Dashboard (remaining\/limit with color coding), captured from the API response headers.<\/li>\n<li>New: Block button directly in the Event Log rows for one-click blocking of suspicious IPs.<\/li>\n<li>New: Configurable log retention period in Settings (default 90 days, minimum 7).<\/li>\n<li>Improvement: Automatic backoff when the daily API quota is exhausted (HTTP 429) \u2014 API checks pause until the quota resets at midnight UTC, keeping your site fast.<\/li>\n<li>Improvement: API check timeout reduced from 10s to 5s so visitors never wait long if AbuseIPDB is slow; reports keep the 10s timeout.<\/li>\n<li>Improvement: Authenticated users with editing capabilities are no longer checked against the API \u2014 saves quota and prevents locking yourself out of wp-admin.<\/li>\n<li>Improvement: Comment IP checks now require the real wp-comments-post.php endpoint, so unrelated forms with a \"comment\" field no longer trigger API calls.<\/li>\n<\/ul>\n\n<h4>1.0.5<\/h4>\n\n<ul>\n<li>New: IP addresses in the Blocklist, Event Log and Dashboard are now clickable \u2014 they open the corresponding AbuseIPDB check page (abuseipdb.com\/check\/{IP}) in a new tab for quick investigation. (Thanks for the suggestion!)<\/li>\n<li>New: Option to report XML-RPC attacks to AbuseIPDB (opt-in) \u2014 IPs exceeding the failed-attempts limit via XML-RPC are reported with categories Brute-Force + Web App Attack, using a vector-specific privacy-safe comment.<\/li>\n<li>Fix: Added missing translators comments to email notification strings (plugin checker warnings).<\/li>\n<\/ul>\n\n<h4>1.0.4<\/h4>\n\n<ul>\n<li>Security: IP detection no longer trusts proxy headers (X-Forwarded-For, CF-Connecting-IP) by default \u2014 prevents IP spoofing. New \"Trust proxy headers\" option for sites behind Cloudflare or a load balancer.<\/li>\n<li>Privacy: AbuseIPDB report comments no longer include the site URL or targeted username by default \u2014 reports are publicly visible on abuseipdb.com.<\/li>\n<li>New: Customizable report comment template in Settings with placeholders: {attempts}, {window}, {username}, {site}.<\/li>\n<li>New: granipfi_report_comment filter for developers to programmatically modify report comments.<\/li>\n<li>New: Email alerts \u2014 get notified when a brute-force attack is blocked (throttled to one per attacking IP per hour, configurable recipient).<\/li>\n<li>New: Dashboard widget \u2014 at-a-glance security stats on the main WordPress admin dashboard.<\/li>\n<li>Fix: \"Repair database tables\" button now works \u2014 the handler was never registered.<\/li>\n<li>Fix: CIDR whitelist now supports IPv6 ranges (previously IPv4-only).<\/li>\n<li>Fix: Cron cleanup is rescheduled automatically if it goes missing after a migration.<\/li>\n<li>Fix: Activation now records DB version to prevent unnecessary table recreation.<\/li>\n<li>Fix: Added missing event types (xmlrpc_blocked, xmlrpc_probe, report_failed) to the event log filter and styles.<\/li>\n<li>Fix: Spanish (es_ES) translation completed and aligned with the official WordPress.org es_ES glossary (informar, malintencionado, avisos, Escritorio, ajustes, caduca\u2026).<\/li>\n<li>Performance: is_blocked() result cached per-IP for 60 seconds \u2014 avoids a DB query on every request.<\/li>\n<li>Performance: Dashboard statistics cached for 5 minutes \u2014 avoids 3 heavy GROUP BY queries on every page load.<\/li>\n<\/ul>\n\n<h4>1.0.3<\/h4>\n\n<ul>\n<li>Fix: Removed .gitignore file not permitted in WordPress.org plugin repository.<\/li>\n<\/ul>\n\n<h4>1.0.2<\/h4>\n\n<ul>\n<li>i18n: Full internationalization \u2014 all admin view strings wrapped in __() translation functions.<\/li>\n<li>i18n: Plugin now displays correctly in any WordPress language based on site settings.<\/li>\n<li>i18n: English as source language; Spanish (es_ES) loaded automatically via .mo file.<\/li>\n<li>Fix: Removed remaining hardcoded Spanish strings from all admin views.<\/li>\n<li>Fix: CSS prefix updated \u2014 all classes renamed from shield- to granipfi-.<\/li>\n<li>Fix: JS global object renamed from AbuseIPDBShield to GranIPFI.<\/li>\n<\/ul>\n\n<h4>1.0.1<\/h4>\n\n<ul>\n<li>Fix: Blocklist page showing empty despite IPs being blocked \u2014 fixed by adding automatic DB table creation\/repair on every plugin load.<\/li>\n<li>Fix: Added DB version check (granipfi_db_version) to ensure tables are always present and up to date after updates or migrations.<\/li>\n<li>Improvement: Added database repair tool in Settings page for manual recovery.<\/li>\n<li>Fix: Admin panel title text color now correctly displays white on dark background.<\/li>\n<li>Accessibility: Added aria-hidden=\"true\" to all decorative dashicons.<\/li>\n<li>Accessibility: Added scope=\"col\" to all table header cells (17 instances).<\/li>\n<li>Accessibility: Added aria-label to all data tables.<\/li>\n<li>Accessibility: Added aria-live=\"polite\" and aria-atomic to AJAX result region.<\/li>\n<li>Accessibility: Added role=\"status\" to success notices and role=\"alert\" to error notices.<\/li>\n<li>Accessibility: Added aria-busy state to Verify IP button during async requests.<\/li>\n<li>Accessibility: Replaced <strong> with  on IP check input field.<\/strong><\/li>\n<li>Accessibility: Added for= attribute to filter labels in event log.<\/li>\n<li>Accessibility: Added aria-describedby to all settings form fields.<\/li>\n<li>Accessibility: All font sizes increased to minimum 12px (previously 10-11px).<\/li>\n<li>Accessibility: Removed outline:none from focus states \u2014 now shows visible 2px blue outline.<\/li>\n<li>Accessibility: Fixed focus-visible selector pointing to non-existent .shield-field class.<\/li>\n<li>Accessibility: Added focus and focus-visible styles for all interactive elements.<\/li>\n<li>Accessibility: Added border to score badges and event chips (non-color visual cue, WCAG 1.4.1).<\/li>\n<li>Accessibility: Added text-decoration:underline to pagination links (WCAG 1.4.1).<\/li>\n<li>Accessibility: Improved color contrast ratio of muted text: #8b949e \u2192 #a0aab8 (~5.2:1).<\/li>\n<li>Accessibility: Added prefers-reduced-motion support \u2014 disables transitions\/animations.<\/li>\n<li>Accessibility: Added forced-colors (Windows High Contrast) support with borders and forced-color-adjust.<\/li>\n<li>Accessibility: Added minimum touch target size 44x44px to buttons and pagination links (WCAG 2.5.8).<\/li>\n<li>Accessibility: Added screen-reader-text utility class (WordPress standard).<\/li>\n<\/ul>\n\n<h4>1.0.0<\/h4>\n\n<ul>\n<li>Initial release.<\/li>\n<li>Real-time IP checks against the AbuseIPDB v2 API.<\/li>\n<li>Automatic blocking based on configurable score threshold.<\/li>\n<li>Brute-force protection for wp-login.php and XML-RPC.<\/li>\n<li>Automatic reporting of aggressive IPs to AbuseIPDB.<\/li>\n<li>Admin dashboard with statistics and activity chart.<\/li>\n<li>Event log with filters.<\/li>\n<li>Manual blocklist with configurable expiry.<\/li>\n<li>Whitelist with CIDR range support.<\/li>\n<li>API response caching via WordPress transients.<\/li>\n<li>Cloudflare and reverse proxy support.<\/li>\n<li>Spanish (es_ES) translation included.<\/li>\n<\/ul>","raw_excerpt":"Protect your WordPress site by detecting, blocking and reporting malicious IPs using the AbuseIPDB API. Includes brute-force protection.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/tah.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/312997","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/tah.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/tah.wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/tah.wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=312997"}],"author":[{"embeddable":true,"href":"https:\/\/tah.wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/marcgran"}],"wp:attachment":[{"href":"https:\/\/tah.wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=312997"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/tah.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=312997"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/tah.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=312997"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/tah.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=312997"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/tah.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=312997"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/tah.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=312997"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}