在完成了大量的小型javascript项目之后,我现在还想使用php。我决定建立一个简单的联系方式。当然,我希望它是垃圾邮件-保存尽可能多,所以我使用了一些想法,我发现在网上(蜜罐和某种类型的CAPTCHA)。
我以如下方式实现了CAPTCHA的思想:每次用户加载联系人页面时,都会随机创建一个简单的数学问题,用户必须输入正确的解决方案才能提交表单。
Minimal工作示例
Contact
Contact
Your Name:
Your Email:
Message:
I agree with saving and sending this message according to the privacy policy.
//Two random numbers for simple math-problem (spam-prevention)
let array = ["one", "two", "three",
"four", "five", "six",
"seven", "eight", "nine",
"ten"];
let item1 = array[Math.floor(Math.random() * array.length)];
let item2 = array[Math.floor(Math.random() * array.length)];
document.getElementById('exercise').innerHTML = item1 + " + " + item2 + " = ?";
document.getElementById("read").value = item1 + " + " + item2;@media (max-width: 1000px) {
.input {
width: 100%;
padding: 10px 20px;
margin: 10px 0;
display: inline-block;
border: 1px solid black;
border-radius: 5px;
box-sizing: border-box;
background: LightGray;
}
}
@media (min-width: 1001px) {
.input {
width: 30%;
padding: 10px 20px;
margin: 10px 0;
display: inline-block;
border: 1px solid black;
border-radius: 5px;
box-sizing: border-box;
background: LightGray;
}
}
input[type=text] {
width: 100%;
padding: 10px 10px;
margin: 10px 0;
display: inline;
border: 1px solid Gray;
border-radius: 5px;
box-sizing: border-box;
}
input[type=submit] {
width: 100%;
padding: 10px 10px;
margin: 10px 0;
display: inline;
border: 1px solid Gray;
border-radius: 5px;
box-sizing: border-box;
}
input[type=number] {
width: 100%;
padding: 10px 10px;
margin: 10px 0;
display: inline;
border: 1px solid Gray;
border-radius: 5px;
box-sizing: border-box;
}
#website {
display: none;
}PHP-代码
4
* six -> 6
*/
$x = 0;
$y = 0;
for($i = 0; $i <= 10; $i++) {
if(strcmp($substr1, $arr[$i]) == 0) {
$x = $i;
break;
}
}
for($i = 0; $i <= 10; $i++) {
if(strcmp($substr2, $arr[$i]) == 0) {
$y = $i;
break;
}
}
$z = intval($_POST['solution']);
//Did user enter right solution?
if($z == ($x + $y)) {
//Bot filled the honeypott-tree
if(!empty($_POST['website'])) {
echo "Something went wrong";
die();
}
$userName = $_POST['myName'];
$userEmail = $_POST['myEmail'];
$userMessage = $_POST['myMessage'];
//Did user enter a valid email-adress?
if(!filter_var($userEmail, FILTER_VALIDATE_EMAIL)) {
echo "Something went wrong";
die();
}
//Creating message
$to = "mail@domain.com";
$subject = "New Contact-form message";
$body = "Content:";
$body .= "\n\n Name: " . $userName;
$body .= "\n\n Email: " . $userEmail;
$body .= "\n\n Message: " . $userMessage;
//Trying to send message
if(mail($to, $subject, $body)){
echo "Thank you for your message";
die();
} else{
echo "Something went wrong";
die();
}
}
echo "Something went wrong";
?>我对改进php代码的建议特别感兴趣。
我感兴趣的另一件事是这种方法的安全性。如何进一步改善呢?
当然,所有其他建议也会受到赞赏。
发布于 2020-08-31 20:05:37
JS和前端样式
const而不是let。.innerHTML标记时,最好只使用。如果您不处理HTML,那么使用textContent是更快和更安全的。(使用不可信输入设置.innerHTML是一种安全风险。这里的输入碰巧是可信的,但最好养成只在必要时使用.innerHTML的习惯)class="foo"而不是id="foo"。安全性
随机数是在前端产生的,因此对于任何对JS有一点了解的有兴趣的施虐者来说都很简单。(诚然,对于一个小规模的网站来说,这是不太可能的,但它仍然是一个很好的修复方法。)他们所需要做的就是发送一个带有预先设置的read属性的one + one和2的解决方案的请求,以及他们想发送的任何垃圾邮件,他们可以向你发送1000条垃圾邮件。
我建议在服务器上生成随机数,并将它们发送到客户端,以这样一种格式进行验证,以确保无法编程地从有效载荷中提取随机数。
如果我创建的是家用解决方案,而不是像Recaptcha这样的尝试和信任的解决方案,我将让客户端从服务器请求一个映像,让服务器用imagecreatefrompng创建背景图像,使用imagettftext绘制随机文本,将文本保存在会话变量中,并将图像发送到客户端进行验证。这不是完美的,但它将大大提高成功滥用的标准。
https://codereview.stackexchange.com/questions/248695
复制相似问题