Browser-driven WAF efficacy testing

See what your WAF really blocks — and what slips past.

Test My WAF points a real browser at your site and fires fresh, un-gameable attack payloads and evasion chains across 12 categories. It measures exactly what your firewall stops, what bypasses it, and hands you a graded report with copy-paste fixes.

DNS-verified ownership Non-weaponized payloads No agent, no install
scan · app.example.com SCANNING
EFFICACY
0Blocked
0Bypass
Three steps · about two minutes

Prove it's yours. Scan it. Read the number.

No credentials, no agent, no scheduling call. Ownership is verified before a single request goes out — so only you can test your domain.

STEP 01

Verify ownership

Add one DNS TXT record. We re-check it at scan time, so attack-shaped traffic only ever reaches a domain you control.

STEP 02

Run the scan

A headless browser drives categorized payloads, composable evasion chains, and freshly generated metamorphic variants — then watches what your WAF does with each.

STEP 03

Read the report

A graded, self-contained report: every bypass, a false-positive check, and copy-paste remediation tuned to your detected WAF vendor.

Coverage

Twelve attack classes. Every one, re-encoded.

The textbook corpus and a fresh metamorphic set, each fired plain and through layered evasion — so a signature match isn't mistaken for real understanding.

SQLI
SQL Injection
Union, boolean, comment-broken
XSS
Cross-Site Scripting
Reflected, attribute, event
RCE
Command Injection
Shell metacharacters
LFI
Path Traversal
Dot-dot, null byte, wrappers
SSRF
Server-Side Request
Metadata & internal hosts
SSTI
Template Injection
Expression evaluation
LDAP
LDAP Injection
Filter manipulation
NOSQL
NoSQL Injection
Operator injection
REDIR
Open Redirect
Off-domain forwarding
CRLF
CRLF / Header
Response splitting
PROTO
Prototype Pollution
__proto__ traversal
XXE
XML External Entity
Entity expansion

Evasion is built in, not bolted on. Every payload is re-expressed through composable encoding chains — URL, double-URL, mixed-case, SQL comments, whitespace, HTML entities, null byte — to find the exact transform that walks past your rules.

Why it's different

A number your WAF can't game.

Most testers replay a fixed list a firewall can be tuned to recognize. This one changes every run — and drives a real browser, so it sees what a scripted client never will.

It uses a real browser

Playwright navigation executes JavaScript challenges and clears bot detection that a plain HTTP client is stopped by — reaching code paths other scanners never touch.

Payloads it can't memorize

Every scan generates fresh, metamorphic payloads. That measures whether your WAF understands an attack or is just matching known strings it's been trained on.

An honest score

We check for false positives too — flagging benign traffic your WAF wrongly blocks — so a firewall that blocks everything can't earn a fake A. The grade reflects real efficacy.

Fixes, not just findings

Each gap comes with concrete, vendor-aware remediation — the rule to add or tune — in a self-contained report you can hand straight to the WAF team.

One clear verdict

From block-everything to wide-open, on one scale.

Weighted by category, evasion resistance, and false-positive rate — the same measure every time, so you can watch it move as you tune.

ASEALED
BSOLID
CLEAKY
DWEAK
FOPEN

Measure your WAF in a few minutes.

Verify your domain, run a scan, and get a graded efficacy report — free. No install, no credentials, no sales call.

Test your WAF now
Every request is tagged X-WAF-Test-ID so your WAF can recognize, log, or exempt the run.
",1], ['SQLI',"id=1' OR '1'='1",1], ['RCE',"cmd=;cat /etc/passwd",1], ['LFI',"file=../../../../etc/passwd",0], ['SSRF',"url=http://169.254.169.254/",1], ['SSTI',"name={{7*7}}",1], ['XSS',"q=%3Cimg src=x onerror=alert(1)%3E",0], ['SQLI',"id=1/**/UNION/**/SELECT/**/pwd",1], ['CRLF',"q=%0d%0aSet-Cookie:sid=1",1], ['NOSQL',"user[$ne]=&pass[$ne]=",0], ['REDIR',"next=//evil.example.com",1], ['XXE',"",1], ['PROTO',"__proto__[isAdmin]=true",1], ['LDAP',"u=*)(uid=*))(|(uid=*",1], ['LFI',"page=php://filter/convert.b64",1], ['XSS',"svg/onload=alert(document.domain)",1] ]; var log=document.getElementById('log'), ringEl=document.getElementById('ring'), gradeEl=document.getElementById('grade'), tbEl=document.getElementById('tb'), txEl=document.getElementById('tx'), live=document.querySelector('.con-live'), C=2*Math.PI*50, blocked=0, bypass=0, i=0, started=false; var reduce=matchMedia('(prefers-reduced-motion:reduce)').matches; function finalize(){ var total=blocked+bypass, pct=Math.round(blocked/total*100); ringEl.style.strokeDashoffset=C-(C*pct/100); gradeEl.textContent=pct>=90?'A':pct>=80?'B':pct>=65?'C':pct>=50?'D':'F'; tbEl.textContent=blocked; txEl.textContent=bypass; live.innerHTML=''+pct+'% BLOCKED'; live.style.color=pct>=80?'#3ddc84':'#e2a13c'; } function tick(){ if(i>=rows.length){ finalize(); return; } var d=rows[i], row=document.createElement('div'); row.className='logrow'; row.innerHTML=''+d[0]+''+d[1].replace(/'+ ''+(d[2]?'BLOCKED':'BYPASS')+''; log.appendChild(row); if(d[2])blocked++;else bypass++; tbEl.textContent=blocked; txEl.textContent=bypass; var kids=log.children; while(kids.length>9) log.removeChild(kids[0]); var total=blocked+bypass, pct=Math.round(blocked/total*100); ringEl.style.strokeDashoffset=C-(C*pct/100); i++; setTimeout(tick,300+Math.random()*180); } function run(){ if(started)return; started=true; if(reduce){ rows.forEach(function(d){ if(d[2])blocked++;else bypass++; var row=document.createElement('div');row.className='logrow';row.style.animation='none'; row.innerHTML=''+d[0]+''+d[1].replace(/'+(d[2]?'BLOCKED':'BYPASS')+''; if(log.children.length<9)log.appendChild(row); }); finalize(); return; } setTimeout(tick,400); } var cio=new IntersectionObserver(function(es){es.forEach(function(e){if(e.isIntersecting){run();cio.disconnect();}});},{threshold:.35}); cio.observe(document.getElementById('console')); })();