TL;DR: Every plugin was current, every known exploit failed, and the report still had six findings. I explain the reporting discipline of a negative assessment and what a misconfigured perimeter would have exposed.
The scenario
I ran this as a black-box review: no credentials, only the publicly visible surface. Here is what I saw before I touched anything.
A small hospitality business site on a current content platform behind a commercial web application firewall, with caching, statistics and a consent plugin. Assessment covered header posture, mail authentication, user enumeration, version disclosure and firewall fingerprinting.
I removed all identifying information. The target is described only by sector and technology class so the pattern can be reused.
The pattern
The pattern I recognised — and that I keep finding in similar estates:
An assessment behind a firewall produces a different document. The first change is that the vectors stop being the report and become the method: six vectors were planned, all six failed, and that fact is the headline. The second change is that everything worth reporting is now hygiene, because the exploitable layer is exactly what the firewall is covering.
That situation is where reporting discipline gets tested. The temptation is to inflate: to treat a version banner as a vulnerability, to describe an enumeration endpoint as account compromise. The alternative is to be precise about what was attempted, what the firewall returned, and what would still be exploitable if the firewall were ever misconfigured or bypassed. The second document is shorter, more useful and survives being read by an auditor.
The fingerprinting finding deserves separate mention because it is the one that changes how you should think about the perimeter. A firewall that identifies itself in every response is not doing you a favour; it tells an attacker which layer to think about, and it makes the estate appear to be protected by a product rather than by configuration. The response header is also a promise: it says the protection is expected to stay, which is an assumption worth verifying rather than trusting.
Findings
| Severity | Finding | Evidence |
|---|---|---|
| MEDIUM | No security headers on the public surface | HSTS, frame protection and content-type protection absent |
| MEDIUM | Mail authentication soft-fail with no enforcement policy | Sending domain spoofable |
| LOW | User enumeration through the read interface | Author account and identifier exposed |
| LOW | Platform and plugin versions in generator metadata | Exact build identifiable |
| LOW | Firewall fingerprint in a response header | Perimeter product identified |
| LOW | No published security contact file | No coordinated disclosure channel |
The attack path
Reproduction in my lab
Every command below targets a lab container I control. Nothing here is aimed at a live system.
Confirm the fingerprint and the header gaps on your own site
$ curl -sI https://example.org/ | grep -iE 'x-ws|x-cdn|x-firewall|x-sucuri|x-cf-ray|^server:'
$ curl -sI https://example.org/ | grep -icE 'strict-transport-security|content-security-policy|x-frame-options|x-content-type-options|referrer-policy'
$ curl -so /dev/null -w '%{http_code}\n' 'https://example.org/.well-known/security.txt'
Detection in your own estate
Check the mail chain on a domain that sends mail
$ dig +short TXT example.org | grep -i spf
$ dig +short TXT _dmarc.example.org
# note: no _dmarc answer is itself the finding
Remediation
Add the header baseline without touching the firewall rules
# the firewall does not add response headers; the origin must
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "geolocation=(), camera=(), microphone=()" always;
Once an attacker gains access, they can perform the following actions:
Takeaways
- A blocked vector is a result. Write it up as one.
- Do not inflate a version banner into a vulnerability to fill a report.
- State what a misconfigured perimeter would expose; that is the actionable part.
- A firewall that identifies itself is a perimeter you should test, not trust.