Compare commits
5 commits
Author | SHA1 | Date | |
---|---|---|---|
f9cf02d133 | |||
0371201671 | |||
f47a26a7e7 | |||
![]() |
56c808c984 | ||
![]() |
c02727e444 |
3 changed files with 225 additions and 34 deletions
8
LICENSE
Normal file
8
LICENSE
Normal file
|
@ -0,0 +1,8 @@
|
|||
The MIT License (MIT)
|
||||
Copyright © 2022 Paul Malcher
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
6
README.md
Normal file → Executable file
6
README.md
Normal file → Executable file
|
@ -1,3 +1,7 @@
|
|||
# contactform
|
||||
|
||||
A spam and bot resistant contact form. Remeber to update the URL and e-mail address this sends to if you use it.
|
||||
A spam and bot resistant contact form. Remeber to update the URL and e-mail address this sends to if you use it.
|
||||
|
||||
# Notes 11/12/23
|
||||
|
||||
contactform.php now contains the accompanying HTML. Merged due to updates.
|
245
contactform.php
Normal file → Executable file
245
contactform.php
Normal file → Executable file
|
@ -1,23 +1,37 @@
|
|||
<?php
|
||||
// Form code for mail submissions
|
||||
// For usage with hugo site
|
||||
|
||||
// Anti exploit code, not perfect but should throw a wrench into a bot's plan
|
||||
// This code has been used on several sites before and does seem to do a decent job, not perfect but pretty good
|
||||
// The form code is now part of the php file so when the form is loaded the php can run to extend the
|
||||
// functionality of the rate limiting code
|
||||
|
||||
// Using Bluma for the html parts really does make things look and work better
|
||||
|
||||
session_start();
|
||||
$csrf_token = bin2hex(random_bytes(32));
|
||||
if (!isset($_SESSION['csrf_token'])) {
|
||||
|
||||
$_SESSION['csrf_token'] = $csrf_token;
|
||||
}
|
||||
//$_SESSION['csrf_token'] = $csrf_token;
|
||||
|
||||
class antibot {
|
||||
|
||||
private $passfail;
|
||||
public $token;
|
||||
|
||||
function __constructor(){
|
||||
$passfail = 0;
|
||||
$this->passfail = 0;
|
||||
// beter way to filter input data
|
||||
$_POST = filter_var_array($_POST, FILTER_SANITIZE_STRING);
|
||||
$_GET = filter_var_array($_GET, FILTER_SANITIZE_STRING);
|
||||
|
||||
|
||||
}
|
||||
|
||||
private function fromtest() {
|
||||
if ($_SERVER['HTTP_REFERER'] = "http://yourwebsite.com/contactus/"){
|
||||
$passfail = 1;
|
||||
if ($_SERVER['HTTP_REFERER'] = "https://urandom.link/contactform.php"){
|
||||
$this->passfail++;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -25,16 +39,17 @@ class antibot {
|
|||
private function ratetest() {
|
||||
if (!$_SESSION['last_submit']){
|
||||
$_SESSION['last_submit'] = time(); // May not stick to a bot but doing it anyhow
|
||||
$passfail = 2;
|
||||
$this->passfail = 1;
|
||||
}else{
|
||||
//print "Session found";
|
||||
if (time()-$_SESSION['last_submit'] < 60){
|
||||
// Purposefully not letting them know what the interval is
|
||||
die('Error: Message not sent, rate limit hit. Please wait a few minutes and try again.');
|
||||
$passfail = 0;
|
||||
|
||||
die('Error: Message not sent, rate limit hit. Please wait a few minutes and try again.');
|
||||
|
||||
}else{
|
||||
$_SESSION['last_submit'] = time();
|
||||
$passfail = 2;
|
||||
$this->passfail++;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -42,26 +57,28 @@ class antibot {
|
|||
|
||||
private function traptest() {
|
||||
if($_POST['website']){
|
||||
$passfail = 0;
|
||||
$this->passfail = 0;
|
||||
}else{
|
||||
$passfail = 3;
|
||||
$this->passfail++;
|
||||
}
|
||||
return $passfail;
|
||||
return $this->passfail;
|
||||
}
|
||||
|
||||
private function test_input($data) { // Cleans the input
|
||||
$data = trim($data);
|
||||
$data = stripslashes($data);
|
||||
$data = htmlspecialchars($data);
|
||||
return $data;
|
||||
}
|
||||
private function emptytest() {
|
||||
if (empty($_POST['fname']) || empty($_POST['lname']) || empty($_POST['email']) || empty($_POST['comments'])){
|
||||
$this->passfail = 0;
|
||||
}else{
|
||||
$this->passfail++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private function sndmsg($target) {
|
||||
// First clean the data
|
||||
$fname = $this->test_input($_POST["fname"]);
|
||||
$lname = $this->test_input($_POST["lname"]);
|
||||
$email = $this->test_input($_POST["email"]);
|
||||
$comments = $this->test_input($_POST["comments"]);
|
||||
$fname = $_POST["fname"];
|
||||
$lname = $_POST["lname"];
|
||||
$email = filter_var($_POST['email'], FILTER_SANITIZE_EMAIL);
|
||||
$comments = $_POST["comments"];
|
||||
// compile cleaned message
|
||||
$msg = "From $fname Subject $lname email $email with message $comments";
|
||||
mail($target,"Website Form Submission",$msg);
|
||||
|
@ -70,26 +87,188 @@ class antibot {
|
|||
public function do_tests(){
|
||||
$this->fromtest();
|
||||
$this->ratetest();
|
||||
$result = $this->traptest();
|
||||
if($result == 3) {
|
||||
$this->sndmsg("you@yoursite.com");
|
||||
return 3;
|
||||
$this->traptest();
|
||||
$this->emptytest();
|
||||
if($this->passfail == 4) {
|
||||
$this->sndmsg("webmaster@pngpst.net");
|
||||
return 4;
|
||||
}else{
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
$lcheck = new antibot();
|
||||
|
||||
$winner = $lcheck->do_tests();
|
||||
|
||||
if ($winner == 3){
|
||||
echo "Form Submitted thank you!";
|
||||
}else{
|
||||
echo "Error: Send failed, please try again.";
|
||||
}
|
||||
$antibot = new antibot();
|
||||
|
||||
|
||||
if ($_SERVER["REQUEST_METHOD"] == "POST") {
|
||||
// Check if the CSRF token is present
|
||||
if (isset($_POST['csrf_token'])) {
|
||||
$user_token = $_POST['csrf_token'];
|
||||
|
||||
// Check if the submitted token matches the stored session token
|
||||
if ($user_token === $_SESSION['csrf_token']) {
|
||||
// Token is valid, process the form
|
||||
// ... Your form processing logic goes here ...
|
||||
$winner = $antibot->do_tests();
|
||||
if ($winner == 4){
|
||||
echo "Form Submitted thank you!";
|
||||
}else{
|
||||
echo "Error: Send failed, please try again. -1";
|
||||
}
|
||||
|
||||
} else {
|
||||
// Invalid token, handle accordingly (e.g., log the incident, reject the form)
|
||||
die("Error: Send failed, please try again. -2");
|
||||
}
|
||||
} else {
|
||||
// CSRF token is not present, handle accordingly
|
||||
die("Error: Send failed, please try again. -3");
|
||||
}
|
||||
} //else {
|
||||
// Handle non-POST requests accordingly
|
||||
//die("Invalid request method.");
|
||||
//}
|
||||
|
||||
|
||||
// $winner = $lcheck->do_tests();
|
||||
|
||||
//if ($winner == 3){
|
||||
// echo "Form Submitted thank you!";
|
||||
// }else{
|
||||
// echo "Error: Send failed, please try again.";
|
||||
//}
|
||||
|
||||
?>
|
||||
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@0.9.4/css/bulma.min.css">
|
||||
<title>Urandom.link contact form</title>
|
||||
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<section class="hero">
|
||||
<div class="hero-body">
|
||||
<p class="title">
|
||||
URANDOM.LINK Contact Form
|
||||
</p>
|
||||
<p class="subtitle">
|
||||
Embrace the random
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="section">
|
||||
<div class="container">
|
||||
<form action="https://urandom.link/contactform.php" method="post" id="contact">
|
||||
|
||||
<div class="field is-horizontal">
|
||||
<div class="field-label is-normal">
|
||||
<label class="label">From</label>
|
||||
</div>
|
||||
<div class="field-body">
|
||||
<div class="field">
|
||||
<p class="control is-expanded has-icons-left">
|
||||
<input class="input" type="text" placeholder="Your Name" name="fname">
|
||||
<span class="icon is-small is-left">
|
||||
<i class="fas fa-user"></i>
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
<div class="field">
|
||||
<p class="control is-expanded has-icons-left has-icons-right">
|
||||
<input class="input is-success" type="email" placeholder="Email" name="email">
|
||||
<span class="icon is-small is-left">
|
||||
<i class="fas fa-envelope"></i>
|
||||
</span>
|
||||
<span class="icon is-small is-right">
|
||||
<i class="fas fa-check"></i>
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="field is-horizontal">
|
||||
<div class="field-label is-normal">
|
||||
<label class="label">Subject</label>
|
||||
</div>
|
||||
<div class="field-body">
|
||||
<div class="field">
|
||||
<div class="control">
|
||||
<input class="input is-danger" type="text" placeholder="Subject" name="lname">
|
||||
</div>
|
||||
<p class="help is-danger">
|
||||
This field is required
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field is-horizontal">
|
||||
<div class="field-label is-normal">
|
||||
<label class="label">Message</label>
|
||||
</div>
|
||||
<div class="field-body">
|
||||
<div class="field">
|
||||
<div class="control">
|
||||
<textarea class="textarea is-danger" placeholder="Your message here" name="comments"></textarea>
|
||||
</div>
|
||||
<p class="help is-danger">
|
||||
This field is required
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field is-horizontal">
|
||||
<div class="field-label">
|
||||
<!-- Left empty for spacing -->
|
||||
</div>
|
||||
<div class="field-body">
|
||||
<div class="field">
|
||||
<div class="control">
|
||||
<button class="button is-primary">
|
||||
Send message
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<input type="text" name="website" style=" display: none;"/>
|
||||
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token']; ?>"/>
|
||||
|
||||
</form>
|
||||
|
||||
|
||||
</section>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
Loading…
Add table
Add a link
Reference in a new issue