← Blog 2026-04-17 · 8 min read

How the v2.8 Anomaly Hunter finds 0-day bugs

Ten independent hunters looking for weirdness instead of signatures. A design philosophy, sample findings, and why anomaly scanning complements rule-based tools.

The problem with rule-based scanners

Standard security scanners are pattern matchers. They have a rule that says "look for SQL error messages" and a rule that says "check if the param name is id or user", and they fire payloads based on what they were taught to check. They're fast, reliable, and they miss novel bugs.

Here's a real case: a pentest target had a search endpoint at /api/products?q=.... Our standard checks sent SQL and XSS payloads into q, got clean responses, and moved on. A human pentester ran the same scan, scrolled through the crawler output, and noticed a weird debug header: X-Debug-Query: SELECT * FROM products WHERE name LIKE '%q%'. The backend was building queries unsafely but had fixed the obvious error channel. A quick test confirmed blind SQL injection.

The scanner missed it because no rule said "check for unusual headers containing SQL". The human didn't miss it because humans notice when something is off.

Anomaly scanning as a second brain

The v2.8 Anomaly Hunter is built around a simple idea: flag anything unusual, regardless of whether it matches a known pattern. If an attacker would look twice, we flag it.

Ten independent hunters run in parallel during every scan. Each is specialised but none claims to detect specific CVEs — they just produce a stream of "this seems wrong" signals.

The ten hunters

Here's the full list with what each one actually does:

1. Stack trace & debug output hunter

Patterns for PHP fatal errors, Python tracebacks, Java stack frames, Rails error pages, .NET exceptions, Node.js panics, Go stack dumps. Crucially, it also triggers errors — sends malformed input (apostrophes, null bytes, unterminated brackets) and looks for freshly-appeared error signatures. One of the bigger finds in testing was a production PHP app that swallowed errors on the main page but leaked full stack traces when a null byte was injected.

2. Filesystem path disclosure

Regexes for absolute paths: /var/www/..., /home/user/public_html/..., Windows C:\inetpub, Docker /app/.... Low-severity on its own but gold for chained attacks. If LFI is suspected elsewhere, the disclosed path makes exploitation trivial.

3. Suspicious response headers

X-Powered-By: PHP/7.2.11, Server: Apache/2.4.29, X-AspNet-Version, staging markers like X-Environment: dev. Version leaks let an attacker jump straight to the relevant CVE instead of fingerprinting. We just surface them.

4. Dangerous HTTP method surprises

Tests PUT/DELETE/TRACE/PATCH/CONNECT on the crawled URLs. A 200 response on PUT is a potential webshell upload. TRACE echoing the request body is a classic XST (cross-site tracing) vector.

5. Default installation pages

"It works!" Apache, Nginx welcome, IIS default, Tomcat examples, phpMyAdmin, Plesk panels. These are "I forgot to clean up" tells. Attackers check them first because they often come with default credentials.

6. Debug & admin endpoint probing

Probes 40+ known-interesting paths: /actuator/env, /actuator/heapdump, /.git/HEAD, /.env, /composer.lock, /phpmyadmin. Not all findings are critical but any 200-with-content on these paths is worth a human look.

7. HTTP parameter pollution

Sends ?x=A&x=B and compares the response. If the server picks one or the other consistently, no big deal. If behaviour diverges between duplicated and non-duplicated params, that's a WAF bypass surface. Often used to smuggle payloads past filters that check the first copy.

8. Content-Type mismatches

JSON body served with Content-Type: text/html. Browsers may render it, which turns any attacker-controlled HTML in the JSON into XSS. Caught a real one in testing: an API endpoint returning {"title":"<img src=x onerror=alert(1)>"} with text/html.

9. Login timing oracles

Sends a login attempt with an obviously-fake username and admin. Compares response times over three samples each. A consistent 200+ms difference suggests the app is hashing the submitted password only for existing users (short-circuit on unknown) — a reliable user-enumeration channel.

10. Parameter reflection surfaces

Sends a unique marker into every query parameter and checks whether it appears anywhere in the response. Reflection on its own isn't exploitable, but finding which params reach output tells you where to focus manual XSS testing. Scans also identify dangerous context reflections — if the marker lands inside a <script> block or an event handler attribute, severity bumps up.

Why severity varies

Not every anomaly is a vulnerability. A stack trace is HIGH because it leaks implementation details attackers will weaponise. A Content-Type mismatch is LOW because it usually needs another bug to become exploitable. Severities reflect how much an attacker can do with this finding alone, not an absolute rating.

What this doesn't replace

Anomaly scanning complements rule-based checks, it doesn't replace them. Rules are fast, deterministic, and catch the well-known bugs. Anomaly hunters are noisier and slower but catch the weird stuff rules never heard of. Run both. Every scan in v2.8 does.

What's next

Planned for v2.9: a "memory" feature where the anomaly hunter notices when something changes between scans. If your site suddenly starts returning a new suspicious header, or a previously-safe parameter begins reflecting input, that's worth flagging — even if neither state matches any known vulnerability pattern.


← Back to blog · See the v2.8 changelog