What is SQL Injection? How to Prevent SQL Injection?
Structured Query Language (SQL) is the standard language used to query a database. (Note that a query performed in a search engine like Google or Bing is different.)
An SQL injection (SQLi) is a type of attack in which cyber criminals attempt to exploit vulnerabilities in an application’s code by inserting an SQL query into regular input or form fields, such as a username or password. The SQL statement is then passed to the application’s underlying SQL database.
SQL injection attacks are successful when the web-based entry form allows user-generated SQL statements to query the database directly. These attacks have also proliferated with the use of shared codebases, such as WordPress plugins, that contain a vulnerability in the underlying code pattern. This vulnerability is carried over to the entire application and can affect hundreds of thousands of websites that all use that shared code.
The damage can be vast. An attacker with a good knowledge of SQL enters queries on a web-based application with no input validation parameters in place, then easily accesses a company’s customer files or sensitive financial information.
Queries are used to find specific data based on criteria provided by the user. SQL is one of several languages that run the databases for applications, which can be built for internal use by an organization or published on the internet and available to the public. Aside from finding data, SLQ queries can perform calculations, summarize data, and automate tasks.
In-band SQLi
In-band SQLi is a common type of attack and is known for its simplicity and efficiency. This method has two variations: error-based and union-based.
Error-based SQLi
Attackers inject SQL queries hoping that the database will return error messages, which can give attackers information about the database and its structure.
UNION-based SQLi
In this scenario, attackers use the UNION SQL operator for the database to return a single Hypertext Transfer Protocol (HTTP) response. Attackers can then evaluate the response for clues about the contents of a database.
Inferential (Blind) SQLi
In inferential or blind SQLi attacks, fraudsters query the database and observe the server’s behavior to gather information about the database’s structure. These types of attacks are slower, but they can be equally harmful as other types of SQLi. There are two types: boolean and time-based.
Boolean
The attacker queries the database, and by studying whether the HTTP response was modified or stayed the same, they can determine whether the result was true or false.
Time-based
As its name implies, the attacker studies the response time, in seconds, of a query result. As with the boolean type, the attacker looks closely at the HTTP response to determine whether the query was true or false.
Out-of-band SQLi
This is a special SQLi case that can only work if certain features of the database server used by the application are turned on. Out-of-band SQLi is considered an alternative to in-band and inferential techniques. Out-of-band SQLi does not rely on the attacker querying the database to examine error messages or HTTP responses. Instead, it expects the server to generate Domain Name System (DNS) or HTTP requests so that the attacker can obtain data such as usernames and passwords.
An SQL injection manipulates a standard SQL query to exploit vulnerabilities in the application’s underlying database. Let us have a look at a few code examples to see how this works.
A typical SQL database query for an e-commerce application may look like the following:
SELECT ProductName, ProductDescription
FROM Products
WHERE ProductNumber = ProductNumber
If an attacker wants to access all of the product names and descriptions in the database—even those they are not allowed to access—the attacker will enter a Uniform Resource Locator (URL) similar to this in the on-screen web form: http://www.
SELECT ProductName, ProductDescription
FROM Products
WHERE ProductNumber = 999 OR 1=1
If an attacker wants to delete an entire database, they can take advantage of incorrectly filtered characters, inputting http://www.ecommercesite.com/products/products.asp?productid=999; DROP TABLE to generate the following SQL query:
SELECT ProductName, ProductDescription
FROM Products
WHERE ProductNumber = 999; DROP TABLE USERS
As a result, the entire user database can be dropped or deleted.
Sanitization
If attackers can input an unexpected query that the application accepts, then it makes sense to limit the input functionality to protect data. Developers can employ input validation, or sanitization, so the application only accepts certain inputs into form fields and reject those that do not conform. Web users are familiar with this practice. An example is when they are prompted to create a password that must be a certain number of characters long and includes at least one special character.
However, this is not an ideal solution because it is difficult to plan for all permissible input combinations. A substantial number of errors will result from users, who can be employees or customers. This can affect business operations significantly.
Filtering and Validation
To filter out SQLi and block potential threats, enterprises can install a web application firewall (WAF). A WAF matches the inputs to an application against a large list of known signatures to thwart malicious SQL queries. The list is updated and patched regularly so an organization can keep up with the evolving threat landscape.
Limiting the Scope of SQL Commands
Although filtering for SQLi is necessary, blocking 100% of SQL queries is not feasible. Employees, partners, or security industry experts may have to test the application and will need permission to do so. The WAF can cross-verify the input with Internet Protocol (IP) data before blocking the request.
Avoid Unsecured URL Parameters
If a website does not use Hypertext Transfer Protocol Secure (HTTPS), which leverages secure sockets layer/transport layer security (SSL/TLS) for encryption, an attacker can manipulate the session cookie with SQLi to gain access to the database. Organizations must secure their website and web application URLs to prevent this.
FortiWeb is the Fortinet WAF solution, which protects organizations from known and zero-day threats to their web applications. As applications continue to be updated with new features and accessed by new users, including through web application programming interfaces (APIs), the attack surface increases. FortiWeb is built to keep up with an organization’s applications as they change and evolve.
Machine-learning (ML) capabilities built into FortiWeb allow organizations to customize the protection for each application. Further, ML can identify and distinguish between benign and malicious anomalies to reduce business disruption resulting from false positives.
How to prevent SQL injection attacks?
Developers can employ input validation, or sanitization, so the application only accepts certain inputs into form fields and reject those that do not conform.
Why do hackers use SQL injection?
Hackers use SQL injection to gain unauthorized access to data—or information about that data—stored in a web application’s database.
Is SQL injection illegal?
For the most part, SQL injection is illegal, although this depends on jurisdictional boundaries.
How does SQL injection work?
An SQL injection (SQLi) is a type of attack in which cyber criminals attempt to exploit vulnerabilities in an application’s code by inserting an SQL query into regular input or form fields, such as a username or password.
Can SQL injection be traced?
An organization can use IP data to detect where the query was originally input, but the identity of the attacker cannot be confirmed by simply examining the SQL injection query alone.
Resources
Отчеты аналитиков
GuardMiner Cryptocurrency Miner Operation Disclosed
Threat Reports
Analyzing MSSQL brute-force post-exploitation
Проверка базы данных при атаках путем внедрения SQL
При использовании уязвимостей SQL-инъекций часто необходимо собрать некоторую информацию о самой базе данных. Это включает в себя тип и версию программного обеспечения базы данных, а также содержимое базы данных с точки зрения содержащихся в ней таблиц и столбцов.
Запрос типа и версии базы данных
Разные базы данных предоставляют разные способы запроса своей версии. Вам часто приходится пробовать разные запросы, чтобы найти работающий, позволяющий определить как тип, так и версию программного обеспечения базы данных.
Запросы для определения версии базы данных для некоторых популярных типов баз данных следующие:
Тип базы данных | Запрос |
Майкрософт, MySQL | ВЫБЕРИТЕ @@версию |
Оракул | ВЫБЕРИТЕ * ИЗ версии v$ |
PostgreSQL | ВЫБЕРИТЕ версию() |
Например, вы можете использовать атаку UNION
со следующими входными данными:
' ОБЪЕДИНЕНИЕ ВЫБЕРИТЕ @@версия--
Это может вернуть вывод, подобный следующему, подтверждающий, что база данных является Microsoft SQL Server, и используемую версию:
Microsoft SQL Server 2016 (SP2) (KB4052908) — 13. 0.5026.0 (X64)
18 мар 2018 09:11:49
Авторское право (c) Корпорация Microsoft
Standard Edition (64-разрядная версия) в Windows Server 2016 Standard 10.0
ЛАБОРАТОРИЯ
ПРАКТИК Атака с внедрением SQL, запрос типа и версии базы данных на Oracle
ЛАБОРАТОРИЯ
ПРАКТИК Атака с внедрением SQL, запрос типа и версии базы данных на MySQL и Microsoft
Список содержимого базы данных
Большинство типов баз данных (за заметным исключением Oracle) имеют набор представлений, называемых информационной схемой, которые предоставляют информацию о базе данных.
Вы можете запросить information_schema.tables
, чтобы получить список таблиц в базе данных:
SELECT * FROM information_schema.tables
Это возвращает вывод, подобный следующему:
ТАБЛИЦА_КАТАЛОГ ТАБЛИЦА_СХЕМА ТАБЛИЦА_ИМЯ ТАБЛИЦА_ТИП
================================================== ===
MyDatabase dbo Продукты БАЗОВАЯ ТАБЛИЦА
БАЗОВАЯ ТАБЛИЦА пользователей MyDatabase dbo
Обратная связь MyDatabase dbo БАЗОВАЯ ТАБЛИЦА
Эти выходные данные указывают на наличие трех таблиц с именами Products
, Users
и Feedback
.
Затем вы можете запросить information_schema.columns
, чтобы получить список столбцов в отдельных таблицах:
SELECT * FROM information_schema.columns WHERE table_name = 'Пользователи'
Это возвращает вывод, подобный следующему:
TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME DATA_TYPE
================================================== ===============
MyDatabase dbo Пользователи UserId int
MyDatabase dbo Users Имя пользователя varchar
Пароль пользователей MyDatabase dbo varchar
Эти выходные данные показывают столбцы в указанной таблице и тип данных каждого столбца.
ЛАБОРАТОРИЯ
ПРАКТИК Атака с внедрением SQL, перечисление содержимого базы данных в базах данных, отличных от Oracle
Эквивалент информационной схемы в Oracle
В Oracle вы можете получить ту же информацию с помощью немного разных запросов.
Вы можете получить список таблиц, запросив все_таблицы
:
ВЫБРАТЬ * ИЗ всех_таблиц
И вы можете перечислить столбцы, запросив all_tab_columns
:
SELECT * FROM all_tab_columns WHERE table_name = 'USERS'
ЛАБОРАТОРИЯ
ПРАКТИК Атака с внедрением SQL, перечисление содержимого базы данных в Oracle
Что такое внедрение SQL (SQLi) и как предотвратить атаки
Внедрение SQL (SQLi) — это тип атаки путем внедрения, который позволяет выполнять вредоносные операторы SQL. Эти операторы управляют сервером базы данных за веб-приложением. Злоумышленники могут использовать уязвимости SQL Injection для обхода мер безопасности приложений. Они могут обойти аутентификацию и авторизацию веб-страницы или веб-приложения и получить содержимое всей базы данных SQL. Они также могут использовать SQL Injection для добавления, изменения и удаления записей в базе данных.
Уязвимость SQL Injection может затронуть любой веб-сайт или веб-приложение, использующее базу данных SQL, такую как MySQL, Oracle, SQL Server или другие. Преступники могут использовать его для получения несанкционированного доступа к вашим конфиденциальным данным: информация о клиентах, персональные данные, коммерческая тайна, интеллектуальная собственность и многое другое. Атаки SQL Injection — одна из старейших, наиболее распространенных и наиболее опасных уязвимостей веб-приложений. Организация OWASP (Open Web Application Security Project) перечисляет инъекции в своем документе OWASP Top 10 2017 как угрозу номер один для безопасности веб-приложений.
Как и почему выполняется атака путем внедрения SQL-кода
Чтобы осуществить атаку путем внедрения кода SQL, злоумышленник должен сначала найти уязвимые пользовательские данные на веб-странице или в веб-приложении. Веб-страница или веб-приложение, содержащее уязвимость SQL Injection, использует такой пользовательский ввод непосредственно в SQL-запросе. Злоумышленник может создать входной контент. Такой контент часто называют вредоносной полезной нагрузкой, и он является ключевой частью атаки. После того, как злоумышленник отправляет этот контент, в базе данных выполняются вредоносные SQL-команды.
SQL — это язык запросов, разработанный для управления данными, хранящимися в реляционных базах данных. Вы можете использовать его для доступа, изменения и удаления данных. Многие веб-приложения и веб-сайты хранят все данные в базах данных SQL. В некоторых случаях вы также можете использовать команды SQL для запуска команд операционной системы. Поэтому успешная атака SQL Injection может иметь очень серьезные последствия.
- Злоумышленники могут использовать SQL-инъекции для поиска учетных данных других пользователей в базе данных. Затем они могут выдавать себя за этих пользователей. Олицетворенный пользователь может быть администратором базы данных со всеми привилегиями базы данных.
- SQL позволяет выбирать и выводить данные из базы данных. Уязвимость SQL Injection может позволить злоумышленнику получить полный доступ ко всем данным на сервере базы данных.
- SQL также позволяет изменять данные в базе данных и добавлять новые данные. Например, в финансовом приложении злоумышленник может использовать SQL Injection для изменения баланса, аннулирования транзакций или перевода денег на свой счет.
- Вы можете использовать SQL для удаления записей из базы данных, даже для удаления таблиц. Даже если администратор создает резервные копии базы данных, удаление данных может повлиять на доступность приложения до тех пор, пока база данных не будет восстановлена. Кроме того, резервные копии могут не охватывать самые последние данные.
- На некоторых серверах баз данных вы можете получить доступ к операционной системе с помощью сервера баз данных. Это может быть преднамеренным или случайным. В таком случае злоумышленник может использовать SQL-инъекцию в качестве начального вектора, а затем атаковать внутреннюю сеть за брандмауэром.
Существует несколько типов атак SQL Injection: внутриполосный SQLi (с использованием ошибок базы данных или команд UNION), слепой SQLi и внеполосный SQLi. Подробнее о них можно прочитать в следующих статьях: Типы SQL-инъекций (SQLi), Слепые SQL-инъекции: что это такое.
Пошаговое описание того, как выполняется атака путем внедрения SQL-кода и какие серьезные последствия она может иметь, см. в статье Использование внедрения кода SQL: практический пример.
Пример простой SQL-инъекции
Первый пример очень прост. Он показывает, как злоумышленник может использовать уязвимость SQL Injection, чтобы обойти безопасность приложения и аутентифицироваться как администратор.
Следующий сценарий представляет собой псевдокод, выполняемый на веб-сервере. Это простой пример аутентификации с помощью имени пользователя и пароля. В примере базы данных есть таблица с именем 9.0021 пользователей со следующими столбцами: имя пользователя
и пароль
.
# Определение переменных POST uname = запрос.POST['имя пользователя'] пароль = запрос.POST['пароль'] # SQL-запрос уязвим для SQLi sql = «ВЫБЕРИТЕ идентификатор ОТ пользователей, ГДЕ имя пользователя = '» + uname + «’ И пароль = ’» + пароль + «’» # Выполнить оператор SQL database.execute(sql)
Эти поля ввода уязвимы для внедрения SQL. Злоумышленник может использовать команды SQL во входных данных таким образом, чтобы изменить оператор SQL, выполняемый сервером базы данных. Например, они могут использовать трюк с одинарной кавычкой и установить число 9.0021 passwd field to:
password' ИЛИ 1=1
В результате сервер базы данных выполняет следующий запрос SQL:
SELECT id FROM users WHERE username='username' AND password= 'password' ИЛИ 1 =1 '
Из-за оператора OR 1=1
предложение WHERE
возвращает первый идентификатор
из таблицы пользователей
, независимо от того, что такое имя пользователя
и пароль
2. Первый пользователь id
в базе данных очень часто является админом. Таким образом злоумышленник не только обходит аутентификацию, но и получает права администратора. Они также могут закомментировать остальную часть инструкции SQL, чтобы в дальнейшем управлять выполнением SQL-запроса:
-- MySQL, MSSQL, Oracle, PostgreSQL, SQLite. ИЛИ '1'='1' -- ' ИЛИ '1'='1' /* -- MySQL ИЛИ '1'='1' # -- Доступ (с использованием нулевых символов) ИЛИ '1'='1' %00 ' OR '1'='1' %16
Пример SQL-внедрения на основе объединения
Один из наиболее распространенных типов SQL-внедрения использует оператор UNION. Это позволяет злоумышленнику объединить результаты двух или более операторов SELECT в один результат. Этот метод называется SQL-инъекцией на основе union .
Ниже приведен пример этой техники. Он использует веб-страницу testphp.vulnweb. com , намеренно уязвимый веб-сайт, размещенный Acunetix.
Следующий HTTP-запрос является обычным запросом, который должен отправить законный пользователь:
GET http://testphp.vulnweb.com/artists.php?artist= 1 HTTP/1.1 Хост: testphp.vulnweb.com
Параметр artist
уязвим для внедрения SQL. Следующая полезная нагрузка изменяет запрос для поиска несуществующей записи. Он устанавливает значение в строке запроса URL -1
. Конечно, это может быть любое другое значение, которого нет в базе данных. Однако отрицательное значение является хорошим предположением, потому что идентификатор в базе данных редко является отрицательным числом.
В SQL Injection оператор UNION
обычно используется для присоединения вредоносного SQL-запроса к исходному запросу, предназначенному для выполнения веб-приложением. Результат введенного запроса будет объединен с результатом исходного запроса. Это позволяет злоумышленнику получать значения столбцов из других таблиц.
GET http://testphp.vulnweb.com/artists.php?artist= -1 UNION SELECT 1, 2, 3 HTTP/1.1 Хост: testphp.vulnweb.com
В следующем примере показано, как можно использовать полезную нагрузку SQL Injection для получения более значимых данных с этого намеренно уязвимого сайта:
ПОЛУЧИТЬ http://testphp.vulnweb.com/artists.php?artist= -1 UNION SELECT 1,pass,cc ОТ пользователей, ГДЕ uname='test' HTTP/1.1 Хост: testphp.vulnweb.com
Как предотвратить SQL-инъекцию
Единственный надежный способ предотвратить атаки с помощью SQL-инъекции — проверка входных данных и параметризованные запросы, включая подготовленные операторы. Код приложения никогда не должен использовать ввод напрямую. Разработчик должен дезинфицировать все входные данные, а не только входные данные веб-форм, такие как формы входа. Они должны удалять элементы потенциально вредоносного кода, такие как одинарные кавычки. Также рекомендуется отключить видимость ошибок баз данных на рабочих сайтах. Ошибки базы данных можно использовать с SQL Injection для получения информации о вашей базе данных.
Если вы обнаружите уязвимость SQL Injection, например, с помощью сканирования Acunetix, возможно, вы не сможете исправить ее немедленно. Например, уязвимость может быть в открытом коде. В таких случаях вы можете использовать брандмауэр веб-приложения для временной очистки ввода.
Чтобы узнать, как предотвратить атаки SQL-инъекций на языке PHP, см. Предотвращение уязвимостей SQL-инъекций в приложениях PHP и их устранение. Чтобы узнать, как это сделать во многих других языках программирования, обратитесь к руководству Bobby Tables по предотвращению SQL-инъекций.
Дополнительная литература
Руководство по предотвращению SQL-инъекций
Часто задаваемые вопросы
Что такое SQL-инъекция?
SQL Injection — это веб-уязвимость, вызванная ошибками, допущенными программистами. Это позволяет злоумышленнику отправлять команды в базу данных, с которой взаимодействует веб-сайт или веб-приложение. Это, в свою очередь, позволяет злоумышленнику получить данные из базы данных или даже изменить их.
Посмотрите пошаговый пример того, как происходят SQL-инъекции.
Насколько распространены SQL-инъекции?
Внедрение SQL — очень старая уязвимость. Она была обнаружена в 1998 году. Однако, согласно нашему исследованию 2020 года, 8 процентов веб-сайтов и веб-приложений имеют уязвимости, связанные с внедрением SQL.
Прочитайте наш полный отчет о текущем состоянии веб-безопасности.
Насколько опасны SQL-инъекции?
Успешная атака SQL Injection может привести к полной компрометации системы или краже всей базы данных. Например, атака SQL Injection в 2019 году привела к краже полных налоговых данных 5 миллионов человек.