Безопасно ли превращать URL-адреса в ссылки?

Я хочу превратить URL-адреса в комментариях пользователей в ссылки.

У меня нет времени тестировать раздутые анти-xss-библиотеки, такие как HTML Purify, поэтому я бы не разрешал использовать теги html.

Я просто хочу, чтобы все проходило через htmlentities() и nl2br(), а затем использовало preg_replace() для поиска URL-адресов и превращения их в ссылки (html-теги 'a').

Небезопасно ли брать найденные URL-адреса и помещать их в href='' ?

Если нет, что я могу с этим поделать?


person HappyDeveloper    schedule 19.03.2011    source источник
comment
Это зависит от того, что вы подразумеваете под URL и под безопасным.   -  person Gumbo    schedule 19.03.2011
comment
У меня нет времени тестировать раздутые анти-xss-библиотеки вроде HTML Purify. Будем надеяться, что любые библиотеки, которые вы используете, уже были протестированы, так что вы можете просто их использовать. Зачем дублировать усилия и тестировать чужой код?   -  person Merlyn Morgan-Graham    schedule 19.03.2011
comment
Вы можете сделать это. Большинство блогов делают это. Даже ТАК делает это   -  person JohnP    schedule 19.03.2011
comment
Действительно, ваш подход к побегу разумен и достаточен. URL-адресам не присуща небезопасность. Просто ограничьте допустимую длину URL (‹300).   -  person mario    schedule 19.03.2011
comment
@JohnP Я знаю, что это делается везде, но я не могу сказать, как это делается, просто просматривая полученный HTML. И даже если бы я мог, тот факт, что он используется повсеместно, ничего не значит. Блоги взламывают каждый день   -  person HappyDeveloper    schedule 19.03.2011
comment
@Gumbo Если мы говорим о XSS, как вы думаете, что я имею в виду под «безопасным»? А если мы говорим о.. Подождите, URL не может иметь несколько значений, не так ли? @ Merlyn Morgan-Graham Я не могу просто выбрать случайные библиотеки и использовать их, потому что «надеюсь, они были протестированы». И даже если бы это была хорошо известная и проверенная библиотека, я должен сам провести некоторые базовые тесты, например: проверить, действительно ли она превращает URL-адреса в ссылки.   -  person HappyDeveloper    schedule 19.03.2011


Ответы (1)


Да, это должно быть безопасно. Если вам интересно, как, вот функция, которую я использую для этого (я упростил ее для целей этого поста):

function formatPost($string) {
    return nl2br(
        preg_replace_callback(
            '~https?://([^/\s]+)(?:/((?>[/\w]+|\S(?!\s|$))*))?~',
            function($matches) {
                $url  = $matches[0];
                $host = $matches[1];
                $path = isset($matches[2]) ? $matches[2] : '';
                $follow = false;

                if ('' == $path) {
                    $text = $host;
                } elseif ($_SERVER['HTTP_HOST'] == $host) {
                    $text = $path;
                    $follow = true;
                } else {
                    $text = $host . '/' . $path;
                }

                return '<a href="' . $url . '"' . (!$follow ? ' rel="nofollow"' : '') . '>' . $text . '</a>';
            },
            htmlspecialchars($string)
        )
    );
}
person NikiC    schedule 19.03.2011
comment
-1 Эта функция несовершенна: formatPost('http://"><script>alert("XSS")</script>foo') - person Gumbo; 19.03.2011
comment
@Gumbo: Нет, это не так: как я уже упоминал в своем последнем предложении, эта функция принимает уже экранированный ввод (потому что я использую ее как фильтр pre_escape для Twig). Я изменил свой пост, добавив htmlspecialchars, и удалил примечание. - person NikiC; 19.03.2011