{"id":355624,"date":"2026-08-24T15:55:12","date_gmt":"2026-08-24T15:55:12","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/solverguard-security-shield\/"},"modified":"2026-08-24T16:07:11","modified_gmt":"2026-08-24T16:07:11","slug":"solverguard-security-shield","status":"publish","type":"plugin","link":"https:\/\/wordpress.org\/plugins\/solverguard-security-shield\/","author":17927996,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"1.0.1","stable_tag":"1.0.1","tested":"7.1","requires":"6.4","requires_php":"8.0","requires_plugins":null,"header_name":"SolverGuard Security Shield","header_author":"SolverWp","header_description":"Complete WordPress security suite \u2014 login protection, web application firewall, security headers, file integrity monitoring, audit logging, and site hardening.","assets_banners_color":"011134","last_updated":"2026-08-24 16:07:11","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"https:\/\/profiles.wordpress.org\/solverwp\/","header_author_uri":"https:\/\/solverwp.com\/","rating":0,"author_block_rating":0,"active_installs":0,"downloads":48,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"1.0.1":{"tag":"1.0.1","author":"solverwp","date":"2026-08-24 16:07:11"}},"upgrade_notice":{"1.0.1":"<p>Addresses the WordPress.org review feedback. The sign-in history table changes\nshape on update: the old session column is removed and its contents discarded.\nYour history entries themselves are preserved.<\/p>","1.0.0":"<p>Initial release.<\/p>"},"ratings":[],"assets_icons":{"icon-128x128.png":{"filename":"icon-128x128.png","revision":3664468,"resolution":"128x128","location":"assets","locale":"","width":128,"height":128}},"assets_banners":{"banner-772x250.png":{"filename":"banner-772x250.png","revision":3663876,"resolution":"772x250","location":"assets","locale":"","width":2203,"height":714}},"assets_blueprints":{},"all_blocks":[],"tagged_versions":["1.0.1"],"block_files":[],"assets_screenshots":[],"screenshots":{"1":"The security dashboard, showing current status and recent activity.","2":"Firewall settings, with monitor mode and per-rule controls.","3":"The audit log, filterable by severity, event type, and IP address.","4":"File integrity results after a scan."}},"plugin_section":[],"plugin_tags":[8534,1174,1229,55021,600],"plugin_category":[54],"plugin_contributors":[190348],"plugin_business_model":[],"class_list":["post-355624","plugin","type-plugin","status-publish","hentry","plugin_tags-audit-log","plugin_tags-firewall","plugin_tags-login-security","plugin_tags-malware-scanner","plugin_tags-security","plugin_category-security-and-spam-protection","plugin_contributors-solverwp","plugin_committers-solverwp"],"banners":{"banner":"https:\/\/ps.w.org\/solverguard-security-shield\/assets\/banner-772x250.png?rev=3663876","banner_2x":false,"banner_rtl":false,"banner_2x_rtl":false},"icons":{"svg":false,"icon":"https:\/\/ps.w.org\/solverguard-security-shield\/assets\/icon-128x128.png?rev=3664468","icon_2x":false,"generated":false},"screenshots":[],"raw_content":"<!--section=description-->\n<p>SolverGuard Security Shield is a complete security suite for WordPress. Every protection is optional, every option is explained in plain language, and nothing is switched on behind your back.<\/p>\n\n<p><strong>A note on what security plugins can and cannot do.<\/strong> A plugin like this raises the cost of attacking your site: it turns away automated scanners, slows down password guessing, and tells you when something changes. It is not a substitute for keeping WordPress and your plugins updated, using strong unique passwords, and taking backups you have actually tested restoring. Anyone who promises more than that is overselling.<\/p>\n\n<h4>Login protection<\/h4>\n\n<ul>\n<li>Limit failed sign-in attempts per IP address and per username<\/li>\n<li>Progressive lockouts that lengthen for repeat offenders<\/li>\n<li>Optional strong-password policy<\/li>\n<li>A single generic error message, so the login form never confirms which usernames exist<\/li>\n<li>Sign-in history recording the address, browser, and device for each session<\/li>\n<\/ul>\n\n<h4>Firewall<\/h4>\n\n<ul>\n<li>SQL injection, cross-site scripting, directory traversal, and code injection detection<\/li>\n<li>Payloads are decoded before matching, so double-encoded and comment-split evasion still gets caught<\/li>\n<li>Known vulnerability scanners blocked by user agent<\/li>\n<li>XML-RPC can be disabled entirely, or limited to blocking pingback amplification<\/li>\n<li>Username enumeration blocked through both <code>?author=N<\/code> and the REST API<\/li>\n<li><strong>Monitor mode<\/strong> logs what would have been blocked without turning any visitor away \u2014 use it before enforcing<\/li>\n<\/ul>\n\n<h4>Two-factor authentication<\/h4>\n\n<ul>\n<li>Standard time-based codes (TOTP), so any authenticator app works \u2014 Google Authenticator, Authy, 1Password, and the rest<\/li>\n<li>Verified against the official RFC 6238 test vectors, so codes interoperate correctly<\/li>\n<li>Ten single-use recovery codes per account, stored only as hashes and shown once<\/li>\n<li>Can be required per role, with a grace period so nobody is locked out mid-rollout<\/li>\n<li>Each person enrols their own device from their profile, so no administrator ever holds someone else's secret<\/li>\n<li>Failed codes feed the same lockout counter as failed passwords, so guessing codes is rate limited too<\/li>\n<\/ul>\n\n<h4>Country blocking<\/h4>\n\n<p>Restrict access by country, using Cloudflare's header, WooCommerce's bundled database, or a remote lookup. Two honest caveats, both reflected in the defaults: geolocation is approximate, and a VPN sidesteps it in seconds. So the default scope is the sign-in form only \u2014 which cuts remote password guessing without making your content unreadable to a traveller \u2014 and visitors whose country cannot be determined are allowed through, because a lookup failure should never become a site outage.<\/p>\n\n<h4>Scheduled reports<\/h4>\n\n<p>Runs a file scan on a daily, weekly, or monthly schedule and emails a summary: what changed, how many events were recorded, which addresses are blocked, and which protections are switched off. Distinct from the alert digest \u2014 this one actively scans first rather than only recounting what already happened.<\/p>\n\n<h4>Hide login URL<\/h4>\n\n<p>Move the sign-in form to a private address so automated scanners never find it. This is obscurity rather than access control, and it works best alongside login limiting rather than instead of it.<\/p>\n\n<h4>Google reCAPTCHA<\/h4>\n\n<p>Version 2 checkbox or invisible version 3 scoring, on the sign-in, registration, password reset, and comment forms. Tokens are always verified server-side, and a missing token is treated as a failure \u2014 so posting directly to the form does not bypass the check.<\/p>\n\n<h4>Security headers<\/h4>\n\n<ul>\n<li>Content Security Policy, with a report-only mode so you can find breakages before enforcing<\/li>\n<li>HSTS, with a clear warning that browsers cache the instruction and you cannot revoke it early<\/li>\n<li>Referrer-Policy, X-Frame-Options, X-Content-Type-Options, and Permissions-Policy<\/li>\n<\/ul>\n\n<h4>File integrity and malware defence<\/h4>\n\n<ul>\n<li>WordPress core verified against the official checksums published by WordPress.org \u2014 stronger than a local baseline, which would simply record an attacker's files as legitimate if taken after a compromise<\/li>\n<li>Plugin and theme files compared against a baseline you capture when the site is known good<\/li>\n<li>Executable files in the uploads folder flagged, since nothing legitimate puts them there<\/li>\n<li>Pattern scanning for the shapes of code that backdoors take, reported for a human to judge rather than acted on automatically<\/li>\n<\/ul>\n\n<h4>WooCommerce security<\/h4>\n\n<ul>\n<li>Customer sign-in failures counted against the same lockout as the main login form<\/li>\n<li>Checkout throttling and declined-payment lockouts to stop your shop being used for card testing<\/li>\n<li>Order and customer data restricted over the REST API<\/li>\n<li>Order status changes and rejected coupons recorded<\/li>\n<\/ul>\n\n<h4>Audit log and login history<\/h4>\n\n<ul>\n<li>Role changes, account creation and deletion, plugin and theme changes, key setting changes, and uploads<\/li>\n<li>A user quietly gaining administrator is recorded as critical<\/li>\n<li>Filter by severity, event type, user, or IP address; export to CSV<\/li>\n<li>Configurable retention, and optional IP anonymisation for GDPR<\/li>\n<li>A separate Login History screen showing every sign-in with its address, browser, device, and session length<\/li>\n<\/ul>\n\n<h4>Dashboard<\/h4>\n\n<ul>\n<li>Headline counts that refresh themselves while the page is open, and pause when the tab is in the background so a forgotten tab does not keep querying your database<\/li>\n<li>A 14-day activity chart, drawn in plain CSS so there is no charting library to load and nothing to allow through a Content Security Policy<\/li>\n<li>Block an address by hand, with your own IP shown for reference and allow-listed addresses refused as a safety net<\/li>\n<\/ul>\n\n<h4>Backup and restore<\/h4>\n\n<p>Export every setting to a JSON file and apply it to another site. Your reCAPTCHA secret key is deliberately left out of the export, so the file is safe to attach to a support ticket. Imports are validated against the same rules as the settings forms, so an edited file cannot introduce unexpected options.<\/p>\n\n<h4>Alerts<\/h4>\n\n<p>Email alerts for events that need attention, rate limited per event type and capped per hour so one incident cannot flood your inbox. An optional daily summary covers everything else.<\/p>\n\n<h3>External services<\/h3>\n\n<p>This plugin can contact three external services. Two of them are only used when\nyou deliberately switch on the feature that needs them, and neither is contacted\nat all until then. Each is described below with what is sent, when, and why.<\/p>\n\n<h4>WordPress.org core checksums<\/h4>\n\n<p>The file integrity scanner compares your WordPress core files against the\nofficial checksums published by WordPress.org, so it can tell you if a core file\nhas been altered. When a core scan runs \u2014 either from the File Integrity screen\nor on the schedule you set \u2014 the plugin asks WordPress.org for the checksum list\nmatching your WordPress version and locale. It uses the <code>get_core_checksums()<\/code>\nfunction built into WordPress, which is the same mechanism WordPress core itself\nuses.<\/p>\n\n<p>What is sent: your WordPress version number and locale. No personal data, no\nsite address, and no file contents are transmitted; the comparison happens\nentirely on your own server.<\/p>\n\n<p>When: only while a core file integrity scan is running.<\/p>\n\n<p>Service: WordPress.org \u2014 https:\/\/api.wordpress.org\/core\/checksums\/1.0\/\nTerms of service: https:\/\/wordpress.org\/about\/privacy\/\nPrivacy policy: https:\/\/wordpress.org\/about\/privacy\/<\/p>\n\n<h4>Google reCAPTCHA<\/h4>\n\n<p>Used only if you enable reCAPTCHA and enter your own site key and secret key.\nWhen enabled, the plugin loads Google's reCAPTCHA script on the forms you have\nchosen to protect, and verifies the resulting token with Google's servers on\nsubmission.<\/p>\n\n<p>What is sent: on page load, your site key, and whatever the reCAPTCHA script\nitself collects from the visitor's browser as part of Google's bot assessment.\nOn form submission, your secret key, the reCAPTCHA token, and the visitor's IP\naddress are sent to Google's verification endpoint.<\/p>\n\n<p>When: on any page that shows a protected form, and again when that form is\nsubmitted. Never if the feature is switched off, which is the default.<\/p>\n\n<p>Because this sends visitor data to Google, you may need to mention it in your\nown privacy policy. The feature is off by default so that decision stays yours.<\/p>\n\n<p>Service: Google reCAPTCHA \u2014 https:\/\/www.google.com\/recaptcha\/api.js and\nhttps:\/\/www.google.com\/recaptcha\/api\/siteverify\nTerms of service: https:\/\/policies.google.com\/terms\nPrivacy policy: https:\/\/policies.google.com\/privacy<\/p>\n\n<h4>ipapi.co<\/h4>\n\n<p>Used only if you enable country blocking and no local geolocation database is\navailable on your server. It turns a visitor's IP address into a two-letter\ncountry code so the country rules you configured can be applied.<\/p>\n\n<p>What is sent: the visitor's IP address, and nothing else. The result is cached\nfor a week, so a repeat visitor from the same address is not looked up again.<\/p>\n\n<p>When: the first time an unrecognised IP address is checked against your country\nrules, and only while country blocking is switched on \u2014 which it is not by\ndefault.<\/p>\n\n<p>Because this sends visitor IP addresses to a third party, you may need to\nmention it in your own privacy policy.<\/p>\n\n<p>Service: ipapi.co \u2014 https:\/\/ipapi.co\/\nTerms of service: https:\/\/ipapi.co\/terms\/\nPrivacy policy: https:\/\/ipapi.co\/privacy\/<\/p>\n\n<!--section=installation-->\n<ol>\n<li>Upload the plugin folder to <code>\/wp-content\/plugins\/<\/code>, or install it through Plugins \u2192 Add New.<\/li>\n<li>Activate the plugin.<\/li>\n<li>Go to <strong>SolverGuard \u2192 Dashboard<\/strong> to see what is switched on.<\/li>\n<li>Add your own IP address to the allow list under <strong>Settings \u2192 Global access rules<\/strong> before enabling strict rules. This is the single best way to avoid locking yourself out.<\/li>\n<li>If you use a reverse proxy or CDN such as Cloudflare, set the visitor IP source under <strong>Settings \u2192 Visitor IP detection<\/strong>. Leaving it wrong means lockouts and blocklists act on the wrong address.<\/li>\n<\/ol>\n\n<h4>Locked out? There is a way back in<\/h4>\n\n<p>Every protection here can, if misconfigured, shut you out of your own site: a forgotten login address, a lockout on your own IP, a required second factor you never enrolled in. So the plugin ships WP-CLI recovery commands that keep working when the front door does not \u2014 the firewall and country blocking deliberately skip WP-CLI requests.<\/p>\n\n<pre><code>wp solverguard status              # what is on, and where the sign-in page is\nwp solverguard unblock &lt;ip&gt;        # release one address\nwp solverguard unblock --all       # release every address\nwp solverguard allow &lt;ip&gt;          # allow-list an address permanently\nwp solverguard login-url           # show the custom sign-in address\nwp solverguard login-url --disable # restore \/wp-login.php\nwp solverguard 2fa &lt;user&gt; --codes  # issue fresh recovery codes\nwp solverguard 2fa &lt;user&gt;          # remove two-factor from one account\nwp solverguard 2fa --all           # remove two-factor site-wide\nwp solverguard module &lt;id&gt; off     # switch one module off\nwp solverguard panic               # turn off everything that can block access\nwp solverguard scan                # run a file integrity scan\n\nwp solverguard panic is the one to remember. It switches off the firewall, login protection, hidden login address, reCAPTCHA, country blocking, and two-factor, and clears every IP block \u2014 but keeps your settings, so each module can simply be turned back on once you are in. Non-blocking protections such as security headers and hardening are left running.\n<\/code><\/pre>\n\n<!--section=faq-->\n<dl>\n<dt id=\"will%20this%20lock%20me%20out%20of%20my%20own%20site%3F\"><h3>Will this lock me out of my own site?<\/h3><\/dt>\n<dd><p>It can, if configured carelessly \u2014 that is true of every security plugin. Add your IP to the allow list first, and start the firewall in Monitor mode.<\/p>\n\n<p>If you do get locked out and have WP-CLI, run <code>wp solverguard panic<\/code>. Without WP-CLI, rename the plugin's folder over FTP or your host's file manager to deactivate it.<\/p><\/dd>\n<dt id=\"does%20the%20firewall%20replace%20secure%20coding%3F\"><h3>Does the firewall replace secure coding?<\/h3><\/dt>\n<dd><p>No. Pattern matching catches known and automated payloads, not novel ones. It buys time and cuts noise; it does not make vulnerable code safe. Keep everything updated.<\/p><\/dd>\n<dt id=\"why%20does%20the%20file%20scanner%20report%20changes%20after%20every%20plugin%20update%3F\"><h3>Why does the file scanner report changes after every plugin update?<\/h3><\/dt>\n<dd><p>Because the files genuinely changed. Capture a fresh baseline once you have applied your updates and confirmed the site is working.<\/p><\/dd>\n<dt id=\"should%20i%20enable%20hsts%3F\"><h3>Should I enable HSTS?<\/h3><\/dt>\n<dd><p>Only once HTTPS works everywhere on your site, including every subdomain if you include them. Browsers remember the instruction for the duration you set and will refuse plain HTTP until it expires. Start with a short duration.<\/p><\/dd>\n<dt id=\"why%20is%20my%20content%20security%20policy%20breaking%20my%20site%3F\"><h3>Why is my Content Security Policy breaking my site?<\/h3><\/dt>\n<dd><p>Because most themes and plugins rely on inline scripts. Start in report-only mode, watch your browser console, and add what you actually need before switching to enforce.<\/p><\/dd>\n<dt id=\"does%20it%20work%20with%20a%20proxy%20or%20cdn%3F\"><h3>Does it work with a proxy or CDN?<\/h3><\/dt>\n<dd><p>Yes, but you must configure it. Proxy headers can be forged by visitors, so the plugin reads the direct connection address by default and only trusts a proxy header when you opt in and name your trusted proxies.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>1.0.1<\/h4>\n\n<p>Changes made in response to the WordPress.org plugin review.<\/p>\n\n<ul>\n<li>Sign-in history no longer derives its session identifier from the WordPress\nauthentication cookie. It now uses an identifier the plugin generates itself,\nkept in its own cookie, so no authentication material is read or stored. The\nold column is dropped when you update; existing history rows are kept.<\/li>\n<li>The blocked-request page is now rendered by <code>wp_die()<\/code> instead of a page this\nplugin built by hand, which removes the inline stylesheet it used to emit.\nBlocked XML-RPC and REST requests are now refused in the format their client\nexpects rather than always receiving HTML.<\/li>\n<li>Hardening no longer defines WordPress core constants. Disabling the file\neditor and blocking plugin or theme installation are now applied by\nwithholding the relevant capabilities, and forcing HTTPS in the admin area is\napplied by a redirect. All three stay scoped to this plugin's settings and\nstop the moment a setting is switched off, instead of changing behaviour\nglobally for the rest of the request.<\/li>\n<li>The readme now documents every external service the plugin can contact \u2014\nWordPress.org core checksums, Google reCAPTCHA, and ipapi.co \u2014 with what is\nsent, when it is sent, and links to each service's terms and privacy policy.<\/li>\n<li>Corrected the contributor username in the readme.<\/li>\n<\/ul>\n\n<h4>1.0.0<\/h4>\n\n<ul>\n<li>Initial release.<\/li>\n<\/ul>","raw_excerpt":"Firewall, login protection, two-factor, file integrity monitoring, and audit logging, explained in plain language.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/355624","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=355624"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/solverwp"}],"wp:attachment":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=355624"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=355624"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=355624"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=355624"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=355624"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=355624"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}