Title: Hanu Malware Guard
Author: Hanuit Solutions
Published: <strong>September 22, 2026</strong>
Last modified: September 22, 2026

---

Search plugins

![](https://ps.w.org/hanu-malware-guard/assets/banner-772x250.png?rev=3707074)

![](https://ps.w.org/hanu-malware-guard/assets/icon.svg?rev=3707074)

# Hanu Malware Guard

 By [Hanuit Solutions](https://profiles.wordpress.org/hanuitsolutions/)

[Download](https://downloads.wordpress.org/plugin/hanu-malware-guard.1.2.8.zip)

 * [Details](https://wordpress.org/plugins/hanu-malware-guard/#description)
 * [Reviews](https://wordpress.org/plugins/hanu-malware-guard/#reviews)
 *  [Installation](https://wordpress.org/plugins/hanu-malware-guard/#installation)
 * [Development](https://wordpress.org/plugins/hanu-malware-guard/#developers)

 [Support](https://wordpress.org/support/plugin/hanu-malware-guard/)

## Description

Hanu Malware Guard is a self-contained WordPress security plugin covering eight 
areas:

 1.  **Malware Scanner** — recursively scans themes, plugins, mu-plugins and uploads
     for a curated set of regex heuristics matching common backdoor/webshell patterns(
     obfuscated eval(), webshell string signatures, command execution of user input,
     arbitrary file writes, etc). Any executable PHP-family file found inside `wp-content/
     uploads` is flagged outright, since WordPress never legitimately places runnable
     code there.
 2.  **File Integrity Monitor** — hashes every scanned file and records a baseline.
     Later scans report files that are new, modified, or deleted since the previous
     pass, so you can see exactly what changed and when.
 3.  **Cron Guard** — catches cron-based persistence. WordPress fires whatever hook
     name is stored in its `cron` option regardless of whether any currently-loaded
     code registers a handler for it. Malware commonly schedules a job under an unfamiliar
     hook name and re-adds its own callback dynamically, so the job keeps firing even
     after the plugin/theme file that “owns” it is deleted. Hanu Malware Guard snapshots
     every scheduled cron event on each page load, flags any hook with **no currently
     registered callback** (“orphan”) or a randomly-generated-looking name, and lets
     you:
 4.   * **Block** a hook: unschedules every pending event for it immediately and blacklists
        the hook name so WordPress refuses to re-schedule it in the future (via the`
        pre_schedule_event` filter).
      * **Trust** a hook: marks it as known-good so it stops appearing as a flag.
      * Cross-references file changes against flagged cron activity so you can see 
        file changes that happened right around when a suspicious cron job ran.
 5.  **Login Brute-Force Lockout** — locks out an IP/username combination after too
     many failed logins within a configurable window. Runs as an early `authenticate`
     filter, so it covers both wp-login.php and XML-RPC logins (both authenticate through
     the same core `wp_authenticate()` call). Manage active lockouts and view recent
     failed attempts on the Login Security page.
 6.  **Firewall** — blocks the handful of request patterns that account for most automated
     WordPress attacks: XML-RPC pingback amplification abuse (optional full XML-RPC
     disable), `?author=N` and REST `/wp/v2/users` username enumeration, and requests
     whose URL contains obvious SQL-injection / path-traversal / PHP-injection strings.
     Logged-in administrators are always exempt from the query-string check so normal
     site use is never at risk of self-lockout. Blocked requests are logged on the 
     Firewall page.
 7.  **Security Headers** — sends `X-Content-Type-Options`, `X-Frame-Options`, `Referrer-
     Policy`, and a `Content-Security-Policy: frame-ancestors 'self'` (clickjacking
     protection only — no script-src policy, since that reliably breaks themes/page
     builders unless hand-tuned per site).
 8.  **Core File Integrity Check** — compares `wp-admin`/`wp-includes` against the 
     official checksums WordPress.org publishes for your exact version, and additionally
     flags any PHP file physically present in those folders that isn’t part of the 
     official manifest at all (a classic place to hide a backdoor, since admins assume“
     core” never changes). Findings appear in Scan Results alongside everything else.
 9.  **Activity Log** — records logins (success/failure/lockout), new admin users and
     role escalations, plugin/theme activation and switching, core/plugin/theme updates,
     and use of the built-in file editor, so you have a timeline of what changed and
     by whom.

Additional hardening options (Settings page): block PHP execution inside `wp-content/
uploads` (.htaccess/web.config, with an Nginx snippet shown for reference), and 
disable the built-in wp-admin file editor.

#### External services

This plugin makes one outbound HTTP request, only when you run “Check Core File 
Integrity” (manually or via the daily scheduled scan): it calls the official WordPress.
org checksums API at `https://api.wordpress.org/core/checksums/1.0/?version={your
WP version}&locale={your locale}` to fetch the known-good hash list for your exact
WordPress version. No site data, file contents, or personal information is sent —
only your WordPress version number and locale, which is required for the API to 
return the right checksum set. See the WordPress.org API documentation and privacy
policy: https://wordpress.org/about/privacy/. No other external service is contacted
by this plugin.

## Screenshots

[⌊Dashboard — scan summary, quick actions, and core integrity status.⌉⌊Dashboard—
scan summary, quick actions, and core integrity status.⌉[

Dashboard — scan summary, quick actions, and core integrity status.

[⌊Scan Results — findings with severity, snippet, and quarantine/ignore/delete actions.⌉⌊
Scan Results — findings with severity, snippet, and quarantine/ignore/delete actions
.⌉[

Scan Results — findings with severity, snippet, and quarantine/ignore/delete actions.

[⌊Cron Monitor — flagged cron hooks with block/trust actions.⌉⌊Cron Monitor — flagged
cron hooks with block/trust actions.⌉[

Cron Monitor — flagged cron hooks with block/trust actions.

[⌊Login Security — active lockouts and recent failed attempts.⌉⌊Login Security —
active lockouts and recent failed attempts.⌉[

Login Security — active lockouts and recent failed attempts.

## Installation

 1. Upload the `hanu-malware-guard` folder to `/wp-content/plugins/`, or install directly
    from the WordPress Plugin Directory.
 2. Activate the plugin through the ‘Plugins’ menu in WordPress.
 3. Go to Malware Guard  Dashboard and run your first scan.
 4. Review Malware Guard  Cron Monitor for any orphaned/suspicious jobs.
 5. Review Malware Guard  Settings to tune login lockout thresholds, firewall toggles
    and security headers for your site.

## FAQ

### Will this definitely find every piece of malware on my site?

No security scanner can guarantee that, and you should be skeptical of any that 
claims to. The signature scanner and core-integrity checker produce heuristic matches
for you to review — they are a strong starting point, not a certified clean bill
of health. Always keep offline backups regardless.

### I got a “critical” finding but I’m sure the file is legitimate — what now?

Inspect the snippet shown in Scan Results. Several signatures (obfuscated `eval()`,`
create_function()`, long base64 blobs) can legitimately appear in caching layers,
minified vendor code, or some page builders. If you’re confident it’s a false positive,
click “Ignore” rather than deleting the file. Auto-quarantine of critical findings
is off by default for exactly this reason.

### Can it stop a malicious cron job from ever writing a file?

Not in real time — no WordPress plugin can intercept a file write at the PHP-engine
level; that requires a hosting-level security layer. What it does is control cron
_scheduling_ (block a hook so WordPress refuses to re-run it) and _detect_ file 
changes that happened around the same time as a suspicious cron run, so you can 
act quickly.

### Does the login lockout affect XML-RPC too?

Yes. XML-RPC authentication goes through the same core `wp_authenticate()` function
as the normal login form, so the same failed-attempt counter and lockout apply to
both.

### Will the firewall lock me out of my own site?

The query-string pattern check always exempts logged-in administrators, specifically
so normal plugin/editor use can never trigger a self-lockout. Only unauthenticated
requests are checked against the SQLi/path-traversal/PHP-injection patterns.

### Does this send any of my data to a third party?

No. The only outbound request the plugin makes is to WordPress.org’s own official
checksums API, and only your WordPress version + locale are sent (see “External 
services” above). Everything else — scanning, hashing, cron auditing, login tracking—
runs entirely on your own server.

### What happens to quarantined files if I uninstall the plugin?

Nothing is left on disk. Quarantining a file reads its content into the database(
base64-encoded, in the plugin’s own scan_results table) and deletes the original—
the file is gone from the filesystem the moment it’s quarantined, not just hidden
behind a protected folder. Uninstalling the plugin removes that table along with
everything else, so if you want to keep a quarantined file’s content for forensics,
restore or export it before uninstalling.

### Where can I get support?

Use the plugin’s support forum on WordPress.org, or email herry@hanuitsolutions.
com.

## Reviews

There are no reviews for this plugin.

## Contributors & Developers

“Hanu Malware Guard” is open source software. The following people have contributed
to this plugin.

Contributors

 *   [ Hanuit Solutions ](https://profiles.wordpress.org/hanuitsolutions/)

[Translate “Hanu Malware Guard” into your language.](https://translate.wordpress.org/projects/wp-plugins/hanu-malware-guard)

### Interested in development?

[Browse the code](https://plugins.trac.wordpress.org/browser/hanu-malware-guard/),
check out the [SVN repository](https://plugins.svn.wordpress.org/hanu-malware-guard/),
or subscribe to the [development log](https://plugins.trac.wordpress.org/log/hanu-malware-guard/)
by [RSS](https://plugins.trac.wordpress.org/log/hanu-malware-guard/?limit=100&mode=stop_on_copy&format=rss).

## Changelog

#### 1.2.8

 * Fixed: the file-editor activity-log hook read $_POST[‘file’]/$_POST[‘theme’] 
   and used them to build a nonce-action string before sanitizing — even though 
   the only sink is wp_verify_nonce() (a hash comparison, not an executable/output
   context), the fix follows “sanitize early” literally: both values now go through
   sanitize_text_field() immediately, before any use. This is a no-op for every 
   legitimate request, since real file paths and theme slugs never contain the characters
   it strips.
 * Hardened several other raw $_GET/$_SERVER reads in the firewall (author-enumeration
   check, REST user-enumeration check, malicious-pattern scanner) with explicit 
   per-line justification for why they’re intentionally inspected unsanitized — 
   each is used only for validation (is_numeric()), substring comparison, or pattern-
   matching against attack signatures, never stored or output without separate escaping.

#### 1.2.7

 * Fixed: WordPress.DB.PreparedSQLPlaceholders.LikeWildcardsInQuery — a LIKE clause
   value was baked directly into the query string instead of passed through a placeholder.
   The schema-migration column check now passes its LIKE value via %s, and uninstall.
   php’s options cleanup now runs the pattern through $wpdb->esc_like() (it contains
   a real % wildcard) before passing it as %s, rather than hardcoding the pattern
   in the SQL.

#### 1.2.6

 * Fixed: dozens of static-analysis findings from the official Plugin Check tool(
   WordPress.DB.PreparedSQL.InterpolatedNotPrepared / PluginCheck.Security.DirectDB.
   UnescapedDBParameter) where a table name was interpolated into a SQL string across
   several files. All custom-table queries now pass the table name through $wpdb-
   >prepare()’s %i identifier placeholder instead — this also closes a few cases
   where an existing `phpcs:ignore` comment sat on the wrong physical line of a 
   multi-line prepare() call and so wasn’t actually suppressing anything. %i requires
   WordPress 6.2+, so the minimum supported version is now 6.2 (previously 6.0).
 * Fixed: the legacy quarantine-folder cleanup used raw unlink()/rmdir() instead
   of the WP_Filesystem API (Plugin Check ERROR-level finding); it now goes through
   WP_Filesystem, and silently skips cleanup if direct filesystem access isn’t available
   rather than failing.
 * Fixed: two remaining input-handling findings — added the missing sniff code to
   an existing justified `phpcs:ignore` on the file-editor’s $_POST[‘file’] read,
   and added a missing `phpcs:ignore` (with rationale) to the read-only $_GET check
   behind the settings-saved admin notice.

#### 1.2.5

 * Fixed: quarantine no longer writes anything to the filesystem. Previously a quarantined
   file was moved into a protected subfolder under wp-content/uploads — the plugin
   directory guidelines don’t allow storing potentially-executable code there at
   all, even in a plugin-specific, .htaccess-protected folder, since that protection
   isn’t guaranteed to be honored (Nginx ignores .htaccess entirely; offloaded/CDN-
   backed uploads bypass it too). Quarantine now reads the file’s bytes into the
   database (base64-encoded) and deletes the original from disk; restoring writes
   it back from the database. Sites upgrading from an earlier version automatically
   migrate any already-quarantined files into the database and remove the legacy
   on-disk folder on first load after updating.

#### 1.2.4

 * Fixed: the activity-log entry for built-in theme/plugin file-editor usage was
   written before verifying the nonce, so a CSRF-forged request from a user with
   edit_themes/edit_plugins capability could produce a false log entry even though
   core’s own handler would go on to reject the edit. It now verifies the same nonce
   core checks (edit-plugin_{file} / edit-theme_{file}{stylesheet}) before writing
   anything, and simply skips logging on failure without interfering with core’s
   own request handling.

#### 1.2.3

 * Fixed: the Quarantine action could move a file out of wp-admin/wp-includes for
   core-integrity findings, which counts as modifying a WordPress core directory.
   Findings inside core directories can now only be reviewed or ignored from Scan
   Results; the UI explains that core files must be restored via Dashboard  Updates
   Re-install Now, or replaced manually.
 * Fixed: the activity-log entry for built-in theme/plugin file-editor usage could
   previously be triggered by any logged-in user, since it hooked core’s ajax action
   at a priority that ran before core’s own nonce/capability check. It’s now gated
   by its own capability check (edit_themes/edit_plugins) before logging anything.

#### 1.2.2

 * Fixed: is_writable() replaced with wp_is_writable() (Windows-safe core wrapper).
 * Fixed: shortened the readme short description to meet the 150-character limit.
 * Fixed: every admin view file now defines its own prefixed render function instead
   of running top-level template code, so its local variables are function-scoped
   rather than looking like unprefixed globals to static analysis.
 * Fixed: corrected the placement of several phpcs:ignore suppressions that were
   on the wrong line to take effect, and added missing ones for direct-query/no-
   caching/unescaped-parameter findings against this plugin’s own custom tables (
   table names always come from the internal WPMG_DB::table() helper, never user
   input).
 * Fixed: clarified/suppressed the DISALLOW_FILE_EDIT prefix warning (it’s a WordPress
   core-mandated constant name) and the REMOTE_ADDR sanitization warning (already
   validated via filter_var() immediately after).
 * No functional changes — this release addresses static-analysis findings only.

#### 1.2.1

 * Renamed the main bootstrap class from the unprefixed WP_Malware_Guard to WPMG_Plugin,
   per WordPress.org’s naming-collision guidelines.
 * Replaced hardcoded wp-content-relative paths with proper WordPress location APIs:
   WP_PLUGIN_DIR / WPMU_PLUGIN_DIR for plugins/mu-plugins, and theme-root enumeration
   via wp_get_themes() (so themes registered outside wp-content/themes are scanned
   too), and fixed the Nginx snippet to derive its path from wp_upload_dir()[‘baseurl’]
   instead of ABSPATH.
 * Moved quarantine storage out of wp-content/wpmg-quarantine into wp-content/uploads/
   hanu-malware-guard/quarantine, resolved via wp_upload_dir() at runtime (multisite-
   safe), per the plugin directory’s file-storage-location requirements.

#### 1.2.0

 * Renamed from “WP Malware Guard” to “Hanu Malware Guard” (and slug from wp-malware-
   guard to hanu-malware-guard) to comply with the WordPress.org restriction on 
   plugin names/slugs starting with “wp”.
 * Added bulk actions for incident response: “Quarantine All Critical Findings” 
   on Scan Results and “Block All Suspicious Cron Jobs” on Cron Monitor, so a large-
   scale infection doesn’t require clicking every row individually.

#### 1.1.0

 * Added login brute-force lockout (covers wp-login.php and XML-RPC).
 * Added a lightweight firewall: XML-RPC pingback lockdown, username-enumeration
   blocking, malicious query-string blocking.
 * Added baseline security response headers.
 * Added WordPress core file integrity checking against the official WordPress.org
   checksums, plus detection of unexpected PHP files in wp-admin/wp-includes.
 * Added a site-wide activity/audit log (logins, admin user/role changes, plugin/
   theme changes, file editor use, firewall blocks).
 * Fixed the scanner and quarantine system flagging/moving the plugin’s own files(
   its signature list legitimately contains strings like “eval” and “FilesMan” as
   plain text).

#### 1.0.0

 * Initial release: scanner, file integrity monitor, cron guard, upload hardening.

## Meta

 *  Version **1.2.8**
 *  Last updated **1 day ago**
 *  Active installations **Fewer than 10**
 *  WordPress version ** 6.2 or higher **
 *  Tested up to **7.1.2**
 *  PHP version ** 7.4 or higher **
 * Tags
 * [backdoor](https://wordpress.org/plugins/tags/backdoor/)[firewall](https://wordpress.org/plugins/tags/firewall/)
   [login security](https://wordpress.org/plugins/tags/login-security/)[malware scanner](https://wordpress.org/plugins/tags/malware-scanner/)
   [security](https://wordpress.org/plugins/tags/security/)
 *  [Advanced View](https://wordpress.org/plugins/hanu-malware-guard/advanced/)

## Ratings

No reviews have been submitted yet.

[Your review](https://wordpress.org/support/plugin/hanu-malware-guard/reviews/#new-post)

[See all reviews](https://wordpress.org/support/plugin/hanu-malware-guard/reviews/)

## Contributors

 *   [ Hanuit Solutions ](https://profiles.wordpress.org/hanuitsolutions/)

## Support

Got something to say? Need help?

 [View support forum](https://wordpress.org/support/plugin/hanu-malware-guard/)