Во-первых, я хотел упомянуть использование preg_replace_callback
. Я знаю, что вы упомянули, что вы должны использовать preg_replace
(без объяснения причин), но сначала я скажу вам, что вы должны сделать, и объясню, почему preg_replace
- это плохой выбор.
Ваш код выглядит так:
$pc = preg_replace('#\[div(=(.*))?\](.*?)\[/div\]#iuUe', "\bbcode_div('\$2', '\$3')", $_POST["data"]);
Можно переписать следующим образом:
<?php
$regex = '{\[div(?:=(.*?))?\](.*??)\[/div\]}iu';
$pc = preg_replace_callback($regex, function ($matches) {
return bbcode_div($matches[1], $matches[2]);
});
Или, если вы все еще используете PHP 5.2 или более раннюю версию (обновление серьезно).
<?php
$regex = '{\[div(?:=(.*?))?\](.*??)\[/div\]}iu';
$pc = preg_replace_callback($regex, create_function('$matches', '
return bbcode_div($matches[1], $matches[2]);
'));
Теперь я собираюсь объяснить, почему /e
плохой выбор. Это дает ложное чувство безопасности. При замене двойных кавычек ваша безопасность практически нарушена.
<?php
$_POST['code'] = 'echo "broken";';
$_POST['data'] = '[div]{${eval($_POST[code])}}[/div]';
$pc = preg_replace('#\[div(=(.*))?\](.*?)\[/div\]#iuUe', 'bbcode_div("$2", "$3")', $_POST["data"]);
При использовании символов '
, addslashes()
сбрасывается, когда не должно (/e
использует addslashes
внутренне!). Поэтому, если пользователь введет символ "
, он будет изменен на \"
при выполнении вызова (в одинарных кавычках \
может экранировать только \
и '
, иначе он вставляется буквально). Это, вероятно, не то, что вы хотите. /e
модификатор не работает. Ну, по крайней мере, в PHP. Perl один хорошо ...
Это затронуло некоторые проекты, например roundcube, в котором использовался модификатор /e
. Это вызвало изменения в кодовой базе . Зачем беспокоиться о хакерских атаках, если вы можете защитить от них, просто не используя модификатор /e
.
Кроме того, прочитайте https://wiki.php.net/rfc/remove_preg_replace_eval_modifier (это уже принято, и следующая основная версия PHP (PHP 5.5 или PHP 6.0) не одобрит этот модификатор).