1. SQL Injection – are you ready for
defense?
Andrey Korshikov
Krasnodar, Russia
PASS Regional Mentor for Central Eastern Europe
MVP, MCT, MCSE, MCITP, MCPD, MCSD .NET, MCDBA, MOS
6. Statistics
• In February 2002, Jeremiah Jacks discovered that Guess.com was vulnerable
to an SQL injection attack, permitting anyone able to construct a properly-
crafted URL to pull down 200,000+ names, credit card numbers and expiration
dates in the site's customer database.
• On November 1, 2005, a teenage hacker used SQL Injection to break into the
site of a Taiwanese information security magazine from the Tech Target group
and steal customers' information.
• On March 29, 2006, a hacker discovered an SQL Injection flaw in an official
Indian government's tourism site.
• On June 29, 2007, a computer criminal defaced the Microsoft UK website using
SQL Injection. UK website The Register quoted a Microsoft spokesperson
acknowledging the problem.
• In January 2008, tens of thousands of PCs were infected by an automated SQL
Injection attack that exploited a vulnerability in application code that uses
Microsoft SQL Server as the database store.
7. Statistics
• …
• In May 2012, the website for Wurm Online, a massively multiplayer online
game, was shut down from an SQL Injection while the site was being updated.
• In July 2012 a hacker group was reported to have stolen 450,000 login
credentials from Yahoo!. The logins were stored in plain text and were allegedly
taken from a Yahoo subdomain, Yahoo! Voices. The group breached Yahoo's
security by using a "union-based SQL Injection technique".
• In February 2013, a group of Maldivian hackers, hacked the website " UN-
Maldives" using SQL Injection.
8. SQL Injection
One package of milk for 30 rubles
SELECT TOP 1 productname FROM shop
WHERE (type=‘milk' AND price=‘30')
9. SQL Injection
One package of milk for 30 rubles or one
kilogram of sweets for 200 rubles
SELECT TOP 1 productname FROM shop
WHERE (type=‘milk' AND price=‘30')
OR (type=‘sweets' AND price='200')
11. Dangers of SQL Injection
It is easy to study and apply
Archives of solutions
http://www.exploit-db.com/
Can be automatized
Many script examples in the Network are
vulnerable for attack
Does harm to the most valuable – a database
17. Application
'; drop table users--
SqlCommand comm = new SqlCommand("select * from users where
username = '" + txtUserName.Text + "' and password = '" +
txtPassword.Text + "'");
18. Getting data
Username: '; drop table temp--
Username: admin'--
Username: ' or 1=1--
Username: ' union select 1,
'fictional_user', 'some_password', 1--
19. Getting data
table name
' having 1=1--
columns name
' group by users.id having 1=1 --
' group by users.id, users.username,
users.password, users.privs having 1=1--
Type of data
' union select sum(username) from
users--
' union select sum(id) from users--
20. Getting data
add new row
'; insert into users values( 666,
'attacker', 'foobar', 0xffff )--
info about system
' union select @@version,1,1,1 --
logins
' union select min(username),1,1,1 from
users where username > 'a'–-
passwords
' union select password,1,1,1 from users
where username = 'admin'--
27. Defense
Tell to the user only that he/she really needs
to know
try
{
// Attempt some database operation
}
catch(Exception e)
{
errorLabel.Text = string.Concat("Sorry, your request
failed. ", "If the problem persists please report the following
message ", "to technical support", Environment.Newline,
e.Message);
}
try
{
// Attempt some database operation
}
catch(Exception e)
{
int id = ErrorLogger.LogException(e);
errorLabel.Text = string.Format("Sorry, your request
Failed. If the problem persists please report error code {0}
to the technical support team.", id);
}
28. Defense
Check of all entered data
size
content of string variables
using XML-schema
decline symbols ; ' -- /* */ xp_
Use stored procedures
29. Defense
Use the parameterized input with stored
procedures
SqlDataAdapter myCommand = new
SqlDataAdapter("LoginStoredProcedure
'" + Login.Text + "'", conn);
30. Defense
Use SQL parameters of safe types
SqlDataAdapter myCommand = new
SqlDataAdapter("AuthorLogin", conn);
myCommand.SelectCommand.CommandType =
CommandType.StoredProcedure;
SqlParameter parm =
myCommand.SelectCommand.Parameters.Add("@
au_id", SqlDbType.VarChar, 11);
parm.Value = Login.Text;
31. Defense
Pack parameters by functions QUOTENAME()
and REPLACE()
--before:
SET @temp = 'select * from authors where
au_lname=''' + @au_lname + '''‘
--after:
SET @temp = 'select * from authors where
au_lname=''' +
REPLACE(@au_lname,'''','''''') + ''''
32. Defense
Execute with least privilege
<add key="cnxNWindBad"
value="server=localhost;uid=sa;pwd=;da
tabase=northwind;" />
<add key="cnxNWindGood"
value="server=localhost;uid=NWindReade
r;pwd=utbbeesozg4d;
database=northwind;" />
33. Defense
Secrets must be secrets
<add key="cnxNWindBest"
value="AQAAANCMnd8BFdERjHoAwE/
Cl+sBAAAAcWMZ8XhPz0O8jHcS1539LAQAAAACAAAA
AAADZgAAqAAAABAAAABdodw0YhWfcC6+
UjUUOiMwAAAAAASAAACgAAAAEAAAALPzjTRnAPt7/
W8v38ikHL5IAAAAzctRyEcHxWkzxeqbq/
V9ogaSqS4UxvKC9zmrXUoJ9mwrNZ/
XZ9LgbfcDXIIAXm2DLRCGRHMtrZrp9yledz0n9kgP
3b3s+
X8wFAAAANmLu0UfOJdTc4WjlQQgmZElY7Z8" />
34. Defense
Secrets must be secrets
string strCnx =
SecureConnection.GetCnxString("cnxNWindBest");
public class SecureConnection {
static public string GetCnxString(string configKey)
{
string strCnx;
try { // get encrypted string from web.config
string strEncryptedCnx = ConfigurationSettings.AppSettings[configKey];
// decrypt
string DataProtector dp = new DataProtector(DataProtector.Store.USE_MACHINE_STORE);
byte[] dataToDecrypt = Convert.FromBase64String(strEncryptedCnx);
strCnx = Encoding.ASCII.GetString(dp.Decrypt(dataToDecrypt,null));
} catch { strCnx=""; } return strCnx; } }
*Win32 Data Protection API (DPAPI) (System.Security.Cryptography)
35. Defense
Secrets must be secrets
EncryptByPassPhrase
DecryptByPassPhrase
DECLARE @plaintext nvarchar(1000), @enc_text
varbinary(2000)
SET @plaintext='Я помню чудное мгновенье'
SET
@enc_text=ENCRYPTBYPASSPHRASE('Krasnodar',@plaintext)
SELECT 'Оригинальный текст: ', @plaintext
SELECT 'Зашифрованный текст:', @enc_text
SELECT 'Расшифровка:',
CAST(DECRYPTBYPASSPHRASE('Krasnodar',@enc_text) as
nvarchar(1000))
38. Defense (conclusion)
Tell to the user only that he needs really to know
Check of all entered data
Use stored procedures
Use SQL parameters of safe types
Pack parameters by functions QUOTENAME()
and REPLACE()
Execute with Least Privilege
Secrets must be secrets
Defense on all layers