SQL инжекции

Така наречените "SQL инжекции" са вид атака срещу приложение, което използва недостатъци на сигурността в базата данни. В този урок ще видим примери за SQL инжекции. Този урок се основава на статията на Steve Friedl SQL Injection Attacks by Example, която препоръчвам да прочетете, или измамническия лист на SQL инжекцията. Разбира се, целта на този урок е да повиши информираността за необходимостта от защита на всяко уеб приложение от този тип атака.

Примерно приложение

Ще използваме като пример приложение, подобно на това в упражненията Бази данни 1.

  • Това приложение има меню с три опции:
    • Изтрийте всичко, да изтриете и създадете потребителската таблица, която съдържа само две полета (име и парола на потребителя).
    • Добавете потребители, за да добавите потребителски имена и техните пароли в потребителската таблица.
    • Влезте в системата, което симулира страница за вход в уеб приложение, изискващо потребителско име и парола, проверка дали е в таблицата на потребителите и отговор
      • потребителското име и паролата са правилни.
      • потребителското име е правилно, но паролата не е правилна.
      • потребителското име не е правилно.
  • Това приложение е уязвимо за някои SQL инжекционни атаки, тъй като данните, изпратени от потребителя, са включени в заявките към базата данни без предварително третиране.
  • Това приложение не е уязвимо за всички атаки на SQL инжектиране, обсъдени в този урок, защото използва разширението PDO. Ако искате да тествате подобно приложение, уязвимо за всички атаки, обсъдени в този урок, на вашия компютър, можете да изтеглите този файл (injection_sql_2.zip) и да го тествате на компютъра си.

SQL Injection 1 - Достъп до приложението без потребителско име или парола

Когато потребителят въведе потребителско име и парола, приложението отговаря на едно от трите съобщения:

За да влезете в системата, въведете потребителското си име и парола:

Потребител:
Парола:

Правилно потребителско име и парола.

Неправилно потребителско име.

За да проверим дали приложението включва данните, изпратени от потребителя без предварително третиране, можем да изпратим оферта (единична или двойна) като данни.

За да влезете в системата, въведете вашето потребителско име и парола:

Потребител:
Парола:

Неправилно потребителско име.

За да влезете в системата, въведете вашето потребителско име и парола:

Потребител:
Парола:

Грешка в заявката.

Това последно съобщение („Грешка в заявката“) ни уведомява, че данните не се обработват и че заявките също са разграничени с двойни кавички. Защо?

Вероятно кодът на приложението ви изглежда по следния начин:

Като поставите двойна кавичка в началото на потребителското име, заявката става

Тази заявка е правилна (не съдържа синтаксични грешки) и при изпълнение на базата данни просто връща 0.

Въвеждането на единична кавичка в началото на потребителското име обаче превръща заявката в

Тази заявка не е правилна (съдържа синтаксична грешка поради кавичката вътре в кавичките на втория ред и когато се изпълни, базата данни дава грешка.

Сега, след като знаем, че заявката е разделена с двойни кавички, можем да напишем някои данни, които ще модифицират заявката и ще накарат приложението да повярва, че сме въвели данни от регистриран потребител.

За да влезете в системата, въведете вашето потребителско име и парола:

Потребител:
Парола:

Правилно потребителско име и парола.

В този случай заявката за база данни ще бъде нещо подобно:

Тази заявка е правилна и когато се изпълни, базата данни връща общия брой записи в таблицата, тъй като условието винаги е изпълнено, дори ако потребителското име и паролата са неправилни, тъй като крайното условие ИЛИ '1' = '1 винаги е вярно.

SQL инжекция 2 - Разберете името на полетата

Имената на полетата могат да бъдат открити чрез проби и грешки. Идеята е да се въведат данни, които изграждат заявки, в които се появяват възможни имена на полетата. В случай че заявките дават грешка, това означава, че името е неправилно, ако не, това означава, че сме получили правилно името на полетата.

Например ще тестваме дали името на едно от полетата е „потребител“.