=== Hard Guard Security ===
Contributors: buzbuz
Donate link: https://www.paypal.com/donate?hosted_button_id=PWTVTARRF9Q2A
Tags: security, malware scanner, vulnerability scanner, login security, two-factor authentication
Requires at least: 7.0
Tested up to: 7.0
Requires PHP: 7.4
Stable tag: 1.16.1
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Login protection, 2FA, audit logs, local malware scanning, local vulnerability monitoring, antispam, SSL diagnostics, and WordPress hardening.

== Description ==

Hard Guard Security is a free, open-source security plugin combining login protection, activity monitoring, local file analysis, antispam, SSL diagnostics, and hardening controls.

The plugin does not lock features behind payment, require a license key, or send telemetry, scan results, or website files to its author. A voluntary PayPal donation link appears only on Hard Guard Security screens and in the plugin row.

Main features:

* Progressive login lockouts by IP address, username, or both.
* IPv4 and IPv6 whitelist, blacklist, CIDR, and hardened trusted-proxy client-IP resolution with explicit header selection.
* Optional custom login URL with safety checks, rollback, and emergency recovery.
* Email-code and RFC 6238 TOTP two-factor authentication.
* Per-user methods, role policies, setup grace periods, recovery codes, and administrator reset.
* Application Password policies, inventory, revocation, inactivity cleanup, and security alerts.
* Searchable Audit Log with severity, category, action, result, retention, alert rules, CSV/JSON export, redaction, and Multisite aggregation.
* Quick and Full malware scans performed locally with scan history, SHA-256 ignore rules, quarantine, and restoration.
* Optional read-only Database Malware Scanner for manual Quick/Full scans with separate SQL findings and context-aware behavioural heuristics.
* Full and Automatic scans include a separate Vulnerabilities & updates stage for WordPress Core, plugins, and themes.
* Known-vulnerability matching is performed locally against a signed Hard Guard threat-intelligence database; plugin/theme inventory and scan results are not sent to Hard Guard.
* Outdated components are identified separately from known vulnerabilities using WordPress' existing local update cache, without Hard Guard forcing an additional inventory request.
* WordPress Core integrity checks using official WordPress.org checksums.
* File-permission diagnostics and checks for unexpected executable files.
* Local antispam for native comments, WooCommerce reviews using the comment system, and native registration.
* Optional country allow/block rules using country.is, with IP/CIDR recovery exceptions and fail-open handling.
* SSL certificate, HTTPS redirect, mixed-content, and live security-header diagnostics.
* HSTS, upgrade-insecure-requests, MIME-sniffing, Referrer-Policy, frame protection, Permissions-Policy, and X-Powered-By controls.
* XML-RPC, REST user listing, author enumeration, user sitemap, directory indexing, sensitive-file, uploads PHP, and file-editor hardening.
* Daily Server Rules Integrity + Auto-Heal for Hard Guard-managed .htaccess blocks, with safety-check rollback.
* Upload Directory Shield adds a second managed .htaccess layer directly in WordPress uploads on Apache/LiteSpeed.
* Suspicious .htaccess detection identifies dangerous PHP/CGI execution directives during daily checks and manual malware scans.
* Dedicated SMTP settings used only for Hard Guard Security messages.
* Settings export/import and optional complete data cleanup during uninstall.
* Personal-data exporter and eraser integration under WordPress Tools.
* The administration interface follows each user’s WordPress dashboard language. Translations are supplied through WordPress.org language packs when available and are not bundled in the plugin ZIP.

Important: Hard Guard Security reduces selected risks but cannot guarantee that a website is secure or malware-free. Keep verified backups, install updates, use secure hosting, and test high-risk changes on a staging site.

== Installation ==

1. Upload the `hard-guard-security` directory to `/wp-content/plugins/`, or install the ZIP from Plugins > Add New > Upload Plugin.
2. Activate Hard Guard Security. On Multisite it may be activated per site or network-wide.
3. Open Hard Guard Security > Settings and review login protection, trusted proxies, notifications, GeoIP, and mail delivery.
4. Configure your own method under Hard Guard Security > 2FA and save recovery codes outside WordPress.
5. Run File Integrity, File Permissions, and Quick Scan before changing or quarantining files.
6. Test custom login URLs, redirects, server rules, country policies, and email delivery before relying on them.
7. Create a complete backup before enabling high-risk hardening options.

== External services ==

Hard Guard Security operates primarily on the local site. The following connections occur only when the related feature is enabled or manually run.

= country.is IP-to-country API =

When GeoIP or Antispam country rules require a lookup, the visitor IP is sent to `https://api.country.is/{ip}`. Country results are cached for 24 hours, failures for 10 minutes, and unknown countries fail open.

Service: https://country.is/
Terms of use / usage conditions and rate limits: https://country.is/
Privacy / request logging information: https://country.is/
Source and self-hosting information: https://github.com/lineofflight/country

= Cloudflare Turnstile =

Turnstile is optional and disabled by default. When enabled, the browser loads JavaScript from Cloudflare and the plugin sends the challenge token, client IP address, configured secret, and verification metadata to Cloudflare Siteverify.

Service documentation: https://developers.cloudflare.com/turnstile/
Privacy addendum: https://www.cloudflare.com/turnstile-privacy-policy/
Cloudflare privacy policy: https://www.cloudflare.com/privacypolicy/

= WordPress.org checksum services =

When an administrator runs the WordPress Core integrity check, the plugin requests official checksum data for the installed WordPress version and locale. Website file contents are not sent to WordPress.org.

WordPress.org privacy policy: https://wordpress.org/about/privacy/
Core checksum reference: https://developer.wordpress.org/reference/functions/get_core_checksums/


= Hard Guard vulnerability intelligence database =

Vulnerability Monitoring can use a signed compressed database downloaded from the Hard Guard website. Automatic database downloads are disabled by default and start only after an administrator explicitly enables automatic updates; an administrator can also request a one-time manual refresh. The request uses a neutral `Hard-Guard-Security/<version>` User-Agent and does not include the website URL, installed plugin/theme inventory, installed versions, scan results, file paths, or file contents. Matching against installed software is performed locally. The server hosting the feed can still receive normal connection metadata such as the requesting IP address and request time.

Default feed: https://cve.wp-hard-guard.ma7.eu/vulnerabilities-v1.json.gz
Detached signature: https://cve.wp-hard-guard.ma7.eu/vulnerabilities-v1.sig.txt

Data sent and when: only a normal HTTPS GET is made when automatic database updates run or an administrator requests a manual refresh. No site URL, software inventory, installed versions, scan results, file paths, or file contents are added to the request. As with ordinary web hosting, the feed server can receive connection metadata such as the requesting IP address, request time, requested URL, HTTP headers, and the Hard-Guard-Security User-Agent. The downloaded database is public security data and matching is performed locally.

Service endpoint: https://cve.wp-hard-guard.ma7.eu/vulnerabilities-v1.json.gz
Service privacy information: https://github.com/endriu7777/WP-Hard-Guard#privacy-conscious-operation
Service implementation/source project: https://github.com/endriu7777/WP-Hard-Guard

The Hard Guard database is built from public vulnerability sources and retains source attribution. The 1.13.0 feed format supports CVE Program / CVE List V5, optional NIST NVD enrichment, GitHub Advisory Database (CC BY 4.0), and CISA Known Exploited Vulnerabilities (CC0). Ambiguous WordPress component mappings should be reviewed before publication rather than guessed. The ZIP does not bundle a vulnerability database. Known-vulnerability coverage becomes active after an administrator enables automatic database updates or requests a manual refresh and a valid signed production feed is downloaded. Hard Guard clearly warns when production coverage is unavailable and never treats a missing database as a clean result.

= PayPal donations =

After an administrator clicks Donate, the browser submits the hosted-button identifier to PayPal in a new tab. No PayPal scripts, images, or tracking pixels load before the click. PayPal processes the visit and payment under its own terms.

PayPal privacy statement: https://www.paypal.com/privacy
PayPal user agreement: https://www.paypal.com/legalhub/paypal/useragreement-full

= Administrator-configured SMTP server =

When custom SMTP is enabled, Hard Guard Security connects to the configured server to deliver alerts and email 2FA codes. The provider receives message content and delivery metadata under its own terms.

= The administrator's own website =

SSL certificate checks, live security-header scans, mixed-content front-end scans, redirect tests, and server-rule safety checks make HTTP or TLS requests only to the current website configured in WordPress. These requests are initiated by an administrator or by a safety check connected to a setting change.

== Privacy ==

Hard Guard Security stores security data locally. Depending on enabled modules, this can include IP addresses, usernames, login results, event times, administrative actions, request paths without query strings, antispam incident details, file paths, checksums, database table/record identifiers, matched scanner rules, and short escaped excerpts. Database content is inspected only when an administrator explicitly enables Database Malware Scanner for a manual scan and is not uploaded to Hard Guard.

Known password, token, nonce, cookie, authorization, and API-key fields are redacted before Audit Log storage. Plaintext Application Passwords and their hashes are not written to Hard Guard Security logs. TOTP secrets and SMTP passwords are encrypted when Sodium or OpenSSL is available; recovery codes are stored as one-way hashes.

Retention controls are available for Audit Log, Antispam, scanner history, and other records. WordPress privacy-policy suggestions are added under Settings > Privacy. Personal-data export and erasure callbacks are registered under Tools > Export Personal Data and Tools > Erase Personal Data. Erasure removes user-specific plugin metadata and matching antispam and lockout records, while matching Audit Log events are anonymized so non-personal security metadata can be retained.

Quarantined files remain on the server until restored, manually deleted, or removed during uninstall when complete cleanup is enabled. Scanner file contents and Database Malware Scanner content are not uploaded to an external malware-scanning service. Vulnerability matching also remains local: Hard Guard downloads a signed public database but does not upload installed plugin/theme inventory, versions, scan results, file names, or file contents.

== Frequently Asked Questions ==

= How is the Hard Guard Security interface language selected? =

Hard Guard Security follows the language selected by WordPress for the current user. The plugin does not include compiled translation files in its ZIP. When a translation is available for the plugin on WordPress.org and the corresponding WordPress language is installed, WordPress loads the language pack automatically. Global security emails use the site language, while user-specific 2FA messages use the recipient's WordPress language.

= Is Hard Guard Security completely free? =

Yes. All included features are available without payment, a license key, a trial period, or a quota. Donations are voluntary and do not unlock functionality.

= Does the plugin send telemetry to its author? =

No. It does not send telemetry, usage statistics, settings, scan results, or personal data to the plugin author.


= How does Vulnerability Monitoring protect privacy? =

Full and Automatic scans compare locally installed WordPress Core, plugin, and theme versions against a signed threat-intelligence database downloaded by Hard Guard. The same signed feed can include a complete WordPress.org version index, so outdated checks are performed locally without sending the site's installed inventory. For components not covered by that index, Hard Guard may use WordPress' existing local update cache; it does not force a new inventory request during the scan.

= Is an outdated plugin automatically vulnerable? =

No. Hard Guard reports `Outdated` separately from `Vulnerable`. Outdated means WordPress already knows a newer version is available; Vulnerable means the installed version matches a known affected range in the current Hard Guard threat-intelligence database.

= How does Database Malware Scanner work? =

Database Malware Scanner is an optional checkbox for manual scans and is read-only. Quick Scan inspects `wp_options`; Full Scan additionally inspects `wp_posts.post_content` and `wp_postmeta.meta_value` in bounded batches. It combines high-signal behavioural rules with storage context, safe decoding of explicitly encoded payloads, and conservative handling of ordinary content/code examples. Database findings are displayed separately from file findings. It does not modify SQL records.

= Does the malware scanner delete files automatically? =

No. It reports findings for administrator review. Quarantine and restoration require an authorized administrator action and password confirmation.

= Can the scanner guarantee that a site is clean? =

No. It is a diagnostic tool based on selected patterns, structures, checksums, and heuristics. A professional investigation may still be required.

= How do I disable a feature after losing access? =

Use the documented recovery constants in `wp-config.php`, including `WPGUARD_DISABLE_LOGIN_HIDING`, `WPGUARD_DISABLE_2FA`, `WPGUARD_DISABLE_GEOIP`, and `WPGUARD_DISABLE_SSL_REDIRECT`. Keep a backup and an independent server-access method.

= Does GeoIP block visitors if country.is is unavailable? =

No. Unknown countries fail open. Add a trusted recovery IP or CIDR before enabling a country policy.

= Does uninstall remove all data? =

Only when "Delete all Hard Guard Security data during uninstall" is enabled. Managed server rules and scheduled tasks are removed operationally even when database data is retained.

= Can I hide or replace the donation URL? =

Yes. Define `WPGUARD_DONATE_URL`, use the `wpguard_donate_url` filter, or return an empty string to hide donation links.

== Changelog ==

= 1.16.1 =
- Reworked filesystem location resolution to use WordPress path APIs and plugin-file-derived paths instead of operational ABSPATH and WordPress filesystem plugin-directory helpers.
- Improved support for non-standard WordPress core, content, plugins, themes, uploads, and home-directory layouts, including safer .htaccess location handling.
- Reworked direct database queries to use prepared wpdb statements, including %i placeholders for table and column identifiers and placeholders for all dynamic values.
- Added safe failure handling when required WordPress paths or .htaccess marker helpers cannot be resolved.

= 1.16.0 =

* Added optional read-only Database Malware Scanner to manual Quick and Full scans.
* Added separate Database findings results, severity counts, scan-history counts, and JSON report output.
* Added context-aware behavioural detection and safe explicit-payload decoding without requiring a remote database-malware signature feed.
* Quick database scans inspect `wp_options`; Full database scans additionally inspect `wp_posts.post_content` and `wp_postmeta.meta_value` in bounded batches.

= 1.15.1 =

* Added a persistent current-results snapshot for the automatic Suspicious .htaccess Scanner.
* Added an expandable findings table under System Tweaks → Server Rules Protection showing severity, file path, line number, detected rule, and the matched/redacted directive.
* Kept Audit Log as the historical event record while the System Tweaks table reflects only the most recently completed automatic scan.
* Added upgrade-safe messaging for 1.15.0 scan summaries that did not yet store file-level finding details.

= 1.15.0 =

* Added Server Rules Integrity + Auto-Heal, Upload Directory Shield, and the daily Suspicious .htaccess Scanner.
* Integrated suspicious .htaccess analysis into manual Quick and Full malware scans when enabled.

= 1.14.4 =

* Removed the plugin-only interface language selector so the administration interface follows the locale selected by WordPress for each user.
* Removed the separate Email language setting. Global security emails use the WordPress site language, while user-specific 2FA messages use the recipient’s WordPress language.
* Replaced custom text-domain gettext overrides with WordPress native just-in-time language-pack loading and locale switching.
* Kept compatibility handling for language-dependent event and scan text stored by older plugin versions without bundling translation catalogs.

= 1.14.3 =

* Removed all bundled compiled translation catalogs; runtime translations now come from WordPress.org language packs.
* Removed direct uses of WordPress internal plugin/content directory constants and switched directory resolution to WordPress APIs.
* Updated plugin-name lookup to use WordPress plugin metadata instead of constructing plugin file paths manually.
* Clarified the Hard Guard vulnerability intelligence external-service disclosure, including a direct service URL and privacy-information link.
* Changed automatic Hard Guard vulnerability-feed downloads to opt-in for new installations; the default is now disabled until an administrator enables them.
* Corrected the WordPress.org checksum disclosure to describe the Core checksum request actually performed by this release.

= 1.14.2 =

* Fixed the per-user interface language selector regression introduced in 1.14.0.
* Restored the bundled `.l10n.php` runtime catalogs required when the selected Hard Guard Security language differs from the WordPress dashboard locale.
* Installed WordPress.org language-pack messages take precedence over bundled messages while the bundled catalog remains a fallback.

= 1.14.0 =

* Prepared the package for WordPress.org review: removed bundled compiled translation catalogs and the obsolete `load_plugin_textdomain()` call.
* Updated country.is documentation to the current source repository and clarified service usage/privacy information.
* Removed the global PHP `ini_set()` error-display override; System Tweaks now reports those values diagnostically only.
* Replaced the plugin-managed front-end `ob_start()` callback with WordPress' managed template enhancement output buffer.
* Replaced hardcoded `wp-includes` path segments with the native `WPINC` constant where applicable.
* Switched the emergency login redirect to WordPress `site_url()` handling so subdirectory installations resolve the core login endpoint correctly.
* Expanded external-service disclosure for the signed Hard Guard vulnerability intelligence feed.

= 1.13.1 =

* Added a privacy-preserving signed version index to the threat-intelligence feed so outdated WordPress.org plugins, themes and Core can be detected locally without transmitting installed inventory.
* Kept the feed schema backward-compatible: older 1.13.0 clients accept the extended signed feed and ignore the optional version index.
* Vulnerable components can now also be reported as Outdated instead of suppressing the update finding.
* Added version-index status and a clear warning when a production feed has not yet been rebuilt with version records.

= 1.13.0 =

* Added local Vulnerability Monitoring for WordPress Core, plugins, and themes as a separate Full/Automatic Scan stage.
* Added separate Vulnerable and Outdated result categories so available updates are never mislabeled as known security vulnerabilities.
* Added optional signed Hard Guard vulnerability-database updates every 12 hours, immutable hash-addressed local cache files, anti-rollback checks, and fail-safe retention of the previous verified database.
* Feed downloads use a neutral Hard-Guard-Security User-Agent and do not send the site URL, plugin/theme inventory, installed versions, file names, or scan results.
* Added Critical/High/Medium/Low vulnerability counts, CVE/HGSA identifiers, CVSS, fixed version, active/inactive status, and known-exploited flags.
* Added new/changed vulnerability state tracking so email alerts are not repeated unchanged on every automatic scan.
* Added local Outdated detection using WordPress' existing update transients without initiating an additional update request.
* Added a manual signed-database refresh control, automatic-update toggle, database generation/advisory status, stale/bootstrap warnings, and per-scan threat-database snapshot metadata.
* Added a server-side feed-builder package for CVE List V5, GitHub Advisory Database, CISA KEV, reviewed WordPress mappings, and optional NVD enrichment.

= 1.12.0 =

* Added Scanner mode selection: MANUAL or AUTOMATIC.
* Automatic mode runs a Full Scan every configurable 1–365 days; the default interval is 7 days.
* Automatic scans run in bounded WP-Cron batches and continue through single scheduled step events instead of requiring one long PHP request.
* Added a database advisory lock around the automatic runner to prevent overlapping cron workers from processing the same scan concurrently.
* Added next automatic scan status and a warning when built-in WP-Cron spawning is disabled.
* Manual Quick Scan and Full Scan remain available while Automatic mode is enabled.
* Scan results and history now identify whether each run was Manual or Automatic.
* Switching back to Manual mode cancels pending automatic scan jobs and safely stops a running automatic scan.

= 1.11.0 =

* Added explicit hardened client-IP sources: REMOTE_ADDR, X-Forwarded-For, X-Real-IP, CF-Connecting-IP, and RFC 7239 Forwarded.
* X-Forwarded-For and Forwarded chains are now evaluated from the trusted server side toward the visitor, stopping at the first untrusted hop.
* Malformed, oversized, incomplete, or excessively long forwarded chains fail safely to REMOTE_ADDR.
* Added Proxy diagnostics showing the direct peer, trusted-proxy state, selected source, received headers, resolved visitor IP, and fallback reason.
* New installations default to REMOTE_ADDR only; upgraded sites with existing trusted proxies retain pre-1.11 behavior in a clearly marked Legacy automatic mode until an explicit source is selected.
* Added Polish translations for the new proxy hardening and diagnostics interface.

= 1.10.36 =

* Added dedicated Audit Log → Logins & IP blocks statistics for 24 hours, 7 days, and 30 days.
* Added failed-login and lockout trend chart, suspicious IP ranking, and current active IP lockout table.
* Updated Dashboard security KPIs with unique blocked IPs and current active lockouts; statistics are now linked to detailed Audit Log views.
* Changed Audit Log Overview IP ranking to count only suspicious authentication and blocking activity.
* Added Polish translations for the new login-security statistics interface.

= 1.10.35 =

* Prepared the free WordPress.org edition.
* Added a voluntary PayPal donation panel limited to Hard Guard Security screens and a Donate link in the plugin row.
* Added WordPress personal-data exporter and eraser integration.
* Added Plugin URI and Author URI and shortened the plugin header description.
* Removed the network-only header so the plugin can be activated per site or network-wide.
* Expanded external-service and privacy disclosures.
* Split the long historical changelog into `changelog.txt` and reduced `readme.txt` size.
* Updated bundled translation catalogs for the new donation interface.

For earlier releases, see `changelog.txt` included with the plugin.

Threat-intelligence signing: the detached Ed25519 signature covers the canonical JSON payload. Gzip is transport/storage compression only, so transparent HTTP decompression does not affect signature verification.
