произвольный JOIN в обход xpdo

Сегодня делал рандомную выборку данных, т.к. при большом кол-во данных вроде как в старый mysql сортировка по rand() проходила очень долго. В сети существует множество вариантов как сделать так чтобы выборка была еще быстрее, но по большей части в них используются процедуры, вложенные sql и самый простой вариант мудренный JOIN. Мне не хотелось для моей задачи писать сниппет и я использовал msProducts, который использует методы pdoTools для построения запросов. Поэтому начну с него. Для того чтобы передать состряпать JOIN мы можем использовать запись JSON, но если нам нужен вот такой
JOIN ( SELECT CEIL(RAND() * (SELECT MAX(id) FROM random)) AS id ) AS r2 USING (id);
??? то формат вида:
"Randomid": {
 "alias":"...",
 "class":"...",
 "on":"..."
},
Нам не подходит, да и вообще нет параметров в сниппете которыми можно воспользоваться чтобы добавить такой запрос (если я чего не пропустил конечно). НО есть маленькая лазейка. В pdofetch join строиться как
$this->query->$join($class, $alias, $v['on']);
query это xPDOQuery. Так вот, если мы передадим в него, в моем случае воспользовавшись сниппетом, такую конструкцию при которой JOIN будет парсироваться правильно:
"Randomid": {
 "alias":"modResource",
 "class":"modResource",
 "on":"1=1 JOIN ( SELECT CEIL(RAND() * (SELECT MAX(id) FROM `modx_site_content`)) AS rid ) AS r2"
},
То мы получим вполне работоспособный JOIN. Сразу возникает вопрос, а что если после 1=1 послать
; SELECT 1,2,3
Отвечу: не прокатит, получим ошибку
SQL injection attempt detected: 1=1; SELECT 1,2,3
Не проверял но думаю это либо xpdo либо уже pdo проверяет наличие точки с запятой и UNION. Но это конечно не значит что прикрыты все дырки, например, если в сниппет послать такой подарок:
...&leftJoin=`{
"Randomid": {
    "class":"modResource",
    "on":"1=1 AND ExtractValue(1,concat(0x5C,(select password from modx_users where id=1 limit 1)))"
  }...
}`
То некоторые версии SQL воспримут как нужно и вернут нам нечто вроде:Т.е. в тексте ошибки вернется нам результат запроса.
Конечно нельзя сказать что это настоящая уязвимость, но она вполне имеет место, если вы используете в своих сниппетах или запросах непроверенное содержимое запросов браузера или позволяете менеджерам выполнять код modx (и то и другое уже открытые ворота конечно же). Хотя по мне, так это прекрасная возможность использовать хитрые JOIN-ы.
Степан Прищепенко
27 ноября 2015, 19:52
modx.pro
2
2 206
0
Поблагодарить автора Отправить деньги

Комментарии: 0

Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
0