Долбим SQL’ные базы данных
maravan
Xakep, номер #056, стр. 056-058-2
Вот пример с UPDATE:
UPDATE cc_table SET cc_number=12345 WHERE cc_holder='Agent Smith'
Здесь произойдет просмотр таблицы cc_table. Если в соответствующих записях значение поля cc_holder будет равно 'Agent Smith', то значение cc_number сменится на 12345.
А это запрос DELETE:
DELETE FROM cc_table WHERE cc_type='visa'
Удалятся все записи из таблицы, где поле cc_type равно значению 'visa'.
На этом небольшой ликбез по SQL закончился. Теперь можно приступить к самому вкусному. Тому, ради чего поднялся весь сыр-бор: SQL injection.
SQL injection
Суть ошибок класса SQL injection состоит в том, что из-за некорректной обработки данных, передаваемых скрипту, потенциальный хакер может изменить составляемый скриптом SQL-запрос со всеми вытекающими отсюда последствиями. К примеру, в случае с инет-магазином, он может таким образом изменить запрос, что SQL-сервер после его обработки выдаст все содержимое таблицы, в которой содержится инфа о предыдущих клиентах магазина, включая номера их кредитных карточек и т.д. и т.п.
Это может выглядеть следующим образом. Предположим, что в составе интернет-магазина присутствует скрипт, принимающий от юзера логин и пароль и выдающий инфу о его предыдущих покупках, номерах карточек и т.д. Логин и пароль загоняются скриптом в следующее SQL-выражение, которое передается серверу базы данных:
SELECT * FROM clients WHERE login='$login' AND password='$password'
В результате обработки данного выражения сервер возвращает скрипту все записи в таблице, соответствующие логину юзверя.
Данные, введенные юзверем ($login и $password), берутся из web-формы и напрямую подставляются в это SQL-выражение. Отсюда появляется возможность хитрым образом так задать логин и пароль, что логика SQL-выражения немного изменится, в результате чего сервер базы данных возвратит записи из таблицы clients, соответствующие всем клиентам магазина со всеми данными о них. К примеру, это можно сделать так: в качестве логина задать такую строку: "nobody' OR ''='", а в качестве пароля "nopassword' OR ''='". С использованием этих данных скрипт сформирует такое выражение:
SELECT * FROM clients WHERE login='nobody' OR ''='' AND password='nopassword' OR ''=''
И под это SQL-выражение будут попадать все записи таблицы clients, т.к. login='nobody' OR ''='' и password='nopassword' OR ''='' всегда будут истинными. Так хакеры и ломают многие базы данных.
Собственно говоря, мы сделали то, что принято называть SQL injection. Дальше же будут приведены некоторые особо часто используемые трюки, которые проворачивают, если есть хоть какая-то возможность повлиять на SQL-выражение.
UNION
В предыдущем примере мы предположили, что вся инфа о юзверях содержится в таблице clients. Немного изменим условия. Допустим, в таблице clients находятся просто записи о клиентах - имена, фамилии и т.д. Номера же кредитных карточек располагаются в другой таблице, допустим, cards. Соответственно, теперь стоит задача вытянуть инфу из этой таблицы, смодифицировав уже указанный выше запрос: