August 26, 2026
How I Bypassed an Adaptive SQL Injection Filter
When AI couldn’t help and SQLMap couldn’t get the job done, I had to go back to the basics: manually playing with the request. That’s when…

By Bryan Matthew
3 min read
When AI couldn't help and SQLMap couldn't get the job done, I had to go back to the basics: manually playing with the request. That's when I stumbled upon something interesting.
I spent days trying to bypass a SQL injection filter. I tried different payloads, asked AI to do it for me, and even tested SQLMap. Nothing worked.
As seen below, it blocks a basic SQL Injection Payload I inserted.
I asked AI to try and bypass the WAF/ Filter. The first attempt completely failed — it found nothing. Then after forcing it again, it found a couple of weird (uncommon) functions that worked. But, the AI couldn't even do any useful data exfiltration or call functions like SLEEP(). It only found one function that seemed to work.
Eventually, after playing with the request manually for a couple more hours, I found something interesting: the filter could be bypassed by double-encoding certain special characters. But it doesn't end there, there's more to the story…
That was my first breakthrough.
However, things got more interesting when I tried inserting some more complex SQL injection payloads. The simple payloads could get through, but once I introduced longer SELECT statements and SQL functions, the filter started blocking them again.
I then experimented with different representations of the payload, including:
- Changing the casing (mixing upper & lower case) of SQL function names. Example: sleep() -> SleEp()
- Encoding characters that weren't obviously special. Example: table_name -> table_NAM%2545
- Experimenting with different parts of the request independently. Everytime I got a 403, I kept on removing words from the query until the 403 was gone, and modified my payload.
Finally, after playing more and adjusting my payload for a couple of hours, some of these changes were enough to get the payload past the filter. I was able to enumerate the name of the current database, database username, table names, and the number of columns in a table.
Here are some Proof of Concept:
What About SQLMap?
SQLMap wasn't particularly helpful in this case.
The target used multipart/form-data, and after inspecting SQLMap's generated requests, I noticed that it wasn't preserving the request exactly. In particular, \r\n line endings were being changed to \n, which broke the multipart request format.
This was a good reminder that automated tools aren't always reliable when the request structure itself is unusual. Sometimes it's necessary to understand and reproduce the original request manually before automation becomes useful.
What's Actually Happening?
My suspicion is that the behavior is related to differences in how various layers process the request.
The request may pass through something like:
Client → Reverse Proxy/WAF → Web Server → Application
If one layer decodes or normalizes the input differently from another, the filter may inspect one representation while the application ultimately receives another.
This kind of discrepancy is particularly interesting from a security perspective.
I've touched on a similar concept in my previous article about Secondary Context Attacks, where I discussed how differences in input handling between layers can lead to unexpected behavior.
Takeaways
The biggest lesson from this testing wasn't a specific payload.
It was that understanding how the entire request-processing pipeline handles input can be more valuable than endlessly modifying the payload itself.