|
|
|
(mysql 5.6 + PHP 5.6 + Apache/2.4.12 (FreeBSD 8.4) OpenSSL/0.9.8y mpm-itk/2.4.7-02)
|
|||
|---|---|---|---|
|
#18+
Привет всем! После обновления ПО сервера возникла проблема с одним из древних сайтов. Периодически процесс mysqld вызывает 100%+ загрузку процессора, при этом SHOW PROCESSLIST показывает множество копий одного и того же запроса к базе в состоянии Sending data: В скрипте проблемный запрос выглядит так: Код: sql 1. 2. 3. 4. 5. 6. 7. 8. Так в логах: Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. Заранее спасибо за помощь! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.03.2015, 17:09:37 |
|
||
|
(mysql 5.6 + PHP 5.6 + Apache/2.4.12 (FreeBSD 8.4) OpenSSL/0.9.8y mpm-itk/2.4.7-02)
|
|||
|---|---|---|---|
|
#18+
kirobas, Поздравляю, у вас SQL-инъекция. Уберите из всех генераций SQL-запросов конкатенацию входных значений. Т.е. так делать нельзя:kirobas Код: sql 1. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.03.2015, 17:12:18 |
|
||
|
(mysql 5.6 + PHP 5.6 + Apache/2.4.12 (FreeBSD 8.4) OpenSSL/0.9.8y mpm-itk/2.4.7-02)
|
|||
|---|---|---|---|
|
#18+
miksoft, ого, это весь сайт надо будет перелопатить, т.е. предварительно просто $_GET['idarticle'] проверять на корректность? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.03.2015, 17:15:59 |
|
||
|
(mysql 5.6 + PHP 5.6 + Apache/2.4.12 (FreeBSD 8.4) OpenSSL/0.9.8y mpm-itk/2.4.7-02)
|
|||
|---|---|---|---|
|
#18+
kirobasmiksoft, ого, это весь сайт надо будет перелопатить, т.е. предварительно просто $_GET['idarticle'] проверять на корректность?Либо тщательно проверять, либо пользоваться запросами с параметрами. А лучше и то, и другое. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.03.2015, 17:20:29 |
|
||
|
(mysql 5.6 + PHP 5.6 + Apache/2.4.12 (FreeBSD 8.4) OpenSSL/0.9.8y mpm-itk/2.4.7-02)
|
|||
|---|---|---|---|
|
#18+
miksoft, но в логах-то запросы с корректными параметрами, отчего же они дублируются и висят? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.03.2015, 19:31:54 |
|
||
|
(mysql 5.6 + PHP 5.6 + Apache/2.4.12 (FreeBSD 8.4) OpenSSL/0.9.8y mpm-itk/2.4.7-02)
|
|||
|---|---|---|---|
|
#18+
kirobasmiksoft, но в логах-то запросы с корректными параметрами, отчего же они дублируются и висят?Дублируются - потому что пришло несколько http-запросов с инъекцией. Вероятно, от нетерпения атакующим :) Хотя если целью был DOS (т.е. отказ в обслуживании), то логично, что http-запросов привалило сразу много. Висят (точнее, долго выполняются) потому что в конце инъекченной строки есть фрагмент or 1=(...). Подзапрос в скобках сам по себе долго выполняется. Да и результат этого выражения, похоже, дает истину для большинства или всех записей конечноного запроса, который собирается аж из шести таблиц. Т.е. DISTINCT должен обработать результат декартова произведения шести таблиц, что явно будет работать очень не быстро. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.03.2015, 19:38:53 |
|
||
|
(mysql 5.6 + PHP 5.6 + Apache/2.4.12 (FreeBSD 8.4) OpenSSL/0.9.8y mpm-itk/2.4.7-02)
|
|||
|---|---|---|---|
|
#18+
miksoft, Афигеть. Первый раз вижу реальную инъекцию... Кстати, вам вопрос: разве переход на запросы с бинтованием параметров (через вопросик или именованные) - не исключает инъекции чуть более чем полностью? В смысле а зачем тогда "а лучше и то и другое"? (а то ведь пожирание ресурсов на нагруженных серверах тоже не айс...) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.03.2015, 08:00:59 |
|
||
|
(mysql 5.6 + PHP 5.6 + Apache/2.4.12 (FreeBSD 8.4) OpenSSL/0.9.8y mpm-itk/2.4.7-02)
|
|||
|---|---|---|---|
|
#18+
Arhat109а зачем тогда "а лучше и то и другое"?чтобы не гонять зря запросы с бессмысленными параметрами? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.03.2015, 08:10:31 |
|
||
|
(mysql 5.6 + PHP 5.6 + Apache/2.4.12 (FreeBSD 8.4) OpenSSL/0.9.8y mpm-itk/2.4.7-02)
|
|||
|---|---|---|---|
|
#18+
tanglir, ?!? Бессмысленные параметры проверяются ишо в контроллерах MVC моделей, разве нет? Инъекция, как понимаю возникает из-за прямой передачи содержимого $_REQUEST['параметр'] ($_GET, $_POST ...) в запрос, поскольку требуется именно передача текста, и практически "произвольного"... то есть проверять на "бессмысленность" - нечего. ... или вы проверяете любой текст на наличие в нем sql признаков?!? :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.03.2015, 08:14:48 |
|
||
|
(mysql 5.6 + PHP 5.6 + Apache/2.4.12 (FreeBSD 8.4) OpenSSL/0.9.8y mpm-itk/2.4.7-02)
|
|||
|---|---|---|---|
|
#18+
Arhat109?!? Бессмысленные параметры проверяются ишо в контроллерах MVC моделей, разве нет?Разве код топикстартера похож на MVC? Да и у большинства, думаю, похожего мало. Arhat109то есть проверять на "бессмысленность" - нечего.Почему же нечего? Во-первых, длину. У многих параметров длина довольно небольшая и сотен знаков там явно быть не может. Иногда длина должна быть фиксированной или находиться в некотором диапазоне. Во-вторых, формат. В данном случае это строка, состоящая только из цифр, ограниченной длины. Проверять есть смысл, чтобы можно было бросить обработку всего http-запроса в случае поступления мусора на вход, не пытаясь свалить эту задачу на СУБД и не тратя ресурсы на дальнейшую работу с этими данными. Arhat109... или вы проверяете любой текст на наличие в нем sql признаков?!? :)Некоторые CMS так и делают - проверяют все входные параметры на содержание ключевых слов SQL, PHP, javasrcipt и т.п. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.03.2015, 09:33:31 |
|
||
|
(mysql 5.6 + PHP 5.6 + Apache/2.4.12 (FreeBSD 8.4) OpenSSL/0.9.8y mpm-itk/2.4.7-02)
|
|||
|---|---|---|---|
|
#18+
miksoftРазве код топикстартера похож на MVC? Да и у большинства, думаю, похожего мало. ... Во-первых, длину. У многих параметров длина довольно небольшая и сотен знаков там явно быть не может. ... Проверять есть смысл, чтобы можно было бросить обработку всего http-запроса в случае поступления мусора на вход, не пытаясь свалить эту задачу на СУБД и не тратя ресурсы на дальнейшую работу с этими данными. ... Некоторые CMS так и делают - проверяют все входные параметры на содержание ключевых слов SQL, PHP, javasrcipt и т.п. Да фиг его знает что у него там "до" построения запроса. У меня тоже много где идет контроллер с проверками, а в модели точно такая же фигня прямо из $_REQUEST, только в бинтованный параметр лепится... нафига проверять текст, если он бинтуется? Насчет "длины" ... ну вот поиск по названию фирмы скажем ... сколько знаков "достаточно"? А ежели у меня поле с названием до 1000 знаков "терпит"? И опять же, передача длинного текста в фильтр - больший шанс тупо не найти ничего... то есть ускорить ответ. (чисто примеру для: автокомплит по трем буквам - запрос отрабатывает около секунды на паре миллионов записей, а запрос названия из 20 символов - уже 0.15 ибо есть длинный индекс ... машинка чахлая на самом деле ... ) Тут - да, простое преобразование к целому - и вся "защита"... Ну CMS никогда не отличались "умом и сообразительностью" в плане "высоких нагрузок". Тот же Zend - ещё то "дерьмо", если уж честно... они больше для ленивых и торопливых, чем для серъезной работы. Зато да, часто исправляют кучу ляпов от новичков... В целом меня зантриговал ваш ответ тем, что я заопасался что бинтование НЕ исключает шанс инъекции (то есть, где-то по дороге, таки происходит "сборка" в единый текстовый запрос, который ПОТОМ парсится синт. анализатором Мускуля ... и тогда "всё едино" и таки НАДО проверять даже бинтованные параметры... Вот как оно "на самом деле"? Хотел просто уточнить, а не холиварить... ибо в доках как-то оно размыто это место, на память. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.03.2015, 11:05:11 |
|
||
|
(mysql 5.6 + PHP 5.6 + Apache/2.4.12 (FreeBSD 8.4) OpenSSL/0.9.8y mpm-itk/2.4.7-02)
|
|||
|---|---|---|---|
|
#18+
Arhat109Насчет "длины" ... ну вот поиск по названию фирмы скажем ... сколько знаков "достаточно"? А ежели у меня поле с названием до 1000 знаков "терпит"?По длине поля в БД или по длине поля для ввода в интерфейсе, смотря что меньше. Arhat109бинтование НЕ исключает шанс инъекцииТеоретически такого быть не должно, т.е. исключает. Прямой конкатенации всего запроса внутри MySQL, конечно, не происходит. Но что там с защитой от переполнения и т.п. - неизвестно. Хотя вряд ли веб-сервер вообще такой запрос примет, чтобы мог вызвать переполнение. Т.е. рекомендация была просто исходя из экономии ресурсов, чтобы не совать в MySQL то, что туда совать смысла не имеет. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.03.2015, 11:29:35 |
|
||
|
(mysql 5.6 + PHP 5.6 + Apache/2.4.12 (FreeBSD 8.4) OpenSSL/0.9.8y mpm-itk/2.4.7-02)
|
|||
|---|---|---|---|
|
#18+
miksoft, В общем, пасибки, успокоили. Да кстати, подход prepare - execute фактически должен сначала парсить запрос, и только потом бинтовать данные. Так что здря я "заопасалси". :) Ну а по поводу "что дешевше" - это по ситуации. Так или иначе, но оно завсегда упирается в банальный цикл перебора ключевиков с поиском по строке. Только в случае проверки "до" мускуля - это часто "интерпретатор" (PHP, Perl и т.д.) с перебором ключевиков (предварительно надо продраться через 3-10 классов ООП ЦМС-ки!), а в мускуле таки компилированный вариант поиска в строке индекса (неиндексированные выборки не рассматриваем) плюс расходы на передачи ... всё зависит от логарифма длины индекса (количества итераций по индексу) и количества таких "ключевиков". Но, для большинства "юзверей" - это такие дебри... :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.03.2015, 11:48:52 |
|
||
|
(mysql 5.6 + PHP 5.6 + Apache/2.4.12 (FreeBSD 8.4) OpenSSL/0.9.8y mpm-itk/2.4.7-02)
|
|||
|---|---|---|---|
|
#18+
miksoftkirobasmiksoft, ого, это весь сайт надо будет перелопатить, т.е. предварительно просто $_GET['idarticle'] проверять на корректность?Либо тщательно проверять, либо пользоваться запросами с параметрами. А лучше и то, и другое. ДОСТАТОЧНО второго (пользоваться запросами с параметрами). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.03.2015, 12:43:41 |
|
||
|
(mysql 5.6 + PHP 5.6 + Apache/2.4.12 (FreeBSD 8.4) OpenSSL/0.9.8y mpm-itk/2.4.7-02)
|
|||
|---|---|---|---|
|
#18+
Arhat109Кстати, вам вопрос: разве переход на запросы с бинтованием параметров (через вопросик или именованные) - не исключает инъекции чуть более чем полностью? Исключает от слова "совсем". Но есть одно "но". Параметры могут быть реализованы по-разному. Могут быть параметры, реализованные на уровне CL API, а могут быть параметры, реализованные на уровне "хитрожопой прикладной библиотеки для нашего языка для работы с базами данных на SQL". Первые абсолютно безопасны, поскольку они всегда интерпретируют содержимое параметров как данные .(*) Вторые могут быть запросто релизованы на уровне генерирования фраз SQL, и иметь все те же проблемы, что и у кода типа Код: php 1. * тем не меннее, криворукие программисты бывают и среди тех, кто пишет CL API, и конечно же и там иногда могут обнаруживаться проблемы. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.03.2015, 12:49:31 |
|
||
|
(mysql 5.6 + PHP 5.6 + Apache/2.4.12 (FreeBSD 8.4) OpenSSL/0.9.8y mpm-itk/2.4.7-02)
|
|||
|---|---|---|---|
|
#18+
Arhat109В общем, пасибки, успокоили. Да кстати, подход prepare - execute фактически должен сначала парсить запрос, и только потом бинтовать данные. Так что здря я "заопасалси". :) Не всегда и не обязательно. Собственно, вызов prepare только МОЖЕТ так делать, но вовсе не обязательно, что для конкретной СУБД он БУДЕТ так делать. Само наличие prepare не гарантирует, что не будет SQL INJECTION. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.03.2015, 12:51:35 |
|
||
|
(mysql 5.6 + PHP 5.6 + Apache/2.4.12 (FreeBSD 8.4) OpenSSL/0.9.8y mpm-itk/2.4.7-02)
|
|||
|---|---|---|---|
|
#18+
MasterZivмогут быть параметры, реализованные на уровне "хитрожопой прикладной библиотеки для нашего языка для работы с базами данных на SQL".Да, кстати, про такой вариант в общем случае тоже не надо забывать. И даже кое-что попалось на эту тему: http://stackoverflow.com/questions/18803023/why-wouldnt-i-disable-pdomysql-attr-direct-query Why wouldn't I disable PDO::MYSQL_ATTR_DIRECT_QUERY? I stumbled upon the (imho rather poorly documented) fact that by default PHP PDO has the flag MYSQL_ATTR_DIRECT_QUERY enabled for its MySQL driver. This means rather than actually use prepared statements, it emulates the behaviour of prepared statements. This means it replaces the placeholders client-side with escaped values and just sends the full query to the database as-is. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.03.2015, 13:05:37 |
|
||
|
(mysql 5.6 + PHP 5.6 + Apache/2.4.12 (FreeBSD 8.4) OpenSSL/0.9.8y mpm-itk/2.4.7-02)
|
|||
|---|---|---|---|
|
#18+
miksoftИ даже кое-что попалось на эту тему: http://stackoverflow.com/questions/18803023/why-wouldnt-i-disable-pdomysql-attr-direct-query This means rather than actually use prepared statements, it emulates the behaviour of prepared statements. This means it replaces the placeholders client-side with escaped values and just sends the full query to the database as-is. На самом деле prepared statements вообще никак не связаны с проблемой SQL INJECTION. Т.е. ортогональны. Хотя я конечно не знаю MySQL API, может там нет вообще другой возможности биндить параметр, кроме как в prepared statement. В других СУБД часто это не связано (можно биндить в prepared, можно просто в любой). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.03.2015, 13:23:47 |
|
||
|
(mysql 5.6 + PHP 5.6 + Apache/2.4.12 (FreeBSD 8.4) OpenSSL/0.9.8y mpm-itk/2.4.7-02)
|
|||
|---|---|---|---|
|
#18+
MasterZivХотя я конечно не знаю MySQL API, может там нет вообще другой возможности биндить параметр, кроме как в prepared statement.Именно так. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.03.2015, 13:42:26 |
|
||
|
(mysql 5.6 + PHP 5.6 + Apache/2.4.12 (FreeBSD 8.4) OpenSSL/0.9.8y mpm-itk/2.4.7-02)
|
|||
|---|---|---|---|
|
#18+
miksoftMasterZivмогут быть параметры, реализованные на уровне "хитрожопой прикладной библиотеки для нашего языка для работы с базами данных на SQL".Да, кстати, про такой вариант в общем случае тоже не надо забывать. И даже кое-что попалось на эту тему: http://stackoverflow.com/questions/18803023/why-wouldnt-i-disable-pdomysql-attr-direct-query Why wouldn't I disable PDO::MYSQL_ATTR_DIRECT_QUERY? I stumbled upon the (imho rather poorly documented) fact that by default PHP PDO has the flag MYSQL_ATTR_DIRECT_QUERY enabled for its MySQL driver. This means rather than actually use prepared statements, it emulates the behaviour of prepared statements. This means it replaces the placeholders client-side with escaped values and just sends the full query to the database as-is. Упс... вот я как раз про этот вариант и забеспокоился... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.03.2015, 14:12:34 |
|
||
|
|

start [/forum/topic.php?fid=47&msg=38900663&tid=1833459]: |
0ms |
get settings: |
8ms |
get forum list: |
15ms |
check forum access: |
2ms |
check topic access: |
2ms |
track hit: |
60ms |
get topic data: |
9ms |
get forum data: |
2ms |
get page messages: |
69ms |
get tp. blocked users: |
2ms |
| others: | 204ms |
| total: | 373ms |

| 0 / 0 |
