Под веб апликацијом сматрамо апликацију која се извршава на веб серверу и којој се приступа путем веб прегледача. Напади на веб апликације су чести, обзиром да су веб апликације доступне свим корисницима интернета – и легитимним и малициозним.
Напад убризгавањем SQL кода
У највећем броју случајева, веб апликација се извршава над базом података. Због тога, убризгавање SQL упита (енгл. SQL injection – SQLi) представља једну од често коришћених техника за компромитовање веб апликација. Наравно, овај напад може да буде једнако ефикасан над класичним десктоп апликацијама које се извршавају над базом података.
OR 1=1
Једноставан пример била би веб страница апликације за пријаву корисника, где се од корисника тражи да унесе корисничко име и лозинку. Део кода те веб странице могао би да изгледа овако:
uName = getRequestString("username");
uPass = getRequestString("userpassword");
sql = "SELECT * FROM Users WHERE Username='" + uName + "' AND Password='" + uPass + "'";
Уколико корисник petar.petrovic
унесе своју лозинку lozinka123
, извршиће се следећи упит над базом података:
SELECT * FROM Users WHERE Username='petar.petrovic' AND Password='lozinka123'
Међутим, малициозни корисник у пољима за корисничко име и лозинку може да унесе ' OR 1=1 --
, што ће довести до извршавања следећег упита над базом података:
SELECT * FROM Users WHERE Username='' OR 1=1 -- AND Password= ''
Овај упит је валидан са аспекта исправности кода и вратиће све редове из табеле Users јер ће усплов OR 1=1
увек бити испуњен.
Спајање упита
Анализирајмо следећи једноставан пример. Нека се на страници налази поље за претрагу производа веб продавнице. Део кода те веб странице могао би да изгледа овако:
txtProductName = getRequestString("pName");
sql = "SELECT * FROM Products WHERE ProductName= '" + txtProductName + "'";
Ако малициозни корисник унесе iPhone'; DROP TABLE Users --
, претражиће табелу Products па потом избрисати табелу Users.
SELECT * FROM Products WHERE ProductName= 'iPhone'; DROP TABLE Users --';
Слично, малициозни нападач може користити SQL команду за унију уносом iPhone' UNION DROP TABLE Users --
.
SELECT * FROM Products WHERE ProductName= 'iPhone' UNION DROP TABLE Users --'
Одбрана од SQLi напада
- валидација уноса (енгл. sanitization)
- коришћење филтера пакета за веб апликације (енгл. Web Application Firewall)
На пример, у ASP.NET апликацији могу се користити параметри:
txtUserId = getRequestString("UserId");
txtSQL = "SELECT * FROM Users WHERE UserId = @0";
db.Execute(txtSQL,txtUserId);
где је @0 параметар који не може да се третира као део SQL наредбе. Мало сложенији пример:
txtNam = getRequestString("CustomerName");
txtAdd = getRequestString("Address");
txtCit = getRequestString("City");
txtSQL = "INSERT INTO Customers (CustomerName,Address,City) Values(@0,@1,@2)";
db.Execute(txtSQL,txtNam,txtAdd,txtCit);
Конкретно, SELECT можемо реализовати овако:
txtUserId = getRequestString("UserId");
sql = "SELECT * FROM Customers WHERE CustomerId = @0";
command = new SqlCommand(sql);
command.Parameters.AddWithValue("@0",txtUserId);
command.ExecuteReader();
а INSERT овако:
txtNam = getRequestString("CustomerName");
txtAdd = getRequestString("Address");
txtCit = getRequestString("City");
txtSQL = "INSERT INTO Customers (CustomerName,Address,City) Values(@0,@1,@2)";
command = new SqlCommand(txtSQL);
command.Parameters.AddWithValue("@0",txtNam);
command.Parameters.AddWithValue("@1",txtAdd);
command.Parameters.AddWithValue("@2",txtCit);
command.ExecuteNonQuery();