Как я могу удалить слово из строки? - PullRequest
1 голос
/ 23 октября 2019

Я выполняю небольшой эксперимент, добавляя строку JERRY к каждому ключевому слову sql в операторе sql, проверяя массив ключевых слов SQL, который я указываю. Я хочу удалить строку JERRY из переменной поиска, чтобы, если я набрал 'UNION (SELECT 1, fname, username, password FROM users); - в поле ввода поиска, напечатанный оператор sql должен выглядеть следующим образом;

SELECTJERRY * FROMJERRY shopping WHEREJERRY title LIKEJERRY '% a' UNION (ВЫБЕРИТЕ 1, имя, имя пользователя, пароль от пользователей); -% '

Цель в том, что я не хочуключевые слова SQL во входной переменной поиска, чтобы иметь строку JERRY.

НО прямо сейчас, это то, что я получаю;

SELECTJERRY * FROMJERRY покупки WHEREJERRY title LIKEJERRY '% a' UNIONJERRY (SELECT1, имя, имя пользователя, пароль от пользователей FROMJERRY); -% '

Как мне этого добиться?

$search = $_GET['search'];
if (empty($search)) {
    echo "Please fill in the search bar";

    exit();
}

$keywords = ["SELECT", "FROM", "WHERE", "LIKE", "AND", "OR", "ON","UNION", "JOIN"];
$sql = "SELECT * FROM shopping WHERE title LIKE '%$search%'";
$splittedSql = explode(" ", $sql);

foreach ($splittedSql as $sl) {

    if (in_array($sl, $keywords)) {

        $newstatement = $sl . "JERRY" . ' ';
    } else {
        $newstatement = $sl . ' ';
    }
    echo $newstatement;
}

Ответы [ 2 ]

2 голосов
/ 23 октября 2019

Проблема заключается в том, что вы проверяете свой статический запрос с помощью введенного пользователем значения $search. Достижение желаемых результатов потребует ограничения на замену ключевых слов.

Один из подходов заключается в том, чтобы сначала проверить введенное пользователем значение $search для указанных ключевых слов. Если оно существует, измените статический запрос. Затем вы можете применить предоставленное пользователем значение $search в последствии, что можно легко сделать, используя sprintf.

Вместо того, чтобы взорвать запрос, вы можете использовать preg_replace для применения значений ключевых слов. все сразу, используя группу захвата () и заменяющее значение $1JERRY. Вы можете использовать границы слов \b в шаблоне, чтобы избежать ложных срабатываний для таких слов, как sAND, tON, lORe и т. Д.

Наконец, используя stripos, проверьте значение $searchв отличие от in_array() и /i модификатора регулярных выражений, при сопоставлении и замене $keyword будет учитываться регистр.

Подход 1: https://3v4l.org/ie2Mj

$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 ключевое слово.

Подход 2: https://3v4l.org/iVbBc

$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);--%'
2 голосов
/ 23 октября 2019

Поскольку $search будет зависеть от explode, используя пробелы, мы можем предотвратить это, заменив пробелы уникальными символами:

  $search = str_replace(" ","uniquecharacters",$search);

, а затем заменим эти уникальные символы обратно пробелами / с

$keywords = ["SELECT", "FROM", "WHERE", "LIKE", "AND", "OR", "ON","UNION", "JOIN"];
$search = str_replace(" ","uniquecharacters",$search);
$sql = "SELECT * FROM shopping WHERE title LIKE '%$search%'";
$splittedSql = explode(" ", $sql);

foreach ($splittedSql as $sl) {

    if (in_array($sl, $keywords)) {  
       $newstatement = $sl . "JERRY" . ' ';
    } else {
       $newstatement = str_replace("uniquecharacters"," ",$sl);
       $newstatement = $sl . ' ';
    }
    echo $newstatement;
 }
...