SQLi注入预防和错误报告问题

时间:2015-10-04 09:09:55

标签: php mysql security code-injection

我分别知道这些问题很常见,虽然我已经搜索了可用的答案,并且没有太多运气找到MySQLi或新PHP版本的大量信息。希望你们中的一位专家可以帮助我。

我有一个简单的'运行PHP脚本到数据库的html表单似乎工作得很好,还包括一个文件上传,也可以。我对安全和保护有一些了解,我很确定我的脚本根本不安全。如果脚本没有正常运行,我也会遇到问题。

我尝试添加代码,例如:

} else {
  header('Location: addpcn.php?pcnerror=4');    
}

虽然有这么多'}'在我的代码的末尾,我不知道在哪里添加它。此外,如果代码不成功并且永远不会显示错误,我可能会忘记提醒用户的很多问题?

到目前为止,这是我的代码:

if(isset($_POST['pcn'])){
    $pcn_number = $_POST['pcn_number'];
    $vehicle_reg = $_POST['vehicle_reg'];
    $street_name = $_POST['street_name'];
    $offence = $_POST['offence'];
    $vehicle_make = $_POST['vehicle_make'];
    $vehicle_model = $_POST['vehicle_model'];
    $vehicle_colour = $_POST['vehicle_colour'];
    $date_issued = $_POST['date_issued'];
    $time_issued = $_POST['time_issued'];
    $witnessed_from = $_POST['witnessed_from'];
    $witnessed_to = $_POST['witnessed_to'];
    $issued_by = $_POST['issued_by'];



$target_dir = "evidence/";
$target_file = $target_dir . basename($_FILES["evidence"]["name"]);
$name = $_FILES["evidence"]["name"];
$uploadOk = 1;
$imageFileType = pathinfo($target_file,PATHINFO_EXTENSION);
// Check if image file is a actual image or fake image
    $check = getimagesize($_FILES["evidence"]["tmp_name"]);
    if($check !== false) {
        $uploadOk = 1;
    } else {
        $uploadOk = 0;
    }

// Check if file already exists
if (file_exists($target_file)) {
    $uploadOk = 0;
}

// Allow certain file formats
if($imageFileType != "jpg" && $imageFileType != "png" && $imageFileType != "jpeg"
&& $imageFileType != "gif" ) {
    $uploadOk = 0;
}
// Check if $uploadOk is set to 0 by an error
if ($uploadOk == 0) {
    echo '';
// if everything is ok, try to upload file
} else {
    if (move_uploaded_file($_FILES["evidence"]["tmp_name"], $target_file)) {
        echo '';
    } else {
        echo '';
    }
}   

if(empty($pcn_number) === true){
    header('Location: addpcn.php?pcnerror=2');  
} else {
if(empty($vehicle_reg) === true){
    header('Location: addpcn.php?pcnerror=2');  
} else {
if(empty($street_name) === true){
    header('Location: addpcn.php?pcnerror=2');  
} else {
    if(empty($offence) === true){
    header('Location: addpcn.php?pcnerror=2');  
} else {
    if(empty($vehicle_make) === true){
    header('Location: addpcn.php?pcnerror=2');  
} else {
    if(empty($vehicle_colour) === true){
    header('Location: addpcn.php?pcnerror=2');  
} else {
if(empty($date_issued) === true){
    header('Location: addpcn.php?pcnerror=2');  
} else {
if(empty($time_issued) === true){
    header('Location: addpcn.php?pcnerror=2');  
} else {
if(empty($witnessed_from) === true){
    header('Location: addpcn.php?pcnerror=2');  
} else {
if(empty($witnessed_to) === true){
    header('Location: addpcn.php?pcnerror=2');  
} else {
if(empty($issued_by) === true){
    header('Location: addpcn.php?pcnerror=2');  
} else {
mysqli_query($conn, "INSERT INTO parkingtickets (id, pcn_number, date_issued, vehicle_reg, vehicle_make, vehicle_model, vehicle_colour, street_name, witnessed_from, witnessed_to, time_issued, offence, issued_by, special_fine_discount, special_fine, paid, paid_date, evidence) VALUES ('','$pcn_number', '$date_issued', '$vehicle_reg', '$vehicle_make', '$vehicle_model', '$vehicle_colour', '$street_name', '$witnessed_from', '$witnessed_to', '$time_issued', '$offence', '$issued_by', '', '', '0', '', '$name')"); 
header('Location: addpcn.php?pcnerror=3');  
}
}
}
}
}
}
}
}
}
}
} 
} 

我知道你们会认为这是错误的做法,但我仍然是一个新手,希望你能够指出我正确的方向与一些更好的方法此代码的错误报告以及MySQLi注入预防的示例可以大大改进。

谢谢!

1 个答案:

答案 0 :(得分:1)

我对你的代码做了一些修改。为了保持一致性,我对所有变量使用了下划线而不是camelCase约定。数据库(parking_tickets)中的表名相同。 验证您的输入是一个好习惯,因此,如果其中一个输入的类型不正确,您将能够显示它的信息消息。 此外,我使用关联数组而不是多个if语句。 感谢@ Scott Arciszewski我添加了准备好的语句,省略了付费列,因此请确保它在数据库中的默认值为0。

if (isset($_POST['pcn'])) {

    $pcn_number = $_POST['pcn_number'];
    $vehicle_reg = $_POST['vehicle_reg'];
    $street_name = $_POST['street_name'];
    $offence = $_POST['offence'];
    $vehicle_make = $_POST['vehicle_make'];
    $vehicle_model = $_POST['vehicle_model'];
    $vehicle_colour = $_POST['vehicle_colour'];
    $date_issued = $_POST['date_issued'];
    $time_issued = $_POST['time_issued'];
    $witnessed_from = $_POST['witnessed_from'];
    $witnessed_to = $_POST['witnessed_to'];
    $issued_by = $_POST['issued_by'];

    //User input validation chekcs

    $is_valid = true;

    //e.g
    if (!(is_numeric((int)$pcn_number) && ctype_digit((string)$pcn_number))) {
        $is_valid = false;
        echo 'The pcn_number is not valid. It must be an integer.';
    }

    if (!(is_numeric((int)$vehicle_reg) && ctype_digit((string)$vehicle_reg))) {
        $is_valid = false;
        echo 'The vehicle_reg is not valid. It must be an integer.';
    }

    if (!$is_valid) {
        //Do something here and dont continue if one of the inputs is not valid
    }

    $target_dir = "evidence/";
    $target_file = $target_dir . basename($_FILES["evidence"]["name"]);
    $name = $_FILES["evidence"]["name"];
    $upload_ok = true;
    $image_file_type = pathinfo($target_file, PATHINFO_EXTENSION);
    // Check if image file is a actual image or fake image
    $check = getimagesize($_FILES["evidence"]["tmp_name"]);
    if ($check !== false) {
        $upload_ok = true;
    } else {
        $upload_ok = false;
    }

    // Check if file already exists
    if (file_exists($target_file)) {
        $upload_ok = false;
    }

    // Allow certain file formats
    $valid_formats = array('jpg', 'png', 'jpeg', 'gif');
    if (!in_array($image_file_type, $valid_formats)) {
        $upload_ok = false;
    }

    // Check if $uploadOk is set to false by an error
    if ($upload_ok === false) {
        echo '';
    // if everything is ok, try to upload file
    } else {
        if (move_uploaded_file($_FILES["evidence"]["tmp_name"], $target_file)) {
            echo '';
        } else {
            echo '';
        }
    }

    $checks = array(
        array (
            'var'=>$pcn_number,
            'condition'=>true,
            'location'=>'addpcn.php?pcnerror=2'
        ),
        array (
            'var'=>$vehicle_reg,
            'condition'=>true,
            'location'=>'addpcn.php?pcnerror=2'
        ),
        /*
         * More elements here
        */
    );

    foreach($checks as $key => $value) {
        if (empty($value['var']) === $value['condition'] ) {
            header('Location: '.$value['location']);
            exit;
        }
    }

    $connection = mysqli_connect('localhost', 'root', 'your_password', 'your_database');
    mysqli_set_charset($connection, 'utf8');
    if (!$connection) {
        die("Database connection failed: " . mysqli_error());
    }

    $stmt = mysqli_prepare($connection, "INSERT INTO parking_tickets (pcn_number, date_issued, vehicle_reg, vehicle_make, vehicle_model, vehicle_colour, street_name, witnessed_from, witnessed_to, time_issued, offence, issued_by, evidence) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?");
    if (mysqli_stmt_bind_param($stmt, 'sssssssssssss', $pcn_number, $date_issued, $vehicle_reg, $vehicle_make, $vehicle_model, $vehicle_colour, $street_name, $witnessed_from, $witnessed_to, $time_issued, $offence, $issued_by, $name)) {
         mysqli_stmt_execute($stmt);
         header('Location: addpcn.php?pcnerror=3');  
         exit;
    }

}