February 19, 2026

WordPress Hacked? My Incident Response Checklist (From Triage to Cleanup)

Practical incident response checklist: containment, evidence, triage, cleanup, recovery, hardening, and monitoring.

WordPress Security Incident Response Malware Cleanup

When a WordPress site is hacked, the first mistake is usually panic-driven cleanup. People start deleting plugins, restoring random backups, or running malware scanners before they even know what happened. That destroys evidence and often leaves persistence in place.

This checklist is the workflow I use in production incidents. It is designed for speed, evidence preservation, and durable recovery.

First 15 Minutes: Containment Without Breaking Evidence

Containment means reducing attacker freedom immediately, while preserving enough state to investigate.

Immediate actions

  • Put the site in maintenance mode, or restrict public access at the edge (Cloudflare WAF rule, temporary auth gate, or origin allowlist).
  • Block risky entry points that are not required right now (/wp-login.php, /xmlrpc.php, suspicious wp-json routes).
  • Disable outbound email if spam is being sent from the site.
  • Freeze deployments. No plugin updates, no theme edits, no cache purges unless required for containment.
  • Create an incident channel and assign one decision maker.

What not to do in this phase

  • Do not run blanket delete scripts.
  • Do not "optimize" logs.
  • Do not rotate everything at once before taking snapshots.
  • Do not trust "clean" status from one scanner.

Containment target: stop active abuse and preserve the scene.

Preserve Evidence Before Cleanup

If you skip this, you will not know root cause, and reinfection becomes likely.

Evidence checklist

  • Full filesystem snapshot (including hidden files and all WordPress directories).
  • Database dump.
  • Access logs and error logs from web server.
  • PHP-FPM logs.
  • WAF/CDN logs (Cloudflare Firewall Events, managed rule triggers, bot actions).
  • WordPress application logs (if available).
  • List of recently modified files with timestamps.
  • Copy of cron entries and server-level scheduled jobs.
  • List of users and role assignments from WordPress and hosting panel.

Snapshot strategy

Use immutable copies where possible:

  • tar archive for filesystem.
  • SQL dump with transaction-consistent export.
  • Export logs to external storage.
  • Record server time, timezone, and hostname in case you need timeline reconstruction later.

Keep a short chain-of-custody note: who captured what, when, and where it is stored.

Triage: Confirm the Blast Radius

Before removing anything, answer three questions:

  1. Is the compromise only in WordPress, or at server level too?
  2. Is there data exposure, or just code tampering/defacement/spam?
  3. Is persistence still active?

High-signal indicators

  • New admin users with odd email domains.
  • Recently edited PHP in upload directories.
  • Unknown mu-plugins or drop-ins.
  • Unexpected cron events that execute remote fetches.
  • .htaccess rewrites to suspicious scripts.
  • wp-config.php modifications, especially includes to external files.
  • Outbound calls to suspicious domains from the same host.

Validate scope quickly

  • Compare core WordPress files with known checksums.
  • Diff plugin/theme code against trusted source versions.
  • Inspect only recently changed files first, then widen.
  • Check sibling sites on the same server for similar artifacts.

If multiple sites are affected, treat it as infrastructure compromise, not just app compromise.

Identify Infection Vectors

WordPress incidents usually come through a few repeat paths. Walk these in order.

1. Plugins and themes

  • Look for abandoned or nulled plugins.
  • Compare installed versions against vendor advisories.
  • Search for obfuscated code (base64_decode, gzinflate, dynamic function creation, variable variables).
  • Check custom theme functions.php, footer/header includes, and recently added helper files.

2. Admin users and auth surface

  • Audit all administrator accounts.
  • Identify impossible-travel logins, unusual user agents, and logins outside business windows.
  • Check whether 2FA is missing or bypassed.

3. wp-config.php

  • Verify salts, DB credentials, and any require/include additions.
  • Look for hidden payload loaders or file-based key fetch logic.
  • Check write permissions and ownership.

4. mu-plugins and drop-ins

  • Attackers like persistence here because many teams forget these directories.
  • Inspect wp-content/mu-plugins/ and drop-ins (db.php, object-cache.php, etc.) for unauthorized code.

5. Cron and scheduled execution

  • Review WordPress cron entries and server crontab.
  • Flag jobs that fetch remote payloads or execute encoded blobs.

6. .htaccess and web server config

  • Look for conditional redirects, hidden rewrites, or file upload execution allowances.
  • Confirm PHP execution policy in upload/cache directories.

7. Database-level implants

  • Search options/posts tables for injected JavaScript, iframes, hidden admin payloads, and base64 blobs.
  • Inspect autoloaded options for suspicious entries.

Remove Malicious Code Safely

Cleanup is not "delete suspicious lines and pray." It is controlled replacement.

Safe cleanup sequence

  1. Build a clean workspace from trusted package sources.
  2. Replace WordPress core with verified files.
  3. Replace each plugin/theme with known-good versions.
  4. Remove unknown files and directories not in inventory.
  5. Clean database injections with explicit queries and backups.
  6. Re-scan and re-diff after each major step.

Rules during cleanup

  • Never edit files directly on production if you can avoid it.
  • Keep one untouched evidence snapshot before every destructive action.
  • Document each removed artifact and why it was removed.
  • Do not "temporarily" leave suspicious code because a feature depends on it.

Common persistence traps

  • Backdoor hidden in an image upload with .php extension tricks.
  • Reinfecting plugin auto-installer scripts.
  • Database option that rewrites payload after cache clear.
  • Compromised deploy key that reintroduces malware on next push.

Recovery Steps: Rotate Secrets and Rebuild Trust

After cleanup, assume credentials are compromised unless proven otherwise.

Mandatory rotations

  • All WordPress user passwords (especially admins/editors).
  • WordPress salts/keys in wp-config.php.
  • Database credentials.
  • SFTP/SSH credentials and deploy keys.
  • Hosting panel credentials.
  • Cloudflare/API tokens and CI/CD secrets used by the site.

Account hygiene

  • Remove unknown users from WordPress, hosting panel, Git provider, and CDN.
  • Enforce MFA where available.
  • Reduce admin count.
  • Revoke old application passwords and stale API tokens.

Recovery validation

  • Smoke-test critical user flows.
  • Confirm no malicious outbound traffic.
  • Re-run malware and integrity checks.
  • Verify file permissions and ownership.

Only then remove maintenance restrictions.

Hardening After the Incident

The right post-incident hardening should reduce repeat probability, not just add noise.

Baseline hardening checklist

  • Enforce least privilege on users and service accounts.
  • Disable direct PHP execution in upload directories.
  • Limit write access to WordPress core directories.
  • Keep plugins/themes minimal and maintained.
  • Add controlled update policy (test then promote).
  • Move to secure backup model: encrypted, versioned, and offsite.
  • Use Cloudflare WAF with targeted rules, not broad panic blocks.

Integrity and detection

  • Add file integrity monitoring with alerts on sensitive paths.
  • Alert on new admin creation, plugin/theme install, and option changes tied to execution.
  • Track auth anomalies (wp-login.php spikes, failed login bursts, token abuse).

Operational controls

  • Separate production and staging credentials.
  • Use environment-specific secrets.
  • Restrict admin panels by IP where feasible.
  • Ensure incident runbook exists and is tested quarterly.

Post-Incident Monitoring: What to Watch for 30 Days

Most reinfections happen because monitoring ends too early.

Daily checks (first week)

  • New or modified executable files in wp-content.
  • Unexpected cron entries.
  • Login anomalies and privilege changes.
  • WAF bypass patterns and repeated probes.
  • Outbound traffic to unknown hosts.

Weekly checks (weeks 2-4)

  • Diff current filesystem against clean baseline.
  • Review plugin/theme updates and changelogs.
  • Validate backups by restoring to isolated environment.
  • Confirm no reappearance of old indicators of compromise.

Alert tuning

High-value alerts should page someone. Low-value alerts should aggregate. If everything pages, nothing pages.

A Practical Incident Template

When working live incidents, I keep this short command sequence in front of the team:

  1. Contain edge and auth surfaces.
  2. Snapshot files, DB, logs.
  3. Confirm scope and persistence.
  4. Replace from trusted artifacts.
  5. Rotate all secrets.
  6. Validate and reopen traffic.
  7. Harden and monitor for 30 days.

This creates order under pressure and reduces decision drift.

Final Notes

A hacked WordPress site is rarely a one-file problem. It is usually a chain: vulnerable component, weak auth, missing detection, and no tested response process.

Treat incident response as engineering, not cleanup theater. Preserve evidence, remove persistence, rotate trust anchors, and harden the system that allowed access in the first place.

If you want me to review your site and incident posture before or after an attack, use the contact page.