MySQL Hexadecimal Strings

MySQL accepts hexadecimal literals as a native string representation — a feature with significant offensive value. When quote-based injection is blocked by escaping functions like PHP’s mysql_real_escape_string() or addslashes(), hex literals bypass the filter entirely because they require no quotes.

Syntax

MySQL supports two hex literal notations:

X'48656C6C6F'      -- standard SQL notation (case-insensitive X)
0x48656C6C6F       -- ODBC-style notation (0x must be lowercase)

Both produce the binary string Hello. The X'val' notation requires an even number of hex digits; 0xval pads odd-length values with a leading zero.

Why it works

By default, a hexadecimal literal is a binary string, not a number. Each pair of hex digits maps to one byte. MySQL automatically decodes it in string contexts:

SELECT 0x68656C6C6F;    -- returns "hello"
SELECT X'4D7953514C';   -- returns "MySQL"

Because hex literals are not quoted strings, escaping functions that only neutralize ' and " have no effect on them. The payload passes through the filter intact and is decoded by MySQL at query time.

Offensive use

Bypassing quote filters. If the application escapes single quotes but passes hex input unfiltered, inject via hex:

-- Instead of: UNION SELECT 'admin'--
-- Use:
UNION SELECT 0x61646D696E--

Concatenation without quotes. Build strings without ever touching a quote character:

SELECT CONCAT(0x61646D696E, 0x3A, 0x70617373);   -- "admin:pass"

Evading WAF keyword rules. Some WAFs flag common SQL keywords or quoted strings but miss hex-encoded equivalents.

GROUP_CONCAT separators. 0x3a is a colon, 0x2c is a comma — useful for building readable output from aggregated rows.

Converting to hex

echo -n "hello" | xxd -p | tr -d '\n'
# 68656c6c6f

Or in Python: 'hello'.encode().hex()68656c6c6f.

Defensive note

Hex literal support cannot be disabled in MySQL. The defense is the same as for all SQLi: parameterized queries. Escaping functions are inherently incomplete — they protect against known-bad characters but cannot anticipate all valid SQL representations of attacker-controlled data.

Sources

See also