使用 JS fetch 和 PHPMailer 的联系表单有多安全?
How secure is my contact form using JS fetch and PHPMailer?
我目前正在使用 vue-cli 构建一个没有真正后端的小型网站。
由于我在 php(以及一般的后端)方面是一个真正的土豆,我想知道我在这个网站上的联系表格有多安全,如果不够安全该怎么办。
总而言之,我正在从我的 vue 应用程序调用 fetch() 到我服务器上的 mail.php 文件。
此 mail.php 文件使用 PHPMailer 将电子邮件从我域的一个电子邮件地址发送到我的另一个地址。
到现在为止一切正常。
这是我发送邮件相关的JS :
sendMail () {
this.sendRequest()
.then(r => {
if (r.mailSent === 'ok') {
// mail sent callback
}
})
},
async sendRequest () {
const response = await fetch('./mail.php', {
method: 'post',
headers: {
'content-type': 'application/json'
},
body: JSON.stringify({
subject: 'Message de ' + this.firstNameInput + ' ' + this.lastNameInput + ' via mysite.com',
body: '<html>' +
'<body>' +
'<p>De : ' + this.firstNameInput + ' ' + this.lastNameInput + '</p>' +
'<p>Email : ' + this.mailInput + '</p>' +
'<p>Message :<br>' + this.messageInput.replace(/\n/g, '<br>') + '</p>' +
'</body>' +
'</html>',
altBody: 'De : ' + this.firstNameInput + ' ' + this.lastNameInput + ' /// Email : ' + this.mailInput + ' /// Message :' + this.messageInput
})
})
return response.json()
}
这是我的 mail.php 文件的内容:
<?php
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
require './PHPMailer/src/Exception.php';
require './PHPMailer/src/PHPMailer.php';
require './PHPMailer/src/SMTP.php';
header('Content-Type: application/json');
include './mailSettings.php'; // contains $site, $mailFrom, $mailTo, $senderName and $recipientName
if(@isset($_SERVER['HTTP_REFERER']) && $_SERVER['HTTP_REFERER'] == $site) {
$contentType = isset($_SERVER["CONTENT_TYPE"]) ?trim($_SERVER["CONTENT_TYPE"]) : '';
if ($contentType === "application/json") {
$content = stripslashes(trim(file_get_contents("php://input")));
$decoded = json_decode($content, true);
if(!is_array($decoded)) {
echo '{"status":"error"}';
} else {
$mail = new PHPMailer(TRUE);
try {
$mail->setFrom($mailFrom, $senderName);
$mail->addAddress($mailTo, $recipientName);
$mail->Subject = $decoded['subject'];
$mail->isHTML(TRUE);
$mail->Body = $decoded['body'];
$mail->AltBody = $decoded['altBody'];
$mail->send();
}
catch (Exception $e) {
echo $e->errorMessage();
}
catch (\Exception $e) {
echo $e->getMessage();
}
echo '{ "mailSent": "ok"}';
}
} else {
echo '{"status":"error"}';
}
} else {
echo '{"status":"no call accepted from this adress"}';
}
?>
我想我还有一些事情要做才能确保安全,但是你们能帮我找出原因和原因吗?
您做对了最重要的事情——没有使用用户提交的地址——这有助于防止您变成垃圾邮件网关!
首先,对于像这样的简单数据捕获,我会完全避免 HTML。普通的纯文本就可以了。
如果你确实想使用 HTML,我建议在服务器端组装它 - 这样你就可以对简单的输入字段进行更严格的过滤,例如使用 strip_tags
,或者在将它们插入布局之前,使用字符允许列表来过滤字段(参见 link @DigitalDrifter 提供的)。这比尝试干净地过滤预先组装的、用户提供的 HTML 更容易和更安全。这也非常简单,因为 JS 和 PHP 代码或多或少是相同的。
我目前正在使用 vue-cli 构建一个没有真正后端的小型网站。 由于我在 php(以及一般的后端)方面是一个真正的土豆,我想知道我在这个网站上的联系表格有多安全,如果不够安全该怎么办。
总而言之,我正在从我的 vue 应用程序调用 fetch() 到我服务器上的 mail.php 文件。 此 mail.php 文件使用 PHPMailer 将电子邮件从我域的一个电子邮件地址发送到我的另一个地址。 到现在为止一切正常。
这是我发送邮件相关的JS :
sendMail () {
this.sendRequest()
.then(r => {
if (r.mailSent === 'ok') {
// mail sent callback
}
})
},
async sendRequest () {
const response = await fetch('./mail.php', {
method: 'post',
headers: {
'content-type': 'application/json'
},
body: JSON.stringify({
subject: 'Message de ' + this.firstNameInput + ' ' + this.lastNameInput + ' via mysite.com',
body: '<html>' +
'<body>' +
'<p>De : ' + this.firstNameInput + ' ' + this.lastNameInput + '</p>' +
'<p>Email : ' + this.mailInput + '</p>' +
'<p>Message :<br>' + this.messageInput.replace(/\n/g, '<br>') + '</p>' +
'</body>' +
'</html>',
altBody: 'De : ' + this.firstNameInput + ' ' + this.lastNameInput + ' /// Email : ' + this.mailInput + ' /// Message :' + this.messageInput
})
})
return response.json()
}
这是我的 mail.php 文件的内容:
<?php
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
require './PHPMailer/src/Exception.php';
require './PHPMailer/src/PHPMailer.php';
require './PHPMailer/src/SMTP.php';
header('Content-Type: application/json');
include './mailSettings.php'; // contains $site, $mailFrom, $mailTo, $senderName and $recipientName
if(@isset($_SERVER['HTTP_REFERER']) && $_SERVER['HTTP_REFERER'] == $site) {
$contentType = isset($_SERVER["CONTENT_TYPE"]) ?trim($_SERVER["CONTENT_TYPE"]) : '';
if ($contentType === "application/json") {
$content = stripslashes(trim(file_get_contents("php://input")));
$decoded = json_decode($content, true);
if(!is_array($decoded)) {
echo '{"status":"error"}';
} else {
$mail = new PHPMailer(TRUE);
try {
$mail->setFrom($mailFrom, $senderName);
$mail->addAddress($mailTo, $recipientName);
$mail->Subject = $decoded['subject'];
$mail->isHTML(TRUE);
$mail->Body = $decoded['body'];
$mail->AltBody = $decoded['altBody'];
$mail->send();
}
catch (Exception $e) {
echo $e->errorMessage();
}
catch (\Exception $e) {
echo $e->getMessage();
}
echo '{ "mailSent": "ok"}';
}
} else {
echo '{"status":"error"}';
}
} else {
echo '{"status":"no call accepted from this adress"}';
}
?>
我想我还有一些事情要做才能确保安全,但是你们能帮我找出原因和原因吗?
您做对了最重要的事情——没有使用用户提交的地址——这有助于防止您变成垃圾邮件网关!
首先,对于像这样的简单数据捕获,我会完全避免 HTML。普通的纯文本就可以了。
如果你确实想使用 HTML,我建议在服务器端组装它 - 这样你就可以对简单的输入字段进行更严格的过滤,例如使用 strip_tags
,或者在将它们插入布局之前,使用字符允许列表来过滤字段(参见 link @DigitalDrifter 提供的)。这比尝试干净地过滤预先组装的、用户提供的 HTML 更容易和更安全。这也非常简单,因为 JS 和 PHP 代码或多或少是相同的。