Должен ли Я повторить Ссылки, Отправленные Пользователем Здесь, С помощью strip_tags() или htmlspecialchars()?

#php #htmlspecialchars #strip-tags

Вопрос:

Я должен безопасно повторить отправленную пользователем ссылку на моей странице, чтобы повторение отправленного пользователем URL-адреса не содержало html или javascript, которые разбивают html моей страницы. Под разрывом html я подразумеваю, что злоумышленник добавляет html-теги в поле ввода отправки url-адреса (в веб-форме отправки моей ссылки), и его ввод html-кода нарушает html-код на моей странице во время вывода его URL-адреса в качестве ссылки на моей странице. Или пользовательская реклама Javascipt, которая предупреждает или перенаправляет других посетителей на фишинговые сайты с моей страницы. Необходимо предотвратить отправку злоумышленниками URL-адресов, содержащих такие части, как:

 ?search=<script>alert('hacked')</script>
 

Действительно нужно запретить пользователям делать такие вещи. Не позволяйте им добавлять коды, когда, когда другие мои посетители загружают мою страницу или переходят по ссылке, отправленной злоумышленником, они не запускают вредоносные коды или не перенаправляются на вредоносные сайты.
У меня есть два варианта. Не уверен, какой из них действителен …
Какое из этих двух является действительным эхом и какого из них я должен придерживаться:

A.

 //WHICH OF THE FOLLOWING TWO ECHOES IS BEST ?
//OPTION 1
echo 'Link: <a href=' .'"' .strip_tags($url) .'"' .'>' .'<b>' .strip_tags($url) .'</b>' .'</a>'; echo '<br>';
 

B.

 //OPTION 2
echo 'Link: <a href=' .'"' .htmlspecialchars($url) .'"' .'>' .'<b>' .htmlspecialchars($url) .'</b>' .'</a>'; echo '<br>'; 
 

контекст

 $query = "SELECT id,date_and_time,domain,domain_email,ip,url,anchor,description,keyword From $table WHERE $column = ? LIMIT $offset,$max";
$stmt = mysqli_stmt_init($conn);
if(mysqli_stmt_prepare($stmt,$query))
{
    mysqli_stmt_bind_param($stmt,'s',$find);
    mysqli_stmt_execute($stmt);
    if($result = mysqli_stmt_get_result($stmt))
    {
        $columns = mysqli_fetch_array($result);
        
        $submission_id = $columns['id'];
        $submission_date_and_time = $columns['date_and_time'];
        $domain = $columns['domain'];
        $domain_email = $columns['email'];
        $ip = $columns['ip'];
        $url = $columns['url'];
        $anchor = $columns['anchor'];
        $description = $columns['description'];
        $keyword = $columns['keyword'];
        $keyphrase = $columns['keyphrase'];
            
        echo 'Submission Id: ' .$submission_id; echo '<br>';
        echo 'Submission Date And Time: ' .$submission_date_and_time; echo '<br>';
        echo 'Email: ' .$domain_email; echo '<br>';
        echo 'Domain: ' .$domain; echo '<br>';
        echo 'Url: ' .$url; echo '<br>';
        echo 'Anchor: ' .$anchor; echo '<br>';
        echo 'Description: ' .$description; echo '<br>';
        echo 'Keyword: ' .$keyword; echo '<br>';
        echo 'Keyphrase: ' .$keyword; echo '<br>';
        //WHICH OF THE FOLLOWING TWO ECHOES IS BEST ?
        //OPTION 1
        echo 'Link: <a href=' .'"' .strip_tags($url) .'"' .'>' .'<b>' .strip_tags($url) .'</b>' .'</a>'; echo '<br>';
        //OPTION 2
        echo 'Link: <a href=' .'"' .htmlspecialchars($url) .'"' .'>' .'<b>' .htmlspecialchars($url) .'</b>' .'</a>'; echo '<br>'; 
    }
    else
    {
        //Error Messages for Production Mode only.
        echo 'Record fetching failed!';
        echo 'Error: ' .mysqli_stmt_error($stmt);
        echo 'Error: ' .mysqli_stmt_errno($stmt);
    }
mysqli_stmt_close($stmt);
}
mysqli_close($conn);
 

Или, если у вас есть лучший способ кодирования для безопасного вывода ссылок, отправленных пользователями, я хотел бы посмотреть, как вы это делаете.

Комментарии:

1. Каковы ожидаемые входные данные для пользователя? Часто ли они должны иметь возможность помещать данные HTML в базу данных?

2. @Нико Хаасе, Нет! Они должны вводить только простой URL-адрес. Но озорной пользователь может ввести вредоносный код. Нужно сорвать это.

Ответ №1:

Всегда используйте htmlspecialchars() при выводе чего-либо в контексте HTML. Просто возьмите за привычку делать это для каждой строки, независимо от того, что она содержит.

Что касается strip_tags() , то многие люди сомневаются в его полезности. Это просто тупое регулярное выражение, которое удаляет информацию между < и > . Это может защитить вас от некоторых атак, но это определенно не мера безопасности. Эффект может быть только случайным. Если вам нужно удалить информацию между < и > , вам, вероятно, лучше использовать обычное регулярное выражение, которое может быть быстрее и проще в реализации.

Если URL-адрес получен из пользовательского ввода, то этот ввод необходимо проверить, чтобы он был правильным URL-адресом. PHP имеет фильтр FILTER_VALIDATE_URL для проверки URL-адресов, который может использоваться для отклонения недопустимого ввода.