Фильтрация ввода контактной формы

Проверяя мою контактную форму, я обнаружил уязвимости межсайтового скриптинга, но не знаю, как это исправить.

Затронутый параметр: name Используемый вектор: ">alert(document.cookie) Найден шаблон: \">alert(document.cookie) Полная атака: /http://############### ###/contact.php [name=\">alert(document.cookie) &email= &message=]

Затронутый параметр: email Используемый вектор: ">alert(document.cookie) Обнаружен шаблон: \">alert(document.cookie) Полная атака: /http://############### ###/contact.php [name= &email=\">alert(document.cookie) &message=]

Затронутый параметр: message Используемый вектор: ">alert(document.cookie) Обнаружен шаблон: \">alert(document.cookie) Полная атака: /http://################ ###/contact.php [name= &email= &message=\">alert(document.cookie)]

Мой текущий код формы выглядит так

<?php 
if (isset($_POST['submit'])) { 
    $error = ""; 

    if (!empty($_POST['name'])) { 
        $name = $_POST['name']; 
        if (!preg_match('/^[a-zA-Z0-9]+$/i', $name)){  
            $error .= "The name you entered is not valid. <br/>"; 
        } 
    } else { 
        $error .= "You didn't type in your name. <br />"; 
    } 

    if (!empty($_POST['email'])) { 
        $email = $_POST['email']; 
        if (!preg_match("/^[_a-z0-9]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,3})$/i", $email)){  
            $error .= "The e-mail address you entered is not valid. <br/>"; 
        } 
    } else { 
        $error .= "You didn't type in an e-mail address. <br />"; 
    } 

    if (!empty($_POST['messagesubject'])) { 
        $messagesubject = $_POST['messagesubject']; 
    } else { 
        $error .= "You didn't type in a subject. <br />"; 
    } 

    if (!empty($_POST['message'])) { 
        $message = $_POST['message']; 
    } else { 
        $error .= "You didn't type in a message. <br />"; 
    } 

    if(($_POST['code']) == $_SESSION['code']) {  
        $code = $_POST['code']; 
    } else {  
        $error .= "The captcha code you entered does not match. Please try again. <br />";     
    } 

    if (empty($error)) { 
        $from = 'From: ' . $name . ' <' . $email . '>'; 
        $to = "[email protected]"; 
        $subject = strip_tags("CWS - Contact Us - \n" . $messagesubject); 
        $content = strip_tags("Name: " . $name . "\nSubject: " . $messagesubject . "\nMessage: \n" . $message); 
        $success = "<h2>Thank you! <span>Your message has been sent!</span></h2>"; 
        mail($to,$subject,$content,$from); 
        $emailSent = true; 
    } 
} 
?> 

Форма

<form action="contact.php" method="post"> 

    <label>Name:</label> 
    <input type="text" name="name" value="<?php if ($_POST['name']) { echo $_POST['name']; } ?>" /> 

    <label>Email:</label> 
    <input type="text" name="email" value="<?php if ($_POST['email']) { echo $_POST['email']; } ?>" /> 

    <label>Subject:</label> 
    <input type="text" name="messagesubject" value="<?php if ($_POST['messagesubject']) { echo $_POST['messagesubject']; } ?>" /> 

    <label>Message:</label><br /> 
    <textarea name="message" rows="20" cols="20"><?php if ($_POST['message']) { echo $_POST['message']; } ?></textarea> 

    <label>Please input the following code: <img src="captcha.php"></label> 
    <input type="text" name="code"> <br />  

    <button type="submit" class="colorButton" name="submit" value="Send message">Send Message</button> 

</form>

Любая помощь очень ценится.


person Aaron Foster    schedule 22.10.2012    source источник


Ответы (3)


У вашего поколения HTML есть недостаток:

 value="<?php if ($_POST['name']) { echo $_POST['name']; } ?>"

Вы всегда должны избегать своих выходных переменных, т.е.:

 value="<?php if ($_POST['name']) { echo htmlspecialchars($_POST['name']); } ?>"

См. также: htmlspecialchars() или htmlentities()

person Ja͢ck    schedule 22.10.2012
comment
Спасибо за совет. Сразу вносим изменения. - person Aaron Foster; 22.10.2012

никогда не доверяйте пользовательскому вводу, какой-то парень может вставлять коды javascript, которые могут нанести вред вашей системе или тому подобное, поэтому вы уязвимы для межсайтового скриптинга, дезинфицируйте вводы, которые публикуются с помощью этой функции:

function xss_protect($data, $strip_tags = false, $allowed_tags = "\"\'") { 
if($strip_tags) {
    $data = strip_tags($data, $allowed_tags . "<b>");
}

if(stripos($data, "script") !== false) { 
    $result = str_replace("script","scr<b></b>ipt", htmlentities($data, ENT_QUOTES,"UTF-8")); 
} else { 
    $result = htmlentities($data, ENT_QUOTES, "UTF-8"); 
} 

return $result;
}

Чтобы использовать функцию, например, используйте так:

$code = xss_protect($_POST['code']); 
person Community    schedule 22.10.2012
comment
Почему вы чувствуете необходимость обращаться со сценарием особым образом? - person Erlend; 22.10.2012

Вы должны использовать некоторые хорошие методы программирования, например:

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

$name = false;
$email = false;
$message = false;
$messagesubject = false;

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

if ( isset( $_POST['name'] ) !== false ) {
    // validate the content
    $name = process_you_choose_to_clean( $_POST['name'] );
}
if ( isset( $_POST['email'] ) !== false ) {
    // validate the content
    $name = process_you_choose_to_clean( $_POST['email'] );
}
if ( isset( $_POST['message'] ) !== false ) {
    // validate the content
    $name = process_you_choose_to_clean( $_POST['message'] );
}
if ( isset( $_POST['messagesubject'] ) !== false ) {
    // validate the content
    $name = process_you_choose_to_clean( $_POST['messagesubject'] );
}

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

<input type="text" name="name" value="<?php { echo( $name ); } ?>" />

Что касается очистки, рассмотрите упомянутые варианты, а также используйте filter_var. опции PHP

person PatomaS    schedule 22.10.2012
comment
Спасибо, что исправили сейчас, и очень ценю помощь. - person Aaron Foster; 22.10.2012