Проблема заключается в том, что вы проверяете свой статический запрос с помощью введенного пользователем значения $search
. Достижение желаемых результатов потребует ограничения на замену ключевых слов.
Один из подходов заключается в том, чтобы сначала проверить введенное пользователем значение $search
для указанных ключевых слов. Если оно существует, измените статический запрос. Затем вы можете применить предоставленное пользователем значение $search
в последствии, что можно легко сделать, используя sprintf
.
Вместо того, чтобы взорвать запрос, вы можете использовать preg_replace
для применения значений ключевых слов. все сразу, используя группу захвата ()
и заменяющее значение $1JERRY
. Вы можете использовать границы слов \b
в шаблоне, чтобы избежать ложных срабатываний для таких слов, как sAND
, tON
, lORe
и т. Д.
Наконец, используя stripos
, проверьте значение $search
в отличие от in_array()
и /i
модификатора регулярных выражений, при сопоставлении и замене $keyword
будет учитываться регистр.
$search = 'a\' UNION (SELECT 1, fname, username, password FROM users);--';
$keywords = ["SELECT", "FROM", "WHERE", "LIKE", "AND", "OR", "ON","UNION", "JOIN"];
//sprintf requires textual percent signs to be escaped as %%
$query = 'SELECT * FROM shopping WHERE title LIKE \'%%%s%%\'';
foreach ($keywords as $w) {
if (false !== stripos($search, $w)) {
//found a keyword build the replacement capture groups.
$patterns = '/\b(' . implode('|', $keywords) . ')\b/i';
$query = preg_replace($patterns, '$1JERRY', $query);
break;
}
}
printf($query, $search);
Альтернативой итерации по $keywords
было бы использование preg_match
для определения, содержит ли значение $search
ключевое слово.
$search = 'a\' UNION (SELECT 1, fname, username, password FROM users);--';
$keywords = ["SELECT", "FROM", "WHERE", "LIKE", "AND", "OR", "ON","UNION", "JOIN"];
$patterns = '/\b(' . implode('|', $keywords) . ')\b/i';
$query = 'SELECT * FROM shopping WHERE title LIKE \'%%%s%%\'';
if (preg_match($patterns, $search)) {
$query = preg_replace($patterns, '$1JERRY', $query);
}
printf($query, $search);
Результаты для обоих подходов:
SELECTJERRY * FROMJERRY shopping WHEREJERRY title LIKEJERRY '%a' UNION (SELECT 1, fname, username, password FROM users);--%'