Пишу, по большей части, про историю, свою жизнь и немного про программирование.

SQL-инъекция в штрих-коде?

*\'; DROP TABLE products; --* (2.32КиБ)

А вот ещё идея возникла. Распечатываете этот штрих-код на стикеры, и незаметно клеите их рядом с ценниками в супермаркетах конкурента.

Когда в конце рабочего дня будут производить учет товаров какой-нибудь доброход-товаровед обязательно посветит на него штрих-код сканером. :)

А там написано *’; DROP TABLE products; —*

P.S. Я и сам принимал участие в разработках программ складского учета с применением сканеров штрихкода. И знаю — никто там, естественно, входные данные не проверяет, чаще всего шпарят прям напрямую запросы с динамическими параметрами в SQL-базу. А теперь вот задумался, прогресс-то не стоит на месте… :)

Забавно, неужели правда сработает?

29 комментариев
Андрей 2010

На одном фотосайте как-то нашёл забавную уязвимость, можно было вставлять html код в EXIF информацию снимка.

toz@livejournal 2010

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

toz@livejournal 2010

да, база данных там внутри далеко не sql, что-то совсем плюшевое

Евгений Степанищев (bolknote.ru) 2010

Комментарий для toz@livejournal:

Я уверен, что какая-нибудь «1С: Склад» на SQL.

Евгений Степанищев (bolknote.ru) 2010

Комментарий для Андрей:

На одном фотосайте как-то нашёл забавную уязвимость, можно было вставлять html код в EXIF информацию снимка.

Это далеко не самая забавная уязвимость, которую при помощи JPEG/EXIF можно найти :)

vladon (vladon.ru) 2010

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

в обмен между терминалом и основной БД инъекция точно не попадёт — там синхронизация по внутренним артикулам товаров, а не по штрихкоду.

oldTV 2010

Работать не будет, по ряду причин, некоторые из которых назвали выше:

  1. Сканер не работает с базой напрямую. ТСД например имеет свою базу, и только потом обмен с базой сервера. При WiFi режиме — обмен идет через процедуры, которые вряд ли пропустят. Да и обмен идет не по штрихкодам, а артикулу или ID товара в базе.
  2. Сканер читает штриховой код EAN-13, редко другие, очень редко Code 128, как здесь. Маловероятно что сканер поймет этот код. В магазинах обычно дико экономят на оборудовании и вряд ли купят сканер или ТСД читающий все кода.
  3. Есть административное и четкое указание какой код читать, ну по крайней мере в тех организаций, с которыми я сталкивался. Читается всегда код с товара, а не с ценника. Во первых не ценник несут на кассу, а товар, во вторых — ценника может и не быть.
  4. Видно что код не тот. На кодах магазина внизу пишут артикул, как правило, тут его нет.

На кассе тоже маловероятно....

admin (gopstop.org) 2010

а я печатал идентичные ценники с заниженной ценой на весовой товар :)

praeivis (praeivis.lt) 2010

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

Евгений Степанищев (bolknote.ru) 2010

Комментарий для gerty9000:

Забавно :)

oldTV 2010

Комментарий для gopstop.org:

ну с весовым как только не извращаются :), я лично знаю 400, сравнительно честных способов :)

shyster 2010

Через клаву, поле для ввода больше 13 цифр не пропускает.

shyster 2010

Через клаву, поле для ввода больше 13 цифр не пропускает.

dV (dvlab.blogspot.com) 2010

Комментарий для oldTV:

Давайте подробнее

sq_deep 2010

Я вообще-то работаю в области автоматизации розничной торговли... не могу себе представить, чтобы текст, прочитанный сканером штрихкода хоть где-нибудь воспринимался как sql-предложение. Это может быть код ean или количество. Ну, может быть, вес товара, хотя обычно вес интегрируется по определённым правилам в состав ean-13. Но чтобы таким образом вводились sql-предложения? Да ещё с ценников или этикеток? Это просто невероятно. Кстати, с той базой, с которой я работаю, шутка «drop table products» не пройдёт. Соответствующая таблица называется goods. Ещё в одной известной мне системе таблица называется не products, а product. Хотя конечно сама идея выглядит смешно, для Первого апреля покатит :)

caesar (gaius-julius.ya.ru) 2010

блин, придётся напечатать десяток-другой вариантов и пойти тестировать в боевых условиях.
Настенные терминалы, которые говорят тебе цену по штрихкоду — прекрасная цель (-:

zelgadis 2010

Либо автор считает всех разработчиков идиотами либо он сам не осведомлен что стандартной практикой является не составление строки с параметрами в запросе а пользование плэйсхолдерами
insert into a (col_a, col_b) values (?, ?)
select * from products where prod_id = ?
Все параметры передаются отдельно и корректно обрабатываются.
По другому пишет только школьники.

mikhail kazakov (medvedkrevedkov.blogspot.com) 2010

Работал в рознице. Идея не реальная. Сканер считывает лишь идентификатор (артикул, инв. номер, количество) вся остальная информация — в базах. Ввести SQL со штрих-кода это забавная (и красивая) шутка не более :)

iphonenews.ru 2010

В нормальных БД, в отличие от MySQL, есть динамические параметры, через которые сделать SQL-инъекцию невозможно. Непонятно, что мешает разработчикам MySQL сделать то же самое вместо извращений с кавычками.

Евгений Степанищев (bolknote.ru) 2010

Комментарий для iphonenews.ru:

Пример? Или это будет пример из API? В API MySQL это всё тоже есть

iphonenews.ru 2010

А еще в нормальных БД есть внешние ключи, которые на дадут удалить все из справочника при условии, что хотя бы один товар где-либо используется.

iphonenews.ru 2010

Комментарий для Евгения Степанищева:

procedure TForm1.CoolProc (s: string; id: integer);
begin
pFIBQuery1.SQL.Text := ’update GOODS set name=:name where id=:id’;
pFIBQuery1.ParamByName (’name’).Value := s;
pFIBQuery1.ParamByName (’id’).Value := id;
pFIBQuery1.ExecQuery;
end;

Евгений Степанищев (bolknote.ru) 2010

Комментарий для iphonenews.ru:

А еще в нормальных БД есть внешние ключи, которые на дадут удалить все из справочника при условии, что хотя бы один товар где-либо используется.

Отсюда, какбэ, следует, что MySQL — нормальная БД.

procedure TForm1.CoolProc (s: string; id: integer);

Ну, то есть, как я и предполагал, это пример из API биндинга. То есть от СУБД это не зависит.

Но в MySQL есть «динамические параметры» (parameters markers/placeholders) на уровне API самой СУБД: http://dev.mysql.com/doc/refman/5.1/en/mysql-stmt-bind-param.html и на уровне самой СУБД http://dev.mysql.com/doc/refman/5.1/en/sql-syntax-prepared-statements.html

iphonenews.ru 2010

Комментарий для Евгения Степанищева:

То есть от СУБД это не зависит

Зависит. В данном случае это обертка вызовов API клиентской библиотеки СУБД.

Если в MySQL есть динамические параметры, почему их не используют, а формируют текст запросов вручную и постоянно нарываются на sql-инъекции?

Евгений Степанищев (bolknote.ru) 2010

Комментарий для iphonenews.ru:

Нет, от СУБД это не зависит, так как это вполне можно делать в биндинге. Для некоторых СУБД это делается именно в биндинге, а то и выше, на уровне приложения.

Почему люди не делают как правильно? О, ну сотни причин. Неправильно проще, они не читали документацию, они не заморачиваются с обеспечением безопасности и ещё сотни минус три причины.

iphonenews.ru 2010

Комментарий для Евгения Степанищева:

Что такое этот загадочный биндинг? И как в PHP использовать эти динамические параметры?

Евгений Степанищев (bolknote.ru) 2010

Комментарий для iphonenews.ru:

Что такое этот загадочный биндинг?

Смотря о каком из значений этого слова вопрос. «Биндинг» = «привязка».

И как в PHP использовать эти динамические параметры?

В документации же есть. Откуда, кстати, такой термин, «динамические параметры»? В первый раз слышу.
http://ru2.php.net/manual/en/mysqli-stmt.bind-param.php и  http://ru2.php.net/manual/en/pdostatement.bindparam.php

iphonenews.ru 2010

Комментарий для Евгения Степанищева:

Не помню, где я в первый раз услышал «динамические параметры». Общеупотребительный термин. А я про биндинг впервые слышу. Видимо, программирование приложений БД и программирование в интернете разные миры.