У меня есть следующая форма, которую пользователи заполняют:
<form name="form" action="" method="POST"> <table width="100%" border="0" cellpadding="2" cellspacing="2"> <tr> <td width="25%" ><div align="right"><strong>Name:</strong></div></td> <td width="75%" ><span id="sprytextfield1"> <input id="Cname"name="Name" type="text" placeholder="Please fill in your name"> <span class="textfieldRequiredMsg">A value is required.</span></span></td> </tr> <tr> <td><div align="right"><strong>Email:</strong></div></td> <td><span id="sprytextfield2"> <input id="Cemail"name="email" type="text" placeholder="eg sales@company.co.uk"> <span class="textfieldRequiredMsg">A value is required.</span><span class="textfieldInvalidFormatMsg">Invalid format.</span></span></td> </tr> <tr> <td><div align="right"><strong>Phone Number:</strong></div></td> <td> <input id="Cphone" name="Phone" type="text"placeholder="eg 5555-6666666"> </td> </tr> <tr> <td> </td> <td><input name="Manufacturer" type="hidden" value="<?php echo $row_emailProduct['Manufacturer']; ?>"> <input name="Model" type="hidden" value="<?php echo $row_emailProduct['Model']; ?>"> <input name="Color" type="hidden" value="<?php echo $row_emailProduct['Color']; ?>"> <input name="price" type="hidden" value="<?php echo $row_emailProduct['price']; ?>"> <input name="id" type="hidden" value="<?php echo htmlentities($_GET['id']); ?>"> <input name="insert" id="insert" type="submit" value="Send Request"></td> </tr></tr> </table> </form>
После отправки формы происходит следующее:
if (isset($_POST["insert"])){ $OK=false; $insertSQL = "INSERT INTO Item_intrest (Manufacturer, Model, Color, price, Name, Phone, email) VALUES (:Manufacturer, :Model, :Color, :price, :Name, :Phone, :email)"; $Result1 = $conn->prepare($insertSQL) or die(errorInfo()); $Result1->bindParam(':Manufacturer', htmlentities($_POST['Manufacturer']), PDO::PARAM_STR); $Result1->bindParam(':Model', htmlentities($_POST['Model']), PDO::PARAM_STR); $Result1->bindParam(':Color', htmlentities($_POST['Color']), PDO::PARAM_STR); $Result1->bindParam(':price', htmlentities($_POST['price']), PDO::PARAM_STR); $Result1->bindParam(':Name', htmlentities($_POST['Name']), PDO::PARAM_STR); $Result1->bindParam(':Phone', htmlentities($_POST['Phone']), PDO::PARAM_STR); $Result1->bindParam(':email', htmlentities($_POST['email']), PDO::PARAM_STR); $Result1->execute(); $OK = $Result1->rowCount(); /*email to shop */ $emailsubject = 'Product Request'; $webmaster = 'sales@company.co.uk'; /*data collection */ $Name = htmlentities($_POST['Name']); $email = htmlentities($_POST['email']); $Phone = htmlentities($_POST['Phone']); $item1 = htmlentities($_POST['Manufacturer']); $item2 = htmlentities($_POST['Model']); $item3 = htmlentities($_POST['Color']); $Price = htmlentities($_POST['price']); $Body = <<<EOD <br><hr><br> Name: $Name<br> Email: $email<br> Phone: $Phone<br> Product:$item1, $item2,$item3<br> Price: $Price<br> EOD; $headers = "From: $email\r\n"; $headers .= "content-type: text/html\r\n"; $succes = mail($webmaster, $emailsubject, $Body, $headers); if($OK){ header('Location: /thankyourequest.php?id=' . htmlentities($_GET['id']). ''); exit; }else { $errorInfo = $Result1->errorInfo(); if(isset($errorInfo[2])){ $error = $errorInfo[2]; } } }
По какой-то причине при сканировании возвращается
From: < [mailto:<] Sent: 20 April 2015 10:04 To: sales@company.co.uk Subject: Product Request Name: <script>alert("xssvuln")</script> Email: <script>alert("xssvuln")</script> Phone: <script>alert("xssvuln")</script> Product:<script>alert("xssvuln")</script>, <script>alert("xssvuln")</script>,<script>alert("xssvuln")</script> Price: <script>alert("xssvuln")</script>
Как вы можете видеть, я пытался предотвратить это с помощью htmlentities, как бы то ни было, этого недостаточно. Любая помощь приветствуется, чтобы предотвратить это
См. Также: Сохраненный XSS в WordPress 4.2, вызванный усечением столбца MySQL . Фильтрация на выходе предотвратила бы эти условия.
Вместо этого вы хотите просто использовать подготовленные инструкции и хранить данные голыми. (Вы должны все же проверить данные, конечно! Убедитесь, что они дали вам адрес электронной почты, когда вы попросили его, и т. Д.)
Когда вы извлекаете данные из базы данных для отображения на веб-странице, то есть когда вы хотите фильтровать. И вы хотите сделать это так (предполагая, что вам не нужно позволять пользователям предоставлять некоторый HTML-код):
echo htmlentities($row['column'], ENT_QUOTES | ENT_HTML5, 'UTF-8');
ENT_QUOTES | ENT_HTML5
ENT_QUOTES | ENT_HTML5
и 'UTF-8'
? Я предполагаю, что ваша веб-страница использует HTML5 (т.е. <!DOCTYPE html>
), а ваша кодировка – UTF-8 (т. <meta>
теге <meta>
а также в заголовке HTTP Content-Type
). Пожалуйста, отрегулируйте, если вы используете что-то другое.
Мы указываем ENT_QUOTES
чтобы сообщить htmlentities()
чтобы избежать символов кавычек ( "
и '
). Это полезно для ситуаций, таких как:
<input type="text" name="field" value="<?php echo $escaped_value; ?>" />
Если вам не удалось указать ENT_QUOTES
а злоумышленнику просто нужно передать " onload="alert('XSS');
как значение для этого поля формы и, прежде всего! Выполнение мгновенного клиентского кода.
Мы указываем 'UTF-8'
поэтому htmlentities()
знает, с каким персонажем работать. Причина, по которой мы это делаем, демонстрирует, что против mysql_real_escape_string()
некорректная (особенно mysql_real_escape_string()
) кодировка символов может победить стратегии экранирования на основе строк.
Обратите внимание, что это позволит избежать всех специальных символов HTML и запретить пользователям предоставлять любую разметку. Если вам нужно разрешить некоторый HTML, мы наметили лучшие стратегии предотвращения XSS . В двух словах:
Использование Twig? Нижеприведенный пример безопасен. Обратите внимание на использование блоков {% autoescape %}
для указания стратегии по умолчанию, но переопределяя ее с помощью |e('html')
для other_variable
:
{% autoescape 'html_attr' %} <p class="{{ variable }}" id="{{ var_two }}"> {{ other_variable|e('html') }} </p> {% endautoescape %}
это называется проблемой безопасности. Межсайтовый скриптинг, у вас есть много способов избежать этого,
Каков наилучший метод для дезинфекции пользовательского ввода с помощью PHP?
Например, если у вас есть возможность ввести адрес электронной почты, вы должны проверить его, как показано ниже:
<?php $email = filter_var($_POST['username'], FILTER_SANITIZE_EMAIL); ?>
Если есть возможность ввести строку, вы должны подтвердить, как показано ниже.
<?php $password = trim(filter_var($_POST['password'], FILTER_SANITIZE_STRING)); ?>
В вашем случае вам нужно сделать что-то вроде ниже
$Name = htmlentities($_POST['Name']); $email = htmlentities($_POST['email']);
Вместо вышеперечисленного следуйте методу очистки фильтра:
$email = filter_var($_POST['email'], FILTER_SANITIZE_EMAIL); $Name = trim(filter_var($_POST['Name'], FILTER_SANITIZE_STRING));