Executive Summary
A client requested what was initially scoped as a standard WordPress technical audit covering performance, security, and general maintenance recommendations.
While the external review identified only moderate performance issues, several anomalies within the WordPress installation justified a deeper investigation.
A local forensic analysis confirmed that the website had been compromised. Malicious JavaScript had been injected into both the filesystem and the WordPress database, allowing an unauthorized iframe to be served to visitors.
The engagement shifted from a routine audit to a structured incident response process involving containment, evidence preservation, remediation, verification, and controlled recovery.
Initial Assessment Methodology
The investigation followed two independent stages.
Phase 1 — External Assessment
The first stage consisted of a non-invasive review performed against the public website.
This included:
- Lighthouse/PageSpeed analysis
- HTTP response inspection
- Security header review
- Technology fingerprinting
- Public endpoint enumeration
- WordPress version exposure
- XML-RPC availability
- REST API exposure
- Author enumeration
- robots.txt review
- publicly accessible files
- backup discovery
Although the performance review revealed optimization opportunities, several WordPress-specific indicators suggested that the installation deserved further investigation.
Phase 2 — Offline Investigation
Rather than performing remediation directly on production, the website was restored into an isolated local environment.
Working offline provides several advantages:
- no risk to production traffic
- unrestricted filesystem access
- unrestricted database analysis
- safe malware inspection
- repeatable verification
The investigation consisted of:
Filesystem integrity review
- plugin inventory
- unexpected directories
- orphaned plugins
- abandoned backups
- writable directories
- executable uploads
- hidden PHP files
Database inspection
The database was searched for:
- iframe injections
- script tags
- obfuscated payloads
- suspicious options
- injected revisions
- encoded JavaScript
- unexpected administrators
Manual code review
Several plugins were inspected manually to verify that JavaScript assets matched expected functionality.
One plugin immediately stood out because its bundled JavaScript contained code unrelated to its documented behavior.
That ultimately led to the confirmed compromise.
Compromise Indicators
The investigation identified multiple independent indicators of compromise.
Filesystem
- injected JavaScript
- suspicious plugin folders
- obsolete backup directories
- modified plugin assets
Database
- malicious iframe payload
- injected post content
- infected revisions
Infrastructure
- outdated components
- weak hardening
- information disclosure
- exposed attack surface
Finding identical malicious payloads in both the filesystem and the database strongly suggested persistence rather than an isolated file modification.
Containment Strategy
Before remediation began, the primary objective was preventing additional visitors from receiving malicious content.
Containment included:
- replacing the public website with a temporary landing page
- creating full production backups
- preserving compromised files
- preserving database state
- documenting evidence before modification
This ensured that every subsequent remediation step remained reversible.
Remediation Strategy
Rather than deleting individual malicious files, remediation focused on restoring the integrity of the installation.
Activities included:
Filesystem
- removing injected JavaScript
- quarantining compromised files
- removing obsolete backups
- replacing modified assets where possible
- updating WordPress
- updating plugins
Database
- removing injected iframe payloads
- cleaning affected posts
- cleaning revisions
- validating serialized data
Hardening
Additional hardening measures included:
- rotating authentication salts
- disabling theme/plugin editor
- restricting XML-RPC
- reducing REST information disclosure
- limiting author enumeration
- improving security headers
- reviewing permissions
Verification Process
Cleaning malware is only one part of remediation.
Verification is equally important.
The final validation included multiple independent checks.
Integrity Verification
- WordPress checksum validation
- plugin checksum validation
Malware Hunting
- recursive filesystem scan
- IOC search
- database signature search
Persistence Review
- scheduled cron jobs
- wp_options inspection
- uploads review
- executable detection
Infrastructure Validation
- permissions audit
- endpoint validation
- header verification
Only after every verification stage passed was the website considered ready for reopening.
Incident Timeline
| Stage | Activity |
|---|---|
| Phase 1 | External audit |
| Phase 2 | Local restoration |
| Phase 3 | Filesystem investigation |
| Phase 4 | Database investigation |
| Phase 5 | Containment |
| Phase 6 | Remediation |
| Phase 7 | Hardening |
| Phase 8 | Verification |
| Phase 9 | Production validation |
Lessons Learned
Several conclusions emerged from this investigation.
Performance ≠ Security
PageSpeed measures rendering performance.
It does not verify software integrity.
Malware Often Exists in Multiple Layers
Cleaning a modified plugin alone would not have solved this incident because malicious content had also been injected into the database.
Both persistence mechanisms needed to be removed.
Local Investigation Is Worth the Time
The initial external audit required roughly two hours.
The additional local investigation required approximately three more.
Those three hours completely changed the outcome of the engagement.
Without them, the compromise would likely have remained undiscovered.
Proper Remediation Is a Process
Effective incident response is rarely:
Delete one suspicious file and move on.
A complete remediation requires:
- Containment
- Backup
- Investigation
- Evidence preservation
- Cleanup
- Hardening
- Verification
- Controlled reopening
Only after completing all eight stages can the website reasonably be considered trustworthy again.