我在html中有一个联系表单,我想知道如何提高安全性。我的表单的html如下:
<form class="form" id="form" method="post">
<input type="hidden" id="token" name="token" value="<?php echo hash_hmac('sha256', 'some_string', $_SESSION['token']); ?>">
<input type="text" class="form-control" placeholder="Nome" id="nome" name="nome">
<input type="text" class="form-control" placeholder="Email" id="email" name="email">
<select class="form-control" id="assunto" name="assunto">
<option value="1">Mensagem</option>
<option value="2">Testemunho</option>
<option value="3">Reclamação</option>
<option value="4">Outro</option>
</select>
<textarea class="form-control" Placeholder="Mensagem" id="mensagem" name="mensagem" rows="5"></textarea>
<div class="text-left" id="msgs">
<p class="p-mb-30">* Todos os campos são de preenchimento <strong>obrigatório</strong>!</p>
</div>
<input type="submit" class="button sendMsgs" value="Enviar" name="send">
</form>
表单将与ajax一起发布:(注意:我不做javascript验证,因为任何用户都可以使用javascript,所以如果我错了,请纠正我但不是必要的。)
$('#form').on('submit', function(e) {
e.preventDefault();
$.ajax({
type: "POST",
url: 'php/send-email.php',
cache: false,
data: $('.form').serialize(),
success: function(response) {
var result = $.parseJSON(response);
$('#msgs').removeClass();
$('#msgs').addClass('text-left');
$('#msgs').addClass(result['type']);
$('#msgs p').html(result['msg']);
$('.form').find(':input').removeClass('form-error');
$.each(result['fields'], function(k, v) {
var id = '#'+v;
$(id).addClass('form-error');
})
if(result['type'] == 'success') {
$('.form')[0].reset();
}
},
error: function (xhr, ajaxOptions, thrownError) {
$('#msgs').addClass('error');
$('#msgs p').html('Ups! Parece que algo correu mal. Por favor, contacte-nos de outra forma.');
}
});
});
并在php页面上我进行验证等......:
session_start();
if($_SERVER['REQUEST_METHOD'] === 'POST' && !empty($_POST)) {
// i know this function is a little exagerated but im just testing
function sanitize($input) {
$input = trim($input);
$input = htmlentities($input);
$input = stripslashes($input);
$input = preg_replace('/<[^>]*>[^<]*<[^>]*>/', '', $input);
$input = preg_replace('#\s*\<.+\>\s*#U', '', $input);
return($input);
}
$msg = sanitize($_POST['mensagem']);
$nome = sanitize($_POST['nome']);
$email= sanitize($_POST['email']);
$assunto = sanitize($_POST['assunto']);
$token = sanitize($_POST['token']);
$error = false;
$fields = array();
$allowed = ['nome', 'email', 'assunto', 'mensagem', 'token', 'send'];
foreach($_POST as $key=>$value) {
if(!in_array($key, $allowed)) {
$error = true;
}
}
// check if request is made from the server or not
if ((isset($_SERVER['HTTP_REFERER']) && !empty($_SERVER['HTTP_REFERER']))) {
if (strtolower(parse_url($_SERVER['HTTP_REFERER'], PHP_URL_HOST)) != strtolower($_SERVER['HTTP_HOST'])) {
$error = true;
}
}
// check the token against csrf
$calc = hash_hmac('sha256', 'some_string', $_SESSION['token']);
if (!hash_equals($calc, $_POST['token'])) {
$error = true;
array_push($fields, 'token');
}
if(strlen($msg) < 3) {
$error = true;
array_push($fields, 'mensagem');
}
if(strlen($nome) < 3) {
$error = true;
array_push($fields, 'nome');
}
if(!is_numeric($assunto) || strlen($assunto) > 1) {
$error = true;
array_push($fields, 'assunto');
}
if(strlen($email) < 3 || !filter_var($email, FILTER_VALIDATE_EMAIL)) {
$error = true;
array_push($fields, 'email');
}
if($error) {
$msg = 'Existem erros no formulário. Por favor, certifique-se que o preencheu correctamente.';
$type = 'error';
}
else {
// Send email here
// script to send email.
}
$result = array(
'msg' => $msg,
'type' => $type,
'fields' => $fields
);
// here i send the result back to my browser
echo json_encode($result);
}
else {
// do something here
}
我的问题是:这个表格足够安全吗?我无法访问服务器,所以我只能尽可能安全。我在正确的道路上吗?我该怎么做才能让它更安全?我应该使用phpMailer吗?