我有一个简单的网站联系表格创建于2017年。
该表单是用PHP、PHPMailer、jQuery、HTML和CSS开发的。
我想确保代码符合现代标准和安全。
我还想从PHP切换到AJAX以获得成功和错误消息传递(以避免页面刷新)。但这件事可能超出了我的范围,所以我就不谈这个问题了。
这是一个详细的分类:
(1)表单将站点用户的消息发送给站点管理人员。
(2)结构采用HTML,表示采用CSS。
(3)用户输入通过SMTP使用PHPMailer发送。
(4)为用户提供一个带有字符计数器的textarea框,供用户提交消息。
(5)如果超过字符计数,jQuery脚本将阻止表单被提交。
(6)安装Google reCAPTCHA以减少垃圾邮件。
(7)在客户端使用HTML和标准浏览器函数进行用户输入验证。
(8) PHP函数用于服务器端的用户输入验证和清理。
(9) PHP处理发送给用户的成功和错误消息。
据我所知,这个表格很好用。
我想在这里寻求一些指导:
谢谢。
HTML,CSS & jQuery
// text area character counter
// displays total characters allowed
// displays warning at defined count (currently 150)
// disables submit button when < 0
// max characters that can be input set by maxlength attribute in HTML
(function($) {
$.fn.charCount = function(submit, options){
this.submit = submit;
// default configuration properties
var defaults = {
allowed: 1250,
warning: 150,
css: 'counter',
counterElement: 'span',
cssWarning: 'warning',
cssExceeded: 'exceeded',
counterText: ''
};
var options = $.extend(defaults, options);
function calculate(obj,submit){
submit.attr("disabled", "disabled");
var count = $(obj).val().length;
var available = options.allowed - count;
if(available <= options.warning && available >= 0){
$(obj).next().addClass(options.cssWarning);
} else {
$(obj).next().removeClass(options.cssWarning);
}
if(available < 0){
$(obj).next().addClass(options.cssExceeded);
} else {
$(obj).next().removeClass(options.cssExceeded);
submit.removeAttr("disabled");
}
$(obj).next().html(options.counterText + available);
};
this.each(function() {
$(this).after('<'+ options.counterElement +' class="' + options.css + '">'+ options.counterText +'');
calculate(this, submit);
$(this).keyup(function(){calculate(this,submit)});
$(this).change(function(){calculate(this,submit)});
});
};
})(jQuery);
$(document).ready(function(){
$("#comments").charCount($("#submit"));
});
#contact-form {
display: flex;
flex-direction: column;
width: 50%;
font: 1rem/1.5 arial, helvetica, sans-serif;
margin: 0 auto 1em !important;
}
#contact-form > div {
display: flex;
flex-direction: column;
margin-bottom: 10px;
}
#contact-form > div:not(.send-fail-notice):not(#counter-container) {
width: 70%;
}
#contact-form > .ad2 { align-self: flex-start; }
/* label formatting */
#contact-form > div > label {
margin-bottom: 2px;
}
/* asterisk formatting */
#contact-form > div > label > span {
color: #f00;
font-size: 1.5em;
line-height: 1;
}
/* input field formatting */
#contact-form input,
#contact-form textarea {
border: 1px solid #ccc;
background: #fcfcfc;
padding: 2px 5px;
resize: none;
font-family: arial, helvetica, sans-serif;
}
#contact-form input:focus,
#contact-form textarea:focus {
border: 1px solid #777;
}
/* textarea and character counter */
#contact-form > #counter-container { }
#contact-form > #counter-container > .counter {
font-size: 1.5em;
color: #ccc;
}
#contact-form > #counter-container .warning {
color: orange;
}
#contact-form > #counter-container .warning::after {
content: " approaching limit";
font-size: 1em;
}
#contact-form > #counter-container .exceeded {
color: red;
}
#contact-form > #counter-container .exceeded::after {
content: " form won't submit";
font-size: 1em;
}
/* submit button formatting */
#contact-form > button {
align-self: flex-start;
padding: 5px 15px;
cursor: pointer;
border: 1px solid #ccc;
background-color: #f1f1f1;
background-image: linear-gradient(#f1f1f1, #fafafa);
}
#contact-form > button:hover {
background-image: linear-gradient(#e1e1e1, #eaeaea);
}
/* form errors */
.send-fail-notice {
flex-direction: row !important;
align-items: center;
padding: 15px;
background-color: #ffc;
border: 2px solid red;
}
.send-fail-notice > span {
color: #e13a3e;
font-weight: bold;
margin-left: 10px;
}
Name *
E-mail *
Subject
Message *
<?php echo $comments ?>
Send Message
PHP
// CONTACT FORM PROCESSING SCRIPT
// set default values (prevents undefined variable error)
$send_fail_one = null;
$send_fail_two = null;
$name = null;
$email = null;
$subject = null;
$comments = null;
// Load PHPMailer (v 6.5.3 02/02/2022)
// Import PHPMailer classes into the global namespace
// These must be at the top of your script, not inside a function
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;
use PHPMailer\PHPMailer\Exception;
if ($_SERVER["REQUEST_METHOD"] == "POST") {
// Load PHPMailer
require 'PHPMailer/src/Exception.php';
require 'PHPMailer/src/PHPMailer.php';
require 'PHPMailer/src/SMTP.php';
// Create new PHPMailer instance; passing `true` enables exceptions
$mail = new PHPMailer(true);
$mail->CharSet = "UTF-8";
// SMTP Debugging
//SMTP::DEBUG_OFF = off (for production use)
//SMTP::DEBUG_CLIENT = client messages
//SMTP::DEBUG_SERVER = client and server messages
$mail->SMTPDebug = SMTP::DEBUG_SERVER;
$mail->Debugoutput = 'html';
// SMTP settings
$mail->isSMTP();
$mail->Host = 'smtp.gmail.com';
$mail->SMTPAuth = true;
$mail->SMTPSecure = PHPMailer::ENCRYPTION_SMTPS;
$mail->Port = 465;
$mail->Username = 'demo-purposes@yahoo.com';
$mail->Password = 'FakePasswordForDemoPurposes';
$mail->setFrom('demo-purposes@yahoo.com');
$mail->addAddress('demo-purposes@yahoo.com');
$mail->isHTML(true);
// Sanitize & Validate Input
// Trim all $_POST values
/* Using FILTER_SANITIZE_SPECIAL_CHARS as opposed to FILTER_SANITIZE_STRING because:
* (1) FILTER_SANITIZE_SPECIAL_CHARS will disarm code but still display it.
* (2) FILTER_SANITIZE_STRING removes all code, leaving no trace, and all code input is lost (e.g., anything with brackets is lost).
* Hence, with (1) we can identify users trying to submit code.
* Exception: textarea field ('comments') uses FILTER_SANITIZE_STRING because otherwise nl2br (keep line breaks) doesn't work. */
$name = trim(filter_input(INPUT_POST, 'name', FILTER_SANITIZE_SPECIAL_CHARS));
$email = filter_input(INPUT_POST, 'email', FILTER_SANITIZE_EMAIL);
$subject = trim(filter_input(INPUT_POST, 'subject', FILTER_SANITIZE_SPECIAL_CHARS));
$comments = nl2br(filter_input(INPUT_POST, 'comments', FILTER_SANITIZE_STRING));
// Email Body
$message = <<
NAME
$name
E-MAIL
$email
SUBJECT
$subject
MESSAGE
$comments
HTML;
$mail->Subject = 'Message Received =?utf-8?B?4oCT?= Website Contact Form';
$mail->Body = $message;
// verify recaptcha response
$url = "https://www.google.com/recaptcha/api/siteverify";
$privatekey = "xxx";
$response = file_get_contents($url."?secret=".$privatekey."&response=".$_POST['g-recaptcha-response']."&remoteip=".$_SERVER['REMOTE_ADDR']);
$data = json_decode($response);
// if recaptcha verification is a success...
if(isset($data->success) AND $data->success==true) {
// ... and if phpmailer does not send (for whatever reason, such as a wrong SMTP password)...
if (!$mail->send()) {
// then show this error message:
$send_fail_one = <<
ERROR. Message not sent.
Please try again or contact us at bireg at outlook dot com.
ERROR;
} else {
// ...otherwise delivery is successful and page re-directs to thank you / confirmation page
header('Location: https://www.yahoo.com');
}
} else {
// if re-captcha verification fails, show this error message:
$send_fail_two = <<
ERROR. Message not sent.
Please check the anti-spam box.
ERROR;
}
}
发布于 2022-02-08 18:59:50
联系人表单不一定是安全风险,但这完全取决于您如何处理提交的数据。基本上,您需要记住两种类型的安全性:
你不把任何东西存储在数据库里,也不自己发电子邮件。这消除了对您的服务器的最大威胁之一。您遗漏了很多代码,所以仍然有可能存储数据,但显然您不希望在这里讨论这个问题。
用户使用此联系人表单的风险要大得多。除了他们的评论,他们必须提供他们的名字和电子邮件地址。为什么呢?
当然,任何聪明的用户都不会使用自己的名字和电子邮件地址。任何电子邮件地址都行。那么,为什么要问呢?
You可以使提供名称和电子邮件地址成为可选的。
你也在使用谷歌的隐藏reCAPTCHA,它将大量的用户数据交给谷歌。
如果reCAPTCHA错过了这些信息,谷歌还有第二次机会通过他们的邮件服务器偷看你发送的邮件。你不会给你的访问者留下任何选择,如果他们想要评论的话,他们也可以直接把他们的评论发送到谷歌。
为什么这会是个问题?谷歌将这些数据存储在美国。美国政府也喜欢大数据。他们用它。很简单。爱德华·斯诺登向我们展示了。外国人受到美国法律的保护甚至更少。
也可以阅读:独家:政府秘密命令谷歌确认任何搜查性侵犯受害者姓名、地址或电话号码的人。
谷歌( Google )是互联网上没有隐私的主要原因之一,他们与Facebook一起积极努力保持这种状态。他们追求合法的商业利益,但结果是相当有害的。
大多数人,包括我,经常忽视这个明显的问题。我们把注意力集中在所有的技术问题上,但是这个故事有一个完全相反的方面。
https://codereview.stackexchange.com/questions/273786
复制相似问题