清理输入数据php

时间:2014-07-20 13:33:16

标签: php regex mysqli

我的网站 rexhin.al 中有联系表单,访问者可以与我联系。它只有3个字段:姓名,电话号码和消息。

这是我用于清理将在数据库中写入的输入数据的函数。我在stackoverflow上检查了php manual和几个问题,我来到了这个解决方案。 这是一种安全的数据清理方法吗? 功能是否正确? 订单真的重要吗?

spl_autoload_register(function ($class) {
    include '../classes/' . $class . '.class.php';
});

/*
    beje qe nqs ekziston ip bej update vtm time dhe ++$count te ajo ip;
*/

$db = DB::get_instance();   

function sanatize($input) {
    $db = DB::get_instance();
    //mysqli real escape string for all vars.
    //preg_replace for whitespaces, tabs, new lines.
    //strip html tags.
    //convert html tags.
    //strip slashes.
    //htmlentities: htmlentities — Convert all applicable characters to HTML entities.
    //nuk duhet sepse kemi strip tags.

    //trim string
    $trimed_string = trim($input);
    //filter string using php FILTER_SANITIZE_STRING filter.
    $filtered_string = filter_var($trimed_string, FILTER_SANITIZE_STRING);
    //remove slashes
    $no_slash_string = stripslashes($filtered_string);
    //convert special characters to HTML entities
    $conv_string = htmlspecialchars($no_slash_string);
    //strip html tags
    $stripped_tags_string = strip_tags($conv_string);
    //replace whitespaces
    $filtered_string = preg_replace('#[\s]+#', ' ', $stripped_tags_string);
    $safe_string = $mysqli_escaped_string = $db->mysqli->real_escape_string($filtered_string);

    return $safe_string;
}

//send message
if ($_SERVER["REQUEST_METHOD"] == "POST") {
    if(isset($_POST["name"]) && isset($_POST["tel"]) && isset($_POST["message"])) {

        $name = sanatize($_POST["name"]);
        $tel = intval(sanatize($_POST["tel"]));

        //sepse intval ja heq zeron.
        $message = trim(sanatize($_POST["message"]));
        $time = time();

        //name validation.      
        //only letter and spaces.
        if(!preg_match('/^[a-zA-Z\s]+$/', $name)) {
            echo "name should contain only letters.";
        } else if(strlen($_POST["name"]) < 3) {
            echo "name should be three chars min.";
        } else if(!preg_match('/^[1-9][0-9]*$/', $tel)) {
            echo "your phone number should contain only numbers.";
        } else if(strlen($tel) != 9) {
            echo "your phone number must be 10 digits.";
        } else if(in_array(substr($tel, 0, 3), array(066, 067, 068, 069))) {
            echo "your phone number must begin with 066, 067, 068 or 069.";
        } else if(strlen($message) == 0) {
            echo "message should be 10 letters min.";
        } else {
            //insert into db.
            $query = "insert into `messages` (name, tel, message, time) VALUES ('$name', '$tel', '$message', '$time')";
            $db->mysqli->query($query);
            echo "sent";
        }
    }
}

1 个答案:

答案 0 :(得分:1)

相关位是:

filter_var($trimed_string, FILTER_SANITIZE_STRING);
$db->mysqli->real_escape_string($filtered_string);

虽然有人可能会说准备好的语句比手动转义更容易使用(因此你不太可能错过字段),从输入的角度来看,这应该足够了。如果你正确地注意SQL注入,即使缺少filter_var()也不会特别糟糕。

但是您还对用户数据进行了大量编辑,这些编辑被误导:

stripslashes($filtered_string);
htmlspecialchars($no_slash_string);
strip_tags($conv_string);
preg_replace('#[\s\t\n]+#', ' ', $stripped_tags_string);

如果我无法恢复用户提供的确切输入数据并且您基本上删除了任意字符并破坏了数据,我就不会认为联系表格可靠。

我认为根本问题是一些误解:

  1. 数据卫生不是绝对的。一个给定的数据是否被认为是安全的完全是上下文敏感的。例如,HTML标签与SQL无关。

  2. 您不必删除特殊字符以确保其安全。你只需要妥善处理它们。