Вы находитесь на странице: 1из 47

SOFTWARE FOR BUSINESS

«SQL-запросы и SQL-
инъекции» Приготовил QA Engineer: Зязюля Прохор
Введение
SQL является прежде всего информационно-логическим языком, предназначенным
для описания, изменения и извлечения данных, хранимых в реляционных базах
данных. SQL можно назвать языком программирования, при этом он не является
тьюринг-полным, но вместе с тем стандарт языка спецификацией SQL/PSM
предусматривает возможность его процедурных расширений.

Изначально SQL был основным способом работы пользователя с базой данных и позволял выполнять следующий набор
операций:
создание в базе данных новой таблицы;
добавление в таблицу новых записей;
изменение записей;
удаление записей;
выборка записей из одной или нескольких таблиц (в соответствии с заданным условием);
изменение структур таблиц.
Со временем SQL усложнился — обогатился новыми конструкциями, обеспечил возможность описания и управления новыми
хранимыми объектами (например, индексы, представления, триггеры и хранимые процедуры) — и стал приобретать черты,
свойственные языкам программирования.
При всех своих изменениях SQL остаётся единственным механизмом связи между прикладным программным обеспечением и
базой данных. В то же время современные СУБД, а также информационные системы, использующие СУБД, предоставляют
пользователю развитые средства визуального построения запросов.
Достоинства

SQL вобрал в себя достоинства реляционной модели, в


частности, достоинства лежащего в ее основе
математического аппарата реляционной алгебры и
реляционного исчисления, используя при этом
сравнительно небольшое число операторов и относительно
простой синтаксис.

Учитывая место, занимаемое SQL в современных


информационных технологиях, его знание необходимо
любому специалисту, работающему в этой области.
Отличия

SQL относится к классу непроцедурных языков программирования.


SQL ориентирован не на записи, а на множества.
Это означает следующее: в качестве входной информации для формулируемого
на языке SQL запроса к базе данных используется множество кортежей-записей
одной или нескольких таблиц-отношений. В результате выполнения запроса
также образуется множество кортежей результирующей таблицы-отношения.
В SQL результатом любой операции над отношениями также является
отношение.

Запрос SQL задает не процедуру, а условие, которым должны удовлетворять


кортежи результирующего отношения, сформулированные в терминах
входного (или выходных) отношения (й).
Принцип работы

Рассмотрим, как работает SQL. Предположим, что


имеется база данных, управляемая с помощью какой-либо
СУБД. Для извлечения из нее данных используется запрос,
сформулированный на языке SQL. СУБД обрабатывает
этот запрос, извлекает запрашиваемые данные и
возвращает их. Этот процесс схематически изображен на
рисунке.
SQL позволяет не только извлекать данные, но и
определять структуру данных, добавлять и удалять данные,
ограничивать или предоставлять доступ к данным,
поддерживать ссылочную целостность.

Обратите внимание на то, что SQL сам по себе не является ни СУБД, ни отдельным
продуктом. Это язык, применяемый для взаимодействия с СУБД и являющийся в
определенном смысле ее неотъемлемой частью.
Интерактивный и встроенный SQL

Существуют и используются две формы языка SQL:


Интерактивный SQL используется для задания SQL-запросов пользователем и
получения результата в интерактивном режиме;
Встроенный SQL состоит из команд SQL, встроенных внутрь программ, обычно
написанных на каком-то другом языке (Паскаль, С, C++ и др.).

Встроенный SQL делает программы более мощными, гибкими и эффективными,


обеспечивая их применение для работы с данными, хранящимися в реляционных базах.
При этом, однако, требуются дополнительные средства интерфейса SQL с языком, в
который он встраивается.
Составные части SQL

И интерактивный, и встроенный SQL подразделяются на следующие составные части:


Язык определения данных — DDL (Data Definition Language) — дает возможность
создания, изменения и удаления различных объектов базы данных (таблиц, индексов,
пользователей, привилегий и т.д.).
В число дополнительных функций DDL могут быть включены и средства
ограничения целостности данных, определения порядка структур их хранения,
описания элементов физического уровня хранения данных.
Язык обработки данных — DML (Data Manipulation Language) — предоставляет
возможность выборки информации из базы данных и ее преобразования.

Тем не менее, это не два различных языка, а компоненты


единого SQL.
Операторы SQL

Все операторы SQL имеют вид, представленный на


рисунке.
Каждый оператор SQL начинается с глагола,
представляющего собой ключевое слово, определяющее, что
именно делает этот оператор (SELECT, INSERT,
DELETE...).
В операторе также содержатся предложения, содержащие
сведения о том, над какими данными производятся
операции.
Каждое предложение начинается с ключевого слова,
такого как FROM, WHERE и др. Структура предложения
зависит от его типа - ряд предложений содержит имена
таблиц или полей, некоторые могут содержать
дополнительные ключевые слова, константы или
выражения.
Операторы DDL Операторы DDL (Data Definition Language)

CREATE DATABASE – создать базу данных; Операторы определения объектов базы данных содержат операторы,
ALTER DATABASE – изменить базу данных; позволяющие создавать, изменять и уничтожать базы данных и
DROP DATABASE – удалить базу данных; объекты внутри них (таблицы, представления и др.).
CREATE SCHEMA – создать схему базы данных;
DROP SСHEMA – удалить схему базы
данных;
CREATE INDEX – создать индекс для данного поля;
DROP INDEX – удалить существующий
индекс;
CREATE TABLE – создать таблицу;
ALTER TABLE – изменить
таблицу;
DROP TABLE – удалить таблицу;
CREATE DOMAIN – создать домен;
ALTER DOMAIN – изменить домен;
DROP DOMAIN – удалить домен;
CREATE COLLATION – создать
последовательность;
DROP COLLATION – удалить
последовательность;
CREATE VIEW – создать
представление;
DROP VIEW – удалить
представление;
CREATE TRIGGER – создать
триггер;
ALTER TRIGGER – изменить
триггер;
DROP TRIGGER – удалить триггер.
Операторы DDL. CREATE DATABASE.

Синтаксис оператора CREATE DATABASE (создание базы данных):


CREATE DATABASE [IF NOT EXISTS] db_name [CHARACTER SET charset] [COLLATE collation];

db_name - имя, которое будет присвоено создаваемой базе данных.

IF NOT EXISTS - если не указать этот параметр, то при попытке создания базы данных с уже существующим именем, возникнет ошибка выполнения команды.

CHARACTER SET - используется для задания стандартной кодировки таблицы и порядка сортировки.
Если при создании таблицы эти параметры не указываются, то кодировка и порядок сортировки вновь создаваемой таблицы берутся из значений,
указанных для всей базы данных. Если задан параметр CHARACTER SET, но не задан параметр COLLATE, то используется стандартный порядок сортировки. Если
задан параметр COLLATE, но не задан CHARACTER SET, то кодировку определяет первая часть имени порядка сортировки в COLLATE.
Кодировка, заданная в CHARACTER SET, должна поддерживаться сервером (latin1 или sjis), а порядок сортировки должен быть допустимым для текущей
кодировки.
Примеры использования CREATE DATABASE:
Следующий пример создает базу данных "my_db":
CREATE DATABASE `my_db` или CREATE DATABASE `my_db` CHARACTER SET utf8 COLLATE utf8_general_ci;

При создании новой базы данных следует придерживаться некоторых правил относительно имени базы данных:
Максимальная длина имени не должна превышать 64 символов.
Разрешены любые символы, которые допускаются в имени каталога, за исключением / (слеш) и . (точка). Но следует принять во внимание, что нельзя
использовать символы ASCII(0) и ASCII(255).
Операторы DDL. ALTER DATABASE.

Оператор ALTER DATABASE используется для изменения характеристик базы данных. После создания базы данных мы можем изменить ее свойства,
используя оператор ALTER DATABASE. Пользователь должен иметь права администратора для изменения базы данных.
Синтаксис оператора ALTER DATABASE:
ALTER DATABASE database_name [COLLATE collation_name ]

database_name - имя базы данных, которую мы хотим изменить.


-collation_name- - сортировка по умолчанию для базы данных.
collation_name - необязательное поле, и если не указано значение по умолчанию, для базы данных назначается сортировка по умолчанию.

Примеры использования ALTER DATABASE:


Задаем кодировку как utf8 для базы данных `test`:
ALTER DATABASE `test` DEFAULT CHARACTER SET utf8;

Ответ (Выполнено успешно): Query OK, 1 row affected (0.02


sec)
Задаем кодировку utf8, не указывая базу данных:
ALTER DATABASE DEFAULT CHARACTER SET utf8;

Ответ (Ошибка): ERROR 1046 (3D000): No database selected)

Выбираем базу данных `test` базой по умолчанию и задаем для базы по умолчанию кодировку utf8:


1. USE `test`;
2. ALTER DATABASE DEFAULT CHARACTER SET utf8;

Ответ (Выполнено успешно): Query OK, 1 row affected (0.02


sec)
Операторы DDL. DROP DATABASE.

Для удаления базы данных используется оператор DROP DATABASE.

Синтаксис оператора DROP DATABASE:


DROP DATABASE [IF EXISTS] db_name

db_name - задает имя базы данных, которую необходимо удалить.


IF EXISTS - если не указать этот параметр, то при попытке удаления несуществующей базы данных, возникнет ошибка выполнения команды.
При выполнении команды DROP DATABASE удаляется как сама база данных, так и все таблицы, которые в ней находятся.
Если производится удаление базы данных, которая символически связана с другой базой данных, то удалиться как сама ссылка, так и оригинальная
база данных.
Примеры использования DROP DATABASE:
В следующем примере мы удалим базу данных db_test:

DROP DATABASE `db_test`

DROP TABLE - данный запрос используется для удаления таблиц.


DROP TABLE table_name
table_name – имя таблицы в базе данных.
Операторы DDL. CREATE INDEX.

CREATE INDEX  – данный запрос используется для создания индексов в таблице. Индексы позволяют быстрее находить нужные данные без чтения всей
таблицы данных. Пользователь не может увидеть индексы, они просто используются для ускорения поиска/запроса.
Синтаксис CREATE INDEX.
Создания индекса в таблице. Повторяющиеся значения допускаются:
CREATE INDEX index_name ON table_name (column_name)

index_name – имя индекса.


table_name – имя таблицы в базе данных.
column_name – имя столбца из базы данных.

Примеры использования CREATE INDEX:


SQL запрос создает индекс с именем "PIndex" в столбце "LastName" таблице "Persons":
1.CREATE INDEX Pindex
2.ON Persons (LastName)

Если вы хотите создать комбинированный индекс, то можно перечислить имена столбцов в скобках через запятую:
1.CREATE INDEX Pindex
2.ON Persons (LastName, FirstName)

Обновления таблицы с индексами занимает большее время, чем обновления таблицы без индексов (потому что индексы тоже
нуждаются в обновлении). Итак, рекомендуется создавать только один индекс на таблицу (один столбец), в котором будет часто
производится поиск.
Операторы DDL. DROP INDEX.

DROP INDEX - данный запрос используется для удаления индексов в таблице. Индексы, таблицы и базы данных могут быть легко удалены с помощью запроса
DROP.
Синтаксис DROP INDEX.
Синтаксис DROP INDEX для MS Access:
DROP INDEX index_name ON table_name

Синтаксис DROP INDEX для MS SQL Server:


DROP INDEX table_name.index_name

Синтаксис DROP INDEX для DB2/Oracle:


DROP INDEX index_name

Синтаксис DROP INDEX для MySQL:


ALTER TABLE table_name DROP INDEX index_name

index_name – имя индекса.


table_name – имя таблицы в базе данных.

TRUNCATE TABLE  - данный запрос используется для  удаления данных внутри таблицы, не трогая саму
таблицу. TRUNCATE TABLE table_name

Обновления таблицы с индексами занимает большее время, чем обновления таблицы без  индексов (потому что индексы тоже
нуждаются в обновлении). Итак, рекомендуется создавать только один индекс на таблицу (один столбец), в котором будет часто
производится поиск.
Операторы DDL. CREATE TABLE

CREATE TABLE  -  данный запрос используется для создания таблицы в базе данных.
Синтаксис CREATE TABLE:
1. CREATE TABLE table_name (
2. column_name1 data_type,
3. column_name2 data_type,
4. column_name3 data_type,
5. ....
6. )

table_name – имя таблицы в базе данных.


column_name – имя столбца.
data_type – определяет, к какому типу данных относится столбец.

Примеры использования CREATE TABLE:


Создадим таблицу под названием "Persons", который состоит из пяти столбцов: P_Id, LastName, FirstName, Address и City.
Для этого используем такой запрос:
1. CREATE TABLE Persons (
2. P_Id int,
3. LastName varchar(255),
4. FirstName varchar(255),
5. Address varchar(255)
6. City varchar(255)
7. )

Столбец P_Id имеет тип INT. LastName, FirstName, Address и City имеют тип VARCHAR с максимальной длиной
255 символов.
Операторы DDL. ALTER TABLE.

ALTER TABLE - данный запрос используется для добавления, удаления или модификации столбца в уже существующей таблице.
Синтаксис ALTER TABLE:
Для добавления столбца в таблицу, используйте следующий синтаксис:
1. ALTER TABLE table_name
2. ADD column_name datatype

Для удаления столбца в таблице, используйте следующий синтаксис (не все базы данных позволяют удалять один
столбец):
1. ALTER TABLE table_name
2. DROP COLUMN column_name

Для изменения типа данных столбца, используйте следующий синтаксис:


1. ALTER TABLE table_name
2. ALTER COLUMN column_name datatype

Примеры использования CREATE TABLE:


Добавим новый столбец с именем "DateOfBirth" в таблицу "Persons":
1. ALTER TABLE Persons
2. ADD DateOfBirth date

Изменим тип данных столбца "DateOfBirth" в таблице "Persons": table_name – имя таблицы в базе данных.
1. ALTER TABLE Persons
2. ALTER COLUMN DateOfBirth year column_name – имя столбца.
data_type – определяет, к какому типу данных относится столбец.
Удалим столбец "DateOfBirth" из таблицы "Persons":
1. ALTER TABLE Persons
2. DROP COLUMN DateOfBirth
Операторы DDL. CREATE TRIGGER.

CREATE TRIGGER - данный запрос используется для создания триггера.


Триггер — это хранимая процедура, которая не вызывается непосредственно, а исполняется при наступлении определенного события ( вставка, удаление,
обновление строки ).
Синтаксис CREATE TRIGGER:
1. CREATE TRIGGER trigger_name trigger_time trigger_event
2. ON tbl_name FOR EACH ROW trigger_stmt* This source code was highlighted with Source Code Highlighter.

trigger_name –  название триггера.


trigger_time – время срабатывания триггера.
BEFORE — перед событием. AFTER — после события.
trigger_event — событие:
insert — событие возбуждается операторами insert, data load, replace;
update — событие возбуждается оператором update;
delete — событие возбуждается операторами delete, replace.
Операторы DROP TABLE и TRUNCATE не активируют выполнение триггера.
tbl_name — название таблицы.
trigger_stmt — выражение, которое выполняется при активации триггера.

Примеры использования CREATE TRIGGER :


1. CREATE TRIGGER `update_test` AFTER INSERT ON `test`
2. FOR EACH ROW BEGIN INSERT INTO log Set msg = 'insert', row_id = NEW.id;
3. END;* This source code was highlighted with Source Code Highlighter.

Примеры использования DROP TRIGGER :


1. DROP TRIGGER `update_test`;
Операторы DML Операторы DML (Data Manipulation Language)

Операторы манипулирования данными содержат операторы,


SELECT – отобрать строки из позволяющие выбирать, добавлять, удалять и модифицировать
таблицы; данные. Обратите внимание на то, что эти операторы не обязаны
INSERT – добавить строки в
таблицу; завершать транзакцию, внутри которой они вызваны.
UPDATE – изменить строки в таблице;
DELETE – удалить строки в
таблице.

Иногда оператор SELECT относят к


отдельной категории, называемой Data
Query Language (DQL).
Операторы DML. SELECT.

SELECT -  оператор языка SQL, возвращающий набор данных (выборку) из базы.


Синтаксис SELECT:
1. SELECT column_name(s) 1. SELECT *
2. FROM table_name И 2. FROM table_name

table_name – имя таблицы в базе данных.


column_name – имя столбца из базы данных.
Замечание: SQL не чувствителен к регистру.
Примеры использования SELECT:
Есть таблица "Persons":

Сделаем выборку столбцов "LastName"и "FirstName": SELECT LastName,FirstName FROM Persons

Теперь выберем все значения из таблицы "Persons": SELECT * FROM Persons

Подсказка: Звездочка (*)
представляет собой самый
быстрый способ выбора всей
колонки!
Оператор SELECT

1. SELECT [ALL | DISTINCT | DISTINCTROW | TOP] { * | table.* |


2. [table.] field1 [AS alias1 [, [table.] field2 [AS alias2] [, ...]]}
3. FROM table1 [table1Aias] [, table2 [table2Alias]] [, ...] [IN externaldatabase]
4. [WHERE criteria]
5. [GROUP BY groupfieldlist]
6. [HAVING groupcriteria]
7. [ORDER BY field1 [ASC | DESC ][, field2 [ASC | DESC ]][, ...]]]
8. [WITH OWNERACCESS OPTION]

Список { * | table.* |[table.]field1 [AS alias1] [, Предикаты:


[table.]field2 [AS ali-as2] [, …]]} (фигурные ALL – указывает, что в набор передаются все строки (даже с дублируемыми
скобки здесь обозначают список) состоит из имен полей значениями);
таблиц(ы) запроса. Звездочка (*) означает выбор всех DISTINCT – указывает, что в набор передаются только недублированные строки;
полей таблицы. Если в запросе указывается несколько DISTINCTROW – указывает, что в результирующий набор будет включена каждая
таблиц, то для определения поля используется строка, в которой есть отличие в значении любого из полей исходных таблиц (а не
наименование таблицы, отделяемое от имени поля только полей, указанных для отображения в операторе SELECT);
точкой (.). Поле может получать «алиасное» имя при TOP – используется для отображения некоторого количества (точного или в
помощи ключевого слова AS. процентном отношении) начальных или конечных записей из результирующего
После слова FROM указываются таблицы, из которых набора.
выбираются ранее указанные поля. Здесь tablel1
(,table2) — это имя таблицы (или таблиц),
содержащей данные, externaldatabase — имя базы
данных, если не ис-пользуется текущая база.
Оператор SELECT
Ключевое слово WHERE в синтаксисе инструкции SELECT позволяет указывать определенные типы записей, которые должны попадать в набор. При этой
инструкция SELECT имеет следующий синтаксис:
1. SELECT { * | field1 [AS alias1] [,field2 [AS alias2]]}
2. FROM table
3. [WHERE criteria]

Например, можно запросить только те товары, цены которых не более 100 денежных единиц:
1. SELECT НаимТовара as [Наименование товара], Цена1 as [Цена закупочная]
2. FROM Товары
3. WHERE Цена < 100

Для сортировки данных в инструкции SELECT имеются слова ORDER BY:


1. SELECT { * | [table.]field1 [AS alias1] [, [table.]field2 [AS alias2] [, -..]]}
2. FROM table1 [table1Alias] [, table2 [table2Alias]] [, ...]
3. [WHERE criteria]
4. [ORDER BY field1 [ASC | DESC ][, field2 [ASC | DESC ]][, ...]]]

Здесь к тем элементам SQL-запроса, которые уже рассмотрены, добавлено необязательное предложение ORDER BY. Как следует из синтаксиса инструкции
SELECT, используя слова ASC и DESC, можно изменять «направление» сортировки («по возрастанию» и «по убыванию» соответственно). Сортировать можно по
нескольким полям (сначала по одному, затем — по другому, и так далее) и даже по различным элементам одного и того же поля с использованием функций.
В следующем примере используется сортировка выводимого набора по наименованиям:
1. SELECT a.НаимТовара AS [Наименование товара], b.Количество AS [Количество]
2. FROM Товары а, Запасы b
3. WHERE а.КодТовара = b.КодТовара AND b.КодПодразделения='0429'
4. ORDER BY а.НаимТовара
Оператор SELECT
В инструкции SELECT для объединения значений в группы используется конструкция GROUP BY.
Следующий пример имеет результатом список складов и суммарные количества товаров на каждом складе:
1. SELECT с.НаимПодразделения, SUM(b.Количество) AS Количество
2. FROM Запасы b, Подразделения c
3. WHERE b.КодПодразделения = с.КодПодразделения
4. GROUP BY с.НаимПодразделения

Предложение HAVING налагает некоторые условия на выбранные посредством предложения GROUP BY данные.
Следующий пример позволяет получить список складов и суммарное количество товаров на них. Причем в список включаются только те склады, на которых
суммарное количество товаров меньше чем 10000:
1. SELECT с.НаимПодразделения, SUM(b.Количество) AS Количество
2. FROM Запасы b, Подразделения c
3. WHERE b.КодПодразделения = с.КодПодразделения
4. GROUP BY с.НаимПодразделения
5. HAVING SUM(b.Количество) < 10000
Операторы DML. INSERT INTO.

INSERT INTO -  используется для добавления новых строк в таблицу.


Синтаксис INSERT INTO:
Используя перечисление значений с указанием столбцов: В последнем случае в таблицу можно вставить более одной записи. Если в таблице есть другие поля,
1. INSERT INTO ([, ...]) VALUES (, ...) требующие заполнения, но неуказанные в операторе insert, то для них будет установлено значение по
умолчанию, либо null, если значение по умолчанию не установлено.
Используя перечисление значений без указания столбцов:
1. INSERT INTO VALUES (, ...)

Примеры использования INSERT INTO:


Есть таблица "Persons":

Добавим новую строку в таблицу "Persons":


1. INSERT INTO Persons
2. VALUES (4,'Nilsen', 'Johan', 'Bakken 2', 'Stavanger')

Следующий SQL запрос добавит новую строку, но данные будут содержатся только в столцах "P_Id", "LastName" и "FirstName":
1. INSERT INTO Persons (P_Id, LastName, FirstName)
2. VALUES (5, 'Tjessem', 'Jakob')
Операторы DML. UPDATE.
UPDATE -  используется для обновления записей в таблице.
Синтаксис UPDATE:
1. UPDATE table_name
2. SET column1=value, column2=value2,... Замечание: Обратите внимание на WHERE в синтаксисе UPDATE. WHERE определяет, какие записи
3. WHERE some_column = some_value должны быть обновлены, если условие WHERE не прописано, то все записи в таблице будут обновлены!

Примеры использования UPDATE:


Есть таблица "Persons":

Обновим столбцы "Tjessem, Jakob" в таблице "Persons":


1. UPDATE Persons
2. SET Address='Nissestien 67', City='Sandnes'
3. WHERE LastName='Tjessem' AND FirstName='Jakob'

Обновление данных в одной таблице на основание данных в другой таблице:


1. UPDATE Persons as p, Friends as f
2. SET p.Address = f.Address
3. WHERE p.id = f.pid AND p.City='Sandnes'
Операторы DML. DELETE.
DELETE -  используется для удаления записей в таблице.
Синтаксис DELETE:
1. DELETE FROM table_name
2. WHERE some_column = some_value Замечание: При составлении запроса на удаление используйте условие WHERE, иначе все записи могут быть
удалены.
Примеры использования DELETE:
Есть таблица "Persons":

Удалим записи "Tjessem, Jakob" из таблицы "Persons":


1. DELETE FROM Persons
2. WHERE LastName='Tjessem' AND FirstName='Jakob'

Можно удалить все записи в таблице, не удаляя саму таблицу. Это означает, что структура таблицы: атрибуты, индексы будут неповрежденными:
1. DELETE FROM table_name
2. OR
3. DELETE * FROM table_name

Замечание: Будьте очень осторожны при выполнении таких запросов. Поскольку записи могут быть потеряны навсегда.
Операторы TCL Операторы TCL (Transaction Control Language)

Операторы Transaction Control Language применяются для


COMMIT – завершить транзакцию и
сохранить изменения в базе данных; управления изменениями, выполненными группой
операторов DML.
ROLLBACK – откатить транзакцию
и отменить изменения в базе
данных ;
SET TRANSACTION – установить
параметры доступа к данным в
текущей транзакции;
Операторы DCL Операторы DCL (Data Control Language)

Операторы Data Control Language, иногда называемые операторами Access Control


CREATE ASSERTION – создать Language, применяются для осуществления административных функций,
ограничение ; присваивающих или отменяющих право (привилегию) использовать базу данных,
DROP ASSERTION – удалить таблицы в базе данных, а также выполнять те или иные операторы SQL.
ограничение ;
GRANT – предоставить привилегии
пользователю или приложению на
манипулирование объектами ;
REVOKE – отменить привилегии
пользователя или приложения.
Также CREATE USER, ALTER USER,
DROP USER, CREATE GROUP, ALTER
GROUP и DROP GROUP для управления
списком пользователей и групп
пользователей.
Операторы СCL Операторы CCL (Cursor Control Language)

DECLARE CURSOR – определяет курсор для запроса ;


Операторы Cursor Control Language используются для определения
курсора, подготовки SQL-предложений для выполнения, а также для
EXPLAIN – описывает план запроса;
некоторых других операторов.
OPEN CURSOR – открытие курсора при получении
результатов запроса;

FETCH – получение строки из результатов запроса;

CLOSE CURSOR – закрытие курсора;

PREPARE – подготовка оператора SQL для


выполнения;
EXECUTE – выполнение оператора SQL;

DESCRIBE – описание подготовленного запроса.


Другие операторы SQL

Кроме того, есть группы операторов установки


параметров сеанса, получения информации о базе данных,
операторы статического SQL, операторы динамического
SQL.

Наиболее важными для пользователя являются операторы


манипулирования данными (DML).
Другие операторы SQL

Стандарт SQL также включает список потенциальных ключевых слов,


зарезервированных для последующих версий стандарта SQL.
Особенности синтаксиса SQL

В описании синтаксиса команд SQL:


оператор определения «::=» разделяет определяемый элемент (слева от оператора) и собственно его
определение (справа от оператора);
квадратные скобки «[ ]» указывают необязательный элемент синтаксической конструкции;

многоточие «...» определяет, что выражение, предшествующее ему, может повторяться любое число раз;

фигурные скобки «{ }» объединяют последовательность элементов в логическую группу, один из элементов


которой должен быть обязательно использован;
вертикальная черта «|» указывает, что часть определения, следующая за этим символом, является одним из
возможных вариантов;
в угловые скобки «< >» заключаются элементы, объясняемые по мере того, как они вводятся.
Операторы сравнения SQL
SQL-инъекции

SQL-инъекция — это атака, направленная на веб-приложение, в ходе которой


конструируется SQL-выражение из пользовательского ввода путем простой конкатенации
(например, $query="SELECT * FROM users WHERE id=".$_REQUEST["id"]). В случае
успеха атакующий может изменить логику выполнения SQL-запроса так, как это ему
нужно. Чаще всего он выполняет простой fingerprinting СУБД, а также извлекает таблицы
с наиболее «интересными» именами (например «users»). После этого, в зависимости от
привилегий, с которыми запущено уязвимое приложение, он может обратиться к
защищенным частям бэк-энда веб-приложения (например, прочитать файлы на стороне
хоста или выполнить произвольные команды).

Полезная информация: 
1. Конкатенация — это операция склеивания объектов линейной структуры, обычно строк.
2.Fingerprinting (фингерпринтинг) – это идентификация пользователя не по специальным меткам, сохраненным на
его системе, а по уникальным особенностям его браузера, системы и устройства.
Принцип атаки

Серверное ПО, получив входной параметр id, использует его для создания SQL-запроса. Рассмотрим следующий PHP-скрипт:
1. $id = $_REQUEST['id’];
2. $res = mysqli_query("SELECT * FROM news WHERE id_news = " . $id);

Если на сервер передан параметр id, равный 5 (например так: http://example.org/script.php?id=5), то выполнится следующий SQL-запрос:
1. SELECT * FROM news WHERE id_news = 5

Но если передать в качестве параметра id строку -1 OR 1=1 (например, так: http://example.org/script.php?id=-1+OR+1=1), то


выполнится запрос:
1. SELECT * FROM news WHERE id_news = -1 OR 1=1

Таким образом, изменение входных параметров путём добавления в них конструкций языка SQL вызывает изменение в логике
выполнения SQL-запроса (в данном примере вместо новости с заданным идентификатором будут выбраны все имеющиеся в базе
новости, поскольку выражение 1=1 всегда истинно — вычисления происходят по кратчайшему контуру в схеме).
Внедрение в стоковые параметры

Серверное ПО, получив запрос на поиск данных в новостях параметром search_text, использует его в следующем SQL-запросе
(здесь параметры экранируются кавычками):
1. $search_text = $_REQUEST['search_text’];
2. $res = mysqli_query("SELECT id_news, news_date, news_caption, news_text, news_id_author FROM news WHERE news_caption LIKE('%
$search_text%')");

Сделав запрос вида http://example.org/script.php?search_text=Test мы получим выполнение следующего SQL-запроса:


1. SELECT id_news, news_date, news_caption, news_text, news_id_author
2. FROM news
3. WHERE news_caption LIKE('%Test%')

Но, внедрив в параметр search_text символ кавычки (который используется в запросе), мы можем кардинально изменить поведение
SQL-запроса. Например, передав в качестве параметра search_text значение ')+and+(news_id_author='1, мы вызовем к
выполнению запрос: 1. SELECT id_news, news_date, news_caption, news_text, news_id_author
2. FROM news
3. WHERE news_caption LIKE('%') and (news_id_author='1%')
Использование UNION

Язык SQL позволяет объединять результаты нескольких запросов при помощи оператора UNION. Это предоставляет возможность
получить несанкционированный доступ к данным. Рассмотрим скрипт отображения новости (идентификатор новости, которую
необходимо отобразить, передается в параметре id):
1. $res = mysqli_query("SELECT id_news, header, body, author FROM news
WHERE id_news = " . $_REQUEST['id']);

Если передать в качестве параметра id конструкцию -1 UNION SELECT 1,username, password,1 FROM admin, это вызовет
выполнение SQL-запроса:
1. SELECT id_news, header, body, author
2. FROM news
3. WHERE id_news = -1 UNION SELECT 1,username,password,1 FROM admin

Так как новости с идентификатором −1 заведомо не существует, из таблицы news не будет выбрано ни одной записи, однако в результат
попадут записи, несанкционированно отобранные из таблицы admin в результате инъекции SQL.
Использование UNION+group_concat()

В некоторых случаях можно провести атаку, но нельзя видеть более одной колонки. В случае с MySQL можно воспользоваться
функцией:
1. group_concat(col, symbol, col)

которая объединяет несколько колонок в одну. Например, для примера данного выше вызов функции будет таким:
1. -1 UNION SELECT group_concat(username, 0x3a, password) FROM admin
Экранирование хвоста

Зачастую, SQL-запрос, подверженный данной уязвимости, имеет структуру, усложняющую или препятствующую использованию
UNION. Например скрипт:
1. $res = mysqli_query("SELECT author FROM news WHERE id=" .
$_REQUEST['id'] . " AND author LIKE ('a%')");

отображает имя автора новости по передаваемому идентификатору id только при условии, что имя начинается с буквы а, и внедрение
кода с использованием оператора UNION затруднительно.
В таких случаях используется метод экранирования части запроса при помощи символов комментария(/* или -- в зависимости от типа
СУБД). В данном примере, можно передать в скрипт параметр id со значением -1 UNION SELECT password FROM admin/*, выполнив
таким образом запрос:
1. SELECT author FROM news WHERE id=-1 UNION SELECT password FROM
admin/* AND author LIKE ('a%')

в котором часть запроса (AND author LIKE ('a%')) помечена как комментарий и не влияет на выполнение.
Расщепление

Для разделения команд в языке SQL используется символ ; (точка с запятой), внедряя этот символ в запрос, пользователь получает
возможность выполнить несколько команд в одном запросе, однако не все диалекты SQL поддерживают такую возможность.
Например, если в параметры скрипта:
1. $id = $_REQUEST['id’];
2. $res = mysqli_query("SELECT * FROM news WHERE id_news = $id");

пользователем передается конструкция, содержащая точку с запятой, например 12;INSERT INTO admin (username, password)
VALUES ('HaCkEr', 'foo'); то в одном запросе будут выполнены 2 команды:
1. SELECT * FROM news WHERE id_news = 12;
2. INSERT INTO admin (username, password) VALUES ('HaCkEr', 'foo');

и в таблицу admin будет несанкционированно добавлена запись HaCkEr.


Поиск скриптов, уязвимых для атаки

На данном этапе пользователь изучает поведение скриптов сервера при манипуляции входными параметрами с целью обнаружения
их аномального поведения. Манипуляция происходит всеми возможными параметрами:
Данными, передаваемыми через методы POST и GET;
Значениями [HTTP-Cookie];
HTTP_REFERER (для скриптов);
AUTH_USER и AUTH_PASSWORD (при использовании аутентификации).
Как правило, манипуляция сводится к подстановке в параметры символа одинарной (реже двойной или обратной) кавычки.
Аномальным поведением считается любое поведение, при котором страницы, получаемые до и после подстановки кавычек,
различаются (и при этом не выведена страница о неверном формате параметров). Наиболее частые примеры аномального поведения:
выводится сообщение о различных ошибках;
при запросе данных (например, новости или списка продукции) запрашиваемые данные не выводятся вообще, хотя страница отображается и т.д.

Следует учитывать, что известны случаи, когда сообщения об ошибках, в силу специфики разметки страницы, не видны в браузере,
хотя и присутствуют в её HTML-коде.
Защита от SQL-инъекций

Для защиты от данного типа атак необходимо тщательно фильтровать входные


параметры, значения которых будут использованы для построения SQL-запроса.
Фильтрация строковых параметров

Чтобы внедрение кода (закрытие строки, начинающейся с кавычки, другой кавычкой до её завершения текущей закрывающей
кавычкой для разделения запроса на две части) было невозможно, для некоторых СУБД, в том числе, для MySQL, требуется брать в
кавычки все строковые параметры. В самом параметре заменяют кавычки на \", апостроф на \', обратную косую черту на \\ (это
называется «экранировать спецсимволы»). Это можно делать таким кодом:

1. $query = "SELECT * FROM users WHERE user='" . mysqli_real_escape_string($user) . "';";


Фильтрация целочисленных параметров

В случае когда поле id имеет числовой тип, и его чаще всего не берут в кавычки. Поэтому «закавычивание» и замена спецсимволов на
escape-последовательности не проходит. В таком случае помогает проверка типа; если переменная id не является числом, запрос
вообще не должен выполняться.

1. $query = 'SELECT * FROM users WHERE id = ' . (int)$id;


Усечение входных параметров

Для внесения изменений в логику выполнения SQL-запроса требуется внедрение достаточно длинных строк. Так, минимальная длина
внедряемой строки в вышеприведённых примерах составляет 8 символов («1 OR 1=1»). Если максимальная длина корректного
значения параметра невелика, то одним из методов защиты может быть максимальное усечение значений входных параметров.
Например, если известно, что поле id в вышеприведённых примерах может принимать значения не более 9999, можно «отрезать
лишние» символы, оставив не более четырёх:
1. statement := 'SELECT * FROM users WHERE id = ' + LeftStr(id, 4) + ';';
Использование параметризованных запросов

Многие сервера баз данных поддерживают возможность отправки параметризованных запросов (подготовленные выражения). При
этом параметры внешнего происхождения отправляются на сервер отдельно от самого запроса либо автоматически экранируются
клиентской библиотекой. Для этого используются
на Delphi — свойство
TQuery.Params;
на Perl — через DBI::quote или
DBI::prepare;
на Java — через класс PreparedStatement;
на C# — свойство SqlCommand.Parameters;
на PHP — MySQLi (при работе с
MySQL), PDO. 1. var
2. sql, param : string;
3. begin
4. sql := 'select :text as value from dual’;
5. param := 'alpha’;
6. Query1.Sql.Text := sql;
7. Query1.ParamByName('text').AsString := param;
8. Query1.Open;
9. ShowMessage(Query1['value']);
10. end;
Источники информации

Информация по SQL-запросам была взята из следующих источников:


1. https://ru.wikipedia.org/wiki/SQL
2. https://www.site-do.ru/db/db.php#2
3. http://dimonchik.com/insert.html
4. http://beginner-sql-tutorial.com/sql-alterdatabase.htm
5. http://www.spravkaweb.ru/mysql/sql/alter_database
6. Методические материалы по курсу «Базы Данных. Полоцкий Государственный университет».

Информация по SQL-инъекциям была взята из следующих источников:


7. https://xakep.ru/2011/12/06/57950/
8. Внедрение SQL-кода.
УСПЕШНОЙ
РАБОТЫ В
ANDERSEN!