Loading...

Security · 10 min read

The OWASP Top 10, as a WAF actually enforces it

Every vendor claims to cover the OWASP Top 10. The claim is close to meaningless as stated, because the Top 10 is a list of risk categories and a firewall matches patterns in requests. This is the honest mapping: which categories a WAF genuinely blocks, which it only narrows, and which it cannot touch at all.

Updated

The OWASP Top 10, as a WAF actually enforces it

What the Top 10 actually is

OWASP — the Open Worldwide Application Security Project — publishes a ranked list of web application risk categories, revised every few years from real incident and scan data. The current list leads with broken access control, cryptographic failures and injection.

Two things follow from how it is built, and both get lost in vendor copy.

It is categories, not vulnerabilities. "Injection" covers SQL injection, command injection, LDAP injection and template injection. A product cannot "support" a category; it can only detect particular techniques within it.

It is a prioritisation tool for the people building the application. It tells you where to spend review time. It was never a compliance checklist, and a firewall in front of an application does not make the list disappear.

What a WAF is, in one paragraph

A web application firewall sits in front of your application and inspects each request — the path, the query string, the headers, the cookies and the body — against a set of rules. When a rule matches, the request is blocked, logged, or both, before your application ever runs.

The open rule set most WAFs are built on is the OWASP Core Rule Set (CRS), a set of generic detection rules maintained by the same foundation. It is the rule set we run, on ModSecurity, at the edge. CRS groups its rules into families with numeric ranges — 941 for cross-site scripting, 942 for SQL injection, 930 for local file inclusion, 931 for remote file inclusion, 932 for remote command execution, 933 for PHP injection — which is why a blocked request can be traced to an exact rule number rather than a vague "security policy".

Category by category: what the firewall really does

Injection — a WAF is genuinely strong here. SQL injection, command injection and template injection all leave recognisable shapes in request data. This is what pattern matching is good at, and the rules catch most opportunistic attempts outright. It does not make parameterised queries optional; it buys you time and it stops the automated majority.

Cross-site scripting — strong, with caveats. Script payloads in parameters are detectable. Stored XSS that arrives through a path the firewall does not inspect, or a DOM-based issue that never touches your server, is out of reach.

Security misconfiguration — partly. A WAF can hide a server banner, block access to .git and backup files, and refuse dangerous methods. It cannot fix a permissive CORS policy or an admin panel with a default password.

Vulnerable and outdated components — partly, and temporarily. When a CVE is public, generic rules often catch the published exploit shape, which is the entire value of "virtual patching": it buys the days between disclosure and your upgrade window. It is not a substitute for upgrading.

Broken access control — mostly not. If your application lets user A fetch user B's invoice by changing an ID in the URL, both requests look identical to a firewall. It has no idea who owns invoice 4711. This is the top category on the current list and it is an authorisation bug in your code.

Identification and authentication failures — partly. Rate limiting on login endpoints blunts credential stuffing and brute force, which is real and worth having. Weak session handling or a password reset flow that leaks tokens is not something a firewall sees.

Insecure design and software integrity failures — no. These are architectural. No request pattern expresses them.

The false-positive problem, and why it decides everything

Any rule set aggressive enough to catch injection will sometimes block a human. The classic case is a content editor saving an article that contains a code sample, or a support form where someone pastes an error message containing SQL. The request is legitimate; it simply looks like an attack.

This is where WAFs are won or lost operationally. If a false positive means "the site is broken for that person and nobody can explain why", the WAF gets switched off within a month — which is the worst outcome, because the protection disappears quietly while everyone believes it is on.

What makes it survivable is traceability. On our edge a blocked request returns a branded 403 page with a reference ID, and that ID maps to the audit-log entry with the rule that matched and the field it matched on. A support conversation becomes "rule 942100 matched the content field on the editor URL" instead of "the site blocks me sometimes". The fix is then a narrow exclusion: that rule, that field, that path. Not the rule family, and not the site.

Paranoia levels: the dial nobody explains

The Core Rule Set ships with paranoia levels, from 1 to 4. Level 1 catches the obvious and rarely blocks a human. Each level up adds rules that are stricter and more prone to false positives, until at level 4 a firewall will refuse things a normal application does every day.

The honest advice is unexciting. Start at the default, watch the log for a week, and only raise the level if you are protecting something that justifies the operational cost — and then do it in a staging environment first. Most sites are better served by a well-tuned level 1 than a level 3 that somebody silently disabled after the third complaint.

How to evaluate a vendor's "OWASP Top 10 coverage"

Four questions cut through most marketing.

1. Which rule set, and which version? "OWASP-based" can mean the Core Rule Set or a vendor's own rules with OWASP-flavoured names. Version matters too — rule sets are revised, and running an older one is a real tradeoff rather than a detail. We run CRS and upgrade it deliberately, testing against the false-positive patterns our own customers hit, rather than tracking upstream automatically.

2. What do I see when a request is blocked? If the answer is a generic error page and a log you cannot search by rule, tuning will be guesswork.

3. How do I exempt one field on one path? If the smallest available exclusion is "disable the rule family for this site", the product is pushing you toward switching protection off.

4. What is not covered? A vendor who answers "access control and business logic are your code, not our rules" is telling you the truth. One who claims full Top 10 coverage is describing a category list, not a capability.

OWASP and WAF FAQ

Does a WAF make my application OWASP compliant?

There is no such thing as OWASP compliance. The Top 10 is an awareness and prioritisation document, not a standard you certify against. A WAF reduces exposure in some categories and does nothing in others; the application still has to be written carefully.

Is the OWASP Core Rule Set the same as the OWASP Top 10?

No. The Top 10 is the risk list. The Core Rule Set is a set of generic detection rules maintained by the same foundation and used by ModSecurity and compatible engines. The rule set addresses several of the Top 10 categories; it does not implement the list.

Can a WAF stop SQL injection completely?

It stops the large majority of opportunistic attempts and raises the effort for targeted ones. It is not a replacement for parameterised queries, because a determined attacker tailors the payload to evade pattern matching. Treat it as depth, not as the fix.

What is virtual patching?

Blocking the exploit shape of a known vulnerability at the firewall while you wait to deploy the real fix. It is genuinely useful in the window between a CVE becoming public and your maintenance window arriving, and it is dangerous if it becomes the permanent answer.

Which Top 10 category should I worry about most?

Broken access control, because it sits at the top of the current list, it is common, and it is the one your firewall cannot help with. Check that every object your API returns is one the authenticated user is entitled to — most of these bugs are a missing ownership check in a controller.