<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Paulo Rigonato</title>
    <description>The latest articles on DEV Community by Paulo Rigonato (@paulorigonato).</description>
    <link>https://dev.to/paulorigonato</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3963453%2Fe065a6de-f215-4eb0-9e36-cbfac07ac1f8.png</url>
      <title>DEV Community: Paulo Rigonato</title>
      <link>https://dev.to/paulorigonato</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/paulorigonato"/>
    <language>en</language>
    <item>
      <title>WAF Bypass Testing: A Defensive Playbook for Blue Teams</title>
      <dc:creator>Paulo Rigonato</dc:creator>
      <pubDate>Mon, 01 Jun 2026 22:27:28 +0000</pubDate>
      <link>https://dev.to/paulorigonato/waf-bypass-testing-a-defensive-playbook-for-blue-teams-283b</link>
      <guid>https://dev.to/paulorigonato/waf-bypass-testing-a-defensive-playbook-for-blue-teams-283b</guid>
      <description>&lt;p&gt;A Web Application Firewall is useful, but it is not a magic shield.&lt;/p&gt;

&lt;p&gt;In real environments, the difference between “blocked” and “allowed” is often not a zero-day. It is usually a normalization mismatch, a decoding gap, a permissive rule, or an assumption that the WAF and the backend interpret the same request in the same way.&lt;/p&gt;

&lt;p&gt;This article reframes WAF bypass testing from a defensive perspective: how AppSec, Blue Team, and authorized pentest teams can validate whether the WAF, application, and logs agree on what actually happened.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;⚠️ Use this only in systems you own or are explicitly authorized to test. The goal is defensive validation, not unauthorized evasion.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Why WAFs Still Miss Things
&lt;/h2&gt;

&lt;p&gt;Most production WAFs combine three controls:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Signature rules&lt;/strong&gt; — known SQL injection, XSS, path traversal, command injection patterns.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Anomaly scoring&lt;/strong&gt; — unusual request structure, suspicious payloads, abnormal traffic behavior.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Policy enforcement&lt;/strong&gt; — allowed methods, allowed paths, size limits, geo/IP reputation and rate limits.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The weak point is interpretation.&lt;/p&gt;

&lt;p&gt;A WAF may normalize a request once. The backend may normalize it twice. A WAF may inspect the first copy of a parameter. The application framework may use the last copy. A proxy may reassemble traffic differently from the application server.&lt;/p&gt;

&lt;p&gt;That is where defensive validation matters.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Defensive Testing Model
&lt;/h2&gt;

&lt;p&gt;Instead of asking “how do I bypass this WAF?”, ask:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Does the WAF decode and normalize requests the same way the backend does?&lt;/li&gt;
&lt;li&gt;Are suspicious requests visible in logs before and after the WAF?&lt;/li&gt;
&lt;li&gt;Do blocked requests generate useful detection signals?&lt;/li&gt;
&lt;li&gt;Are accepted requests still validated by the application?&lt;/li&gt;
&lt;li&gt;Can the same test be reproduced safely in staging?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The best WAF validation is not a single payload. It is a comparison between four views:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;What the client sent.&lt;/li&gt;
&lt;li&gt;What the WAF inspected.&lt;/li&gt;
&lt;li&gt;What the backend received.&lt;/li&gt;
&lt;li&gt;What the logs and alerts recorded.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Test Category 1: Encoding and Normalization
&lt;/h2&gt;

&lt;p&gt;Encoding gaps happen when different layers decode data differently.&lt;/p&gt;

&lt;p&gt;Common areas to validate:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;URL encoding&lt;/li&gt;
&lt;li&gt;repeated encoding&lt;/li&gt;
&lt;li&gt;Unicode normalization&lt;/li&gt;
&lt;li&gt;HTML entity handling&lt;/li&gt;
&lt;li&gt;null byte handling&lt;/li&gt;
&lt;li&gt;mixed-case keywords&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The defensive goal is not to collect “cool payloads”. The goal is to verify that the request is normalized consistently before security decisions are made.&lt;/p&gt;

&lt;h3&gt;
  
  
  What to Look For
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;WAF logs show a harmless-looking request, but backend logs show a transformed value.&lt;/li&gt;
&lt;li&gt;The WAF blocks one representation but allows another equivalent representation.&lt;/li&gt;
&lt;li&gt;Application code performs additional decoding after WAF inspection.&lt;/li&gt;
&lt;li&gt;Error messages differ between encoded and decoded versions of the same input.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Mitigation
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Normalize input once, early, and consistently.&lt;/li&gt;
&lt;li&gt;Reject ambiguous encodings when possible.&lt;/li&gt;
&lt;li&gt;Log both raw and normalized values in controlled security logs.&lt;/li&gt;
&lt;li&gt;Validate input at the application layer, not only at the WAF.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Test Category 2: Parameter Handling
&lt;/h2&gt;

&lt;p&gt;HTTP parameter pollution occurs when the same parameter appears more than once.&lt;/p&gt;

&lt;p&gt;Different stacks handle repeated parameters differently:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;first value wins;&lt;/li&gt;
&lt;li&gt;last value wins;&lt;/li&gt;
&lt;li&gt;values are concatenated;&lt;/li&gt;
&lt;li&gt;values become an array;&lt;/li&gt;
&lt;li&gt;behavior changes between proxy, framework and application code.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  What to Validate
&lt;/h3&gt;

&lt;p&gt;Create safe test cases in staging and compare:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;WAF inspection result;&lt;/li&gt;
&lt;li&gt;backend parameter value;&lt;/li&gt;
&lt;li&gt;application behavior;&lt;/li&gt;
&lt;li&gt;access logs;&lt;/li&gt;
&lt;li&gt;alerting.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If the WAF checks one value but the application uses another, you have a policy gap.&lt;/p&gt;

&lt;h3&gt;
  
  
  Mitigation
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Reject repeated parameters unless the endpoint explicitly supports them.&lt;/li&gt;
&lt;li&gt;Define a single parsing policy at the edge.&lt;/li&gt;
&lt;li&gt;Add application-level schema validation.&lt;/li&gt;
&lt;li&gt;Alert on duplicated sensitive parameters such as &lt;code&gt;id&lt;/code&gt;, &lt;code&gt;role&lt;/code&gt;, &lt;code&gt;redirect&lt;/code&gt;, &lt;code&gt;url&lt;/code&gt;, &lt;code&gt;callback&lt;/code&gt;, &lt;code&gt;file&lt;/code&gt;, &lt;code&gt;path&lt;/code&gt; and &lt;code&gt;next&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Test Category 3: Transfer and Protocol Differences
&lt;/h2&gt;

&lt;p&gt;Some bypass classes are not about the payload itself, but about how requests are framed or transported.&lt;/p&gt;

&lt;p&gt;Areas to validate:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;chunked transfer handling;&lt;/li&gt;
&lt;li&gt;HTTP/1.1 to HTTP/2 translation;&lt;/li&gt;
&lt;li&gt;reverse proxy behavior;&lt;/li&gt;
&lt;li&gt;oversized headers;&lt;/li&gt;
&lt;li&gt;conflicting headers;&lt;/li&gt;
&lt;li&gt;content-type confusion.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  What to Look For
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;The WAF and backend disagree on request body boundaries.&lt;/li&gt;
&lt;li&gt;The WAF does not inspect a body that the backend accepts.&lt;/li&gt;
&lt;li&gt;A proxy rewrites or forwards headers in unexpected ways.&lt;/li&gt;
&lt;li&gt;Different status codes appear depending on protocol or transfer encoding.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Mitigation
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Enforce consistent protocol handling at the edge.&lt;/li&gt;
&lt;li&gt;Disable unsupported transfer modes.&lt;/li&gt;
&lt;li&gt;Normalize or drop conflicting headers.&lt;/li&gt;
&lt;li&gt;Use request size limits.&lt;/li&gt;
&lt;li&gt;Keep proxy, WAF and application server behavior documented and tested.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Test Category 4: Business Logic
&lt;/h2&gt;

&lt;p&gt;A WAF is not a replacement for application security.&lt;/p&gt;

&lt;p&gt;It cannot reliably understand:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;user roles;&lt;/li&gt;
&lt;li&gt;object ownership;&lt;/li&gt;
&lt;li&gt;workflow order;&lt;/li&gt;
&lt;li&gt;payment rules;&lt;/li&gt;
&lt;li&gt;tenant boundaries;&lt;/li&gt;
&lt;li&gt;account state;&lt;/li&gt;
&lt;li&gt;whether an API action makes business sense.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That means WAF validation must be paired with application-layer tests for IDOR/BOLA, mass assignment, authorization flaws and workflow abuse.&lt;/p&gt;

&lt;h3&gt;
  
  
  Mitigation
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Enforce authorization server-side on every object access.&lt;/li&gt;
&lt;li&gt;Use allowlisted request schemas.&lt;/li&gt;
&lt;li&gt;Validate transitions in business workflows.&lt;/li&gt;
&lt;li&gt;Log high-risk actions with actor, object and decision reason.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  A Safe WAF Validation Checklist
&lt;/h2&gt;

&lt;p&gt;Use this checklist in authorized environments:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Confirm scope, test window and emergency contact.&lt;/li&gt;
&lt;li&gt;[ ] Run tests in staging first.&lt;/li&gt;
&lt;li&gt;[ ] Baseline normal request behavior.&lt;/li&gt;
&lt;li&gt;[ ] Compare WAF logs with backend logs.&lt;/li&gt;
&lt;li&gt;[ ] Test encoding and normalization categories safely.&lt;/li&gt;
&lt;li&gt;[ ] Test repeated parameter handling.&lt;/li&gt;
&lt;li&gt;[ ] Test content-type and method enforcement.&lt;/li&gt;
&lt;li&gt;[ ] Confirm alerts fire on blocked and suspicious requests.&lt;/li&gt;
&lt;li&gt;[ ] Confirm application validation still blocks invalid input.&lt;/li&gt;
&lt;li&gt;[ ] Document exact evidence: request, response, WAF decision, backend interpretation and mitigation.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What Good Evidence Looks Like
&lt;/h2&gt;

&lt;p&gt;A useful WAF finding should include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the affected endpoint;&lt;/li&gt;
&lt;li&gt;request category, not just payload;&lt;/li&gt;
&lt;li&gt;WAF decision;&lt;/li&gt;
&lt;li&gt;backend behavior;&lt;/li&gt;
&lt;li&gt;security log evidence;&lt;/li&gt;
&lt;li&gt;business impact;&lt;/li&gt;
&lt;li&gt;reproducible steps in staging;&lt;/li&gt;
&lt;li&gt;recommended rule or application fix.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Avoid reports that only say “payload X bypassed the WAF”. That is not enough. Explain why the bypass happened and how to remove the class of issue.&lt;/p&gt;

&lt;h2&gt;
  
  
  Defensive Controls That Actually Help
&lt;/h2&gt;

&lt;p&gt;A WAF works best when combined with:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Application input validation&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Strong authorization checks&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Consistent decoding/normalization&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Security logging before and after the WAF&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Rate limiting and abuse detection&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Schema validation for APIs&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Continuous regression tests for known bypass classes&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The key lesson: do not make the WAF the only place where security decisions happen.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;WAF bypass testing should not be treated as a trick collection. It should be treated as defensive engineering.&lt;/p&gt;

&lt;p&gt;If your WAF blocks the obvious request but your backend still accepts an equivalent transformed request, the real issue is not the WAF alone. It is inconsistent interpretation across layers.&lt;/p&gt;

&lt;p&gt;That is fixable.&lt;/p&gt;

&lt;p&gt;Start with safe validation, collect evidence, normalize consistently, and enforce security in the application as well as at the edge.&lt;/p&gt;




&lt;p&gt;Further reading: I expanded this topic in Portuguese with practical examples and mitigation notes on &lt;a href="https://paulo.seg.br/bypass-waf-na-pratica/" rel="noopener noreferrer"&gt;paulo.seg.br&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Paulo Rigonato writes about offensive security, AppSec and defensive validation at &lt;a href="https://paulo.seg.br" rel="noopener noreferrer"&gt;paulo.seg.br&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>cybersecurity</category>
      <category>blueteam</category>
    </item>
  </channel>
</rss>
