The problem that started it all
A friend called me one afternoon, panicked. His client’s WooCommerce store was sending spam emails, rankings had tanked, and Google was showing a “This site may be hacked” warning. The culprit? A nulled theme downloaded from a sketchy forum β pre-loaded with a PHP backdoor.
He spent two days combing through thousands of PHP files manually, looking for the injected code. That’s when I thought: this should take 10 seconds, not two days.
So I built WP Scan β a WordPress-specific security scanner that checks themes, plugins, and raw PHP files against 40+ vulnerability patterns and returns a full report in under 10 seconds.
π Try it free: wp-scan.org β no account, no credit card, just upload a ZIP and scan.
What it looks like in action
The interface is deliberately simple. Drag your ZIP in, hit scan, get results.
or click to browse Β· Max 20 MB free Β· 150 MB premium
or enter your license key for premium scan
And here’s what the results look like. Every finding is tagged by severity (Critical β Low), includes the vulnerable file path, and a code snippet showing exactly what was found:
47: $id = $_GET[‘product_id’]; // β unsanitised
48: $wpdb->get_results(“SELECT * FROM wp_reviews WHERE id=$id”);
49: }
absint() + $wpdb->prepare() β upgrade to see full guide βWhat WP Scan actually detects
I didn’t want a generic “PHP linter”. I focused on the exact patterns that appear in real-world WordPress malware, nulled themes, and poorly coded plugins. The scanner currently detects 40+ vulnerability patterns across these categories:
The patterns cover PHP, JavaScript, HTML, and template files β so it catches JS-based XSS in theme templates and PHP backdoors buried in plugin assets alike.
How it works under the hood
WP Scan is a pure PHP application β no Node, no Python, no external scanning engine. Here’s the flow:
- Upload & extract β ZIP is uploaded, validated (bomb protection: 10k entries max, 10 MB/file, 300 MB total uncompressed), then extracted to a temp directory.
- File walk β recursively walks the directory, skipping binaries and files over 2 MB. Scans PHP, JS, HTML, HTM, TPL, INC files.
- Pattern matching β each file is regex-matched against the pattern library. Patterns are weighted by severity.
- Report generation β findings are assembled into a severity-sorted HTML report with file paths, line numbers (premium), code snippets, and fix guides (premium).
- Cleanup β extracted files are deleted immediately. Nothing is stored.
β‘ Performance note: The scanner uses a 90-second hard deadline, a 20,000-file cap, and set_time_limit(120) before every scan so large repositories never crash the server.
The tech stack is intentionally minimal:
MySQL / PDO
PayPal IPN
Razorpay (India)
Tailwind CSS (CDN)
Custom SMTP mailer
Zero dependencies
No Composer, no npm, no framework. One PHP file + a pattern library. It deploys to any shared hosting plan in under 5 minutes.
Features I’m most proud of
ZIP bomb protection
Hard limits on entry count, per-file size, and total uncompressed size stop malicious ZIPs from crashing the server.
Zero-storage scanning
Uploaded files are extracted to a temp directory, scanned, then deleted immediately β nothing persists on the server.
Geo-based pricing
Indian visitors see INR prices via Razorpay (UPI, NetBanking, EMI). International visitors see USD via PayPal.
Built-in drip emails
A 2-step drip sequence (day 3 + day 7) nurtures free users toward paid, with a 10% coupon on the second email.
Monthly recurring billing
PayPal subscriptions with IPN handling for renewals, cancellations, refunds, and a dashboard toggle for auto-renew.
CSRF protection
Every POST form is protected with session-based CSRF tokens β login, register, settings, password change, and admin actions.
Pricing
Free forever with 2 scans/month. Premium unlocks everything β and the lifetime plan is a steal if you audit code regularly.
- 5 scans/month
- Exact line numbers
- Fix guides
- 150 MB ZIPs
- HTML export
- Unlimited scans
- Exact line numbers
- Fix guides + code fixes
- 150 MB ZIPs
- HTML export
- Priority support
- Unlimited scans
- All premium features
- Future updates
- No recurring fees
What I learned building this
1. Shared hosting has real constraints
PHP’s mail() silently fails on Hostinger. I had to build a full SMTP client from scratch using PHP’s stream_socket_client() β supporting STARTTLS, SSL, and AUTH LOGIN with no external libraries. It works, and it’s ~150 lines of code.
2. ZIP bombs are a real attack vector
Before adding protection, a crafted ZIP with deeply nested directories could hang the server indefinitely. The fix: hard limits on entry count (10k), per-file uncompressed size (10 MB), total size (300 MB), and a 90-second deadline inside the file iterator.
3. Regex pattern libraries need testing on real malware
My first version of the backdoor patterns was catching too much legitimate code (e.g., WordPress core uses eval() in specific places). I ended up hand-testing patterns against a corpus of real nulled themes and malware samples I found on public security repos.
“The pattern that catches the most real-world malware is the combination of
eval()+base64_decode()in the same expression. It appears in virtually every backdoor I’ve ever seen.”
4. Geo-based pricing matters for India
PayPal blocks many Indian cards for domestic merchant accounts. Integrating Razorpay with Cloudflare’s CF-IPCountry header for geo-detection solved this β Indian visitors automatically see INR prices and Razorpay as the only payment option. International visitors see USD + PayPal.
5. Drip emails convert
The day-3 “did you find anything?” email and day-7 coupon email run automatically via a cron job. The 10% coupon code is created on-the-fly if it doesn’t exist yet, and the whole drip sequence is logged per-user to avoid duplicates.
What’s next
A few things I’m planning:
- API access β so CI/CD pipelines can scan plugins before deployment
- WordPress plugin β scan your live installation from wp-admin directly
- Signature database updates β crowdsourced malware signatures from users
- Affiliate program improvements β better reporting, Stripe payouts
β WP Scan is live and scanning. If you use WordPress β for yourself or clients β give it a try. The free tier (2 scans/month) is genuinely useful. And if you find a vulnerability pattern I’m missing, reply to the welcome email and I’ll add it.
Try WP Scan β it’s free
Upload any theme or plugin ZIP and get a full vulnerability report in under 10 seconds. No account required.
Rajan Gupta
FullStack Web DeveloperRajan Gupta is a passionate web developer and digital creator who loves sharing insights on WordPress, modern web design, and performance optimization. When not coding, they enjoy exploring the latest tech trends and helping others build stunning, high-performing websites.