Вечер добрый, собственно, интересно услышать мнение бывалых о дырявости реализации собирания и выполнения запроса. Пример get запроса - mysite.com/api/customers/search/first_name=John&last_name=Doe&phone=0987654321 Делаю апишечку на Slim фреймворке, и собственно данный путь должен парсить входящую строку и выводить пользователей с необходимыми аттрибутами: PHP: $app->get('/api/customers/search/{query}', function(Request $request, Response $response) { $name = $request->getAttribute('query'); parse_str($name, $parsedQuery); $q = ''; $bindings = []; // Определяем необходимость AND в sql запросе. $putAnd = false; foreach ($parsedQuery as $key => $value) { if ($putAnd && !empty($value)) { $q .= ' AND '; } if (!empty($value)) { $q .= "$key = :$key"; $bindings[] = "$key"; $putAnd = true; } } if (!empty($q)) { $sql = "SELECT * FROM customers WHERE $q"; } else { $sql = "SELECT * FROM customers"; } try { $db = new db(); $db = $db->connect(); $stmt = $db->prepare($sql); foreach ($bindings as $value) { $stmt->bindParam(":$value", $parsedQuery["$value"]); } $stmt->execute(); $result = $stmt->fetchAll(PDO::FETCH_OBJ); $db = null; echo json_encode($result); } catch(PDOException $e){ echo '{"error": {"text": '.$e->getMessage().'}'; } }); Спасибо.
Зачем? И, если честно, код слишком индусский. В чем смысл такого усложнения? И зачем не глядя(!!!) формировать WHERE из гета? Это прям врата к тебе в БД. Открытые. С вывеской "Заходи кто хочет!"
По задумке должно соединять WHERE условия. Код-то индусский, не спорю. Касательно WHERE из гета, в какую сторону копнуть для закрытия врат?
Ну как минимум не пилить неглядя запрос на основе гет-параметров, даже не сверяя их с неким белым списком. Как максимум - отказаться от такого механизма в принципе. Абстракции это круто, но не в случае, когда они опираются на данные, приходящие извне. Data-driven logic вообще тема довольно тонкая и опасная. У нас тут не лабораторные задачи по лиспу. У нас тут веб. Надо быть параноиком и всегда исходить из того, что клиент - злоумышленник.
Fell-x27, спасибо за разъяснения. Зачастую не хватает стороннего мнения опытного человека и палки, чтобы по пальцам вовремя прихватывать. Попробую переписать без белого списка и поискать иные пути решения задачи.
@Fell-x27, а можно пример вредоносного кода, для наглядности, к моей индусской реализации? В customers есть поля id, first_name, last_name, phone.
Почитай документацию по MySQL. Секция WHERE принимает на вход любое логическое выражение. При этом каждый операнд выражения может быть получен абсолютно любым путем, включая селекты с джоинами со вложенными селектами. Плюс, вполне реально тебе вкрутить сюда инъекцию в последнем параметре для where. Хотя, если подумать, то этот колхоз после биндинга, технически вообще работать не должен. У тебя ошибок синтаксиса нет там, случайно при исполнении запросов, содержащих текстовые данные? Если работает, то тебе можно не парясь вкрутить инъекцию, да.