Forum Moderators: Robert Charlton & goodroi
addEventListener('fetch', event => {
event.respondWith(fetchAndApply(event.request))
})
async function fetchAndApply(request) {
/* Set some variables some of which will be used in later on */
let referer = request.headers.get('Referer')
let useragent = request.headers.get('user-agent')
let javascript = "window.location.hostname"
let verifyvalue = btoa(javascript)
let response = await fetch(request)
/* Lets whitelist some bots we want to allow,feel free to add to list */
if (useragent != null) {
if ((request.headers.get('user-agent').includes('googlebot')) || (request.headers.get('user-agent').includes('applebot')) || (request.headers.get('user-agent').includes('bingbot')) || (request.headers.get('user-agent').includes('bing')))
{
return fetch(request)
}
}
/* We let all users through who have Cookie called "allow" they we set later */
let cookies = request.headers.get('Cookie') || ''
if (cookies.includes("allow=")) {
return fetch(request)
} else {
/* User is not a friendly bot and is probably a new visitor lets send them a cookie to allow access to our files */
response = new Response(response.body, response)
if (url.indexOf('/wp-content/') === -1) {
response.headers.set("Set-Cookie", "allow=" + verifyvalue)
return response
return fetch(request)
}
}
/* Ok We are getting suspicious now this user doesn't accept cookies lets have a look for a referer and if there is none block */
if (!referer)
{
let response = ('Please enable Cookies in your browser.... ', { status: 403 })
response = new Response(response.body, response);
response.headers.set("Cache-Control", "max-age=0");
return response;
} else {
return fetch(request)
}
}
# START block ips not going through cloudflare
RewriteCond %{HTTP:CF-Connecting-IP} ^$
RewriteRule ^ - [F,L]
RewriteCond %{HTTP:X-FORWARDED-FOR} ^$
RewriteRule ^ - [F,L]
<If "%{HTTP:X-FORWARDED-FOR} != %{HTTP:CF-Connecting-IP}">
RewriteRule ^ - [F,L]
</If>
# Compare Cookie sent from Cloudflare Workers (this may need further testing)
RewriteCond %{HTTP_COOKIE} .*allow=(.*?)(;|$)
RewriteRule .* - [E=COOKIE_DOMAIN:%1]
#Set this to the value of your cookie
SetEnv PROXY_CHECK "d2luZG93LmxvY2F0aW9uLmhvc3RuYW1lID09ICd3d3cuNHF1b3RlczRtZS5jby51ayc="
<If "%{ENV:COOKIE_DOMAIN} == %{ENV:PROXY_CHECK}">
</If>
<Else>
RewriteCond %{REQUEST_URI} !^/not-authorised
RewriteRule ^(.*)$ /not-authorised/ [R=302,L]
</Else>
# END block ips not going through cloudflare
<?php
header('Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0');
header('Expires: Sat, 26 Jul 1997 05:00:00 GMT');
?>
<head>
<meta name="robots" content="noindex" />
</head>
<body style="background:black;color:#fff;">
<center>
<iframe width="560" height="315" src="https://www.youtube.com/embed/J3UjJ4wKLkg" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
<br>
<br>
<p>Please enable Javascript and Cookies in your Browser</p>
</center>
</body>
$mysite = true;
if ((isset($_SERVER['HTTP_REFERER']) && !empty($_SERVER['HTTP_REFERER']))) {
if(!strpos($_SERVER['HTTP_REFERER'],$_SERVER['HTTP_HOST'])){
/* referer not from the same domain this is a hotlink */
$refervalue = $_SERVER['HTTP_REFERER'];
$requesturl = $_SERVER['REQUEST_URI'];
$url = $_SERVER['HTTP_REFERER'];
$urldata = parse_url($url);
$urldata = $urldata['host'];
$referrer = $_SERVER['HTTP_REFERER'];
if(strpos($url,'mysite.com') !== false){
$mysite = true; } else {
$mysite = false;
}
$my_file = '/path-to-your-file/imagehotlink.txt';
$handle = fopen($my_file, 'a') or die('Cannot open file: '.$my_file);
$data = "\n"."$refervalue".","."https://www.mysite.com"."$requesturl";
fwrite($handle, $data);
}
}
/*
if (empty($_SERVER['HTTP_REFERER'])) {
// referer blocked or empty
$refervalue = "blocked";
$requesturl = $_SERVER['REQUEST_URI'];
$my_file = '/path-to-your-file/imagehotlink.txt';
$handle = fopen($my_file, 'a') or die('Cannot open file: '.$my_file);
$data = "\n"."$refervalue".","."https://www.mysite.com"."$requesturl";
fwrite($handle, $data);
}
if($mysite !== true ){
header("Cache-Control: no-cache, must-revalidate"); header("Pragma: no-cache"); header("Expires: Sat, 26 Jul 1997 05:00:00 GMT");
die("Hotlinking not permitted");
}
<?php
/*
Plugin Name: Simple HoneyPot Using Cloudflare
Version: 0.2
Author: V4Vendetta
Description: Simple honeypot script.
License: GPL3
*/
class jpen_Honeypot_Widget extends WP_Widget {
/* Set Up Widget Name and Description */
public function __construct() {
$widget_options = array( 'classname' => '', 'description' => 'This is an Honeypot Widget' );
parent::__construct( 'honeypot_widget', 'Honeypot Widget', $widget_options );
}
public function widget( $args, $instance ) {
$root = $_SERVER["DOCUMENT_ROOT"];
$title = apply_filters( 'widget_title', $instance[ 'title' ] );
/* Create the widget output. */
$title = apply_filters( 'widget_title', $instance[ 'title' ] );
/* We are going to make a dynamic honeypot from categories in wordpress */
$categories = get_categories( array(
'orderby' => 'name'
) );
shuffle($categories);
$cat_count = 0;
$cat_col_one = [];
$cat_col_two = [];
foreach( $categories as $category ) {
$cat_count ++;
$category_link = sprintf(
'<li><a href="%1$s" alt="%2$s">%3$s</a></li>',
esc_url( get_category_link( $category->term_id ) ),
esc_attr( sprintf( __( 'View all posts in %s', 'textdomain' ), $category->name ) ),
esc_html( $category->name )
);
if ($cat_count % 2 != 0 ) {
$cat_col_one[] = $category_link;
}
}
foreach( $cat_col_one as $cat_one ) {
echo $args['before_widget'];
/* I was going to allow an array of folders but decided against */
$titlevalue = $title . "#";
$titlevalue = str_replace(" ","",$titlevalue);
$titlevalue = str_replace(",#","",$titlevalue);
$titlevalue = str_replace("#","",$titlevalue);
$titlevalue = explode(',', $titlevalue);
shuffle($titlevalue);
$titlevalue = reset($titlevalue);
$cat_one = str_replace("category",$titlevalue,$cat_one);
echo "<div class=\"$titlevalue\"><ul>";
echo $cat_one;
echo "</ul></div>";
echo $args['after_widget'];
break;
}
}
public function form( $instance ) {
$title = ! empty( $instance['title'] ) ? $instance['title'] : ''; ?>
<p>
<label for="<?php echo $this->get_field_id( 'title' ); ?>">Title:</label>
<input type="text" id="<?php echo $this->get_field_id( 'title' ); ?>" name="<?php echo $this->get_field_name( 'title' ); ?>" value="<?php echo esc_attr( $title ); ?>" />
</p><?php
}
/* Apply settings to the widget instance. */
public function update( $new_instance, $old_instance ) {
$instance = $old_instance;
$instance[ 'title' ] = strip_tags( $new_instance[ 'title' ] );
return $instance;
}
}
// Register the widget.
function jpen_register_honeypot_widget() {
register_widget( 'jpen_Honeypot_Widget' );
}
add_action( 'widgets_init', 'jpen_register_honeypot_widget' );
/* hide honeypot with css */
function hook_css() {
global $wpdb;
$results = get_option('widget_honeypot_widget');
$value = array_column($results, 'title');
$cssvalue = reset($value);
$cssvalue = $cssvalue . "#";
$cssvalue = str_replace(" ","",$cssvalue);
$cssvalue = str_replace(",#","",$cssvalue);
$cssvalue = str_replace("#","",$cssvalue);
$cssvalue = str_replace(",",", .",$cssvalue);
?>
<style>
.<?php echo $cssvalue; ?> { display:none;}
</style>
<?php
}
add_action('wp_head', 'hook_css');
/* Block the honeypot in robots.txt for whitelisted bots */
function disallow_honeypots_index( $output, $public ) {
if ( '1' === $public ) {
global $wpdb;
$results = get_option('widget_honeypot_widget');
$value = array_column($results, 'title');
$revalue = reset($value);
$revalue = $revalue . "#";
$revalue = str_replace(" ","",$revalue);
$revalue = str_replace(",#","",$revalue);
$revalue = str_replace("#","",$revalue);
$revalue = explode(',', $revalue);
shuffle($revalue);
foreach( $revalue as $link){
$subfolder = $link;
$searchbot = "false";
$user_agent = strtolower($_SERVER['HTTP_USER_AGENT']);
/* Please add to list of whitelisted bots */
$bot_identifiers = array(googlebot','applebot','bingbot','bing');
foreach ($bot_identifiers as $identifier) {
if (strpos($user_agent, $identifier) !== FALSE) {
$searchbot = "true";
}
}
if ( $searchbot == "true"){
$output .= "Disallow: /$link/\n";
}
}
}
$output .= "Disallow: /your-normal-disallow-rules/\n";
return $output;
}
add_filter( 'robots_txt', 'disallow_honeypots_index', 0, 2 );
/* log the ip of the user and serve a redirect */
add_action( 'init', 'global_redirect_new_rule');
function global_redirect_new_rule() {
global $wpdb;
$results = get_option('widget_honeypot_widget');
$value = array_column($results, 'title');
$revalue = reset($value);
$revalue = $revalue . "#";
$revalue = str_replace(" ","",$revalue);
$revalue = str_replace(",#","",$revalue);
$revalue = str_replace("#","",$revalue);
$revalue = explode(',', $revalue);
shuffle($revalue);
foreach( $revalue as $link){
$subfolder = $link;
$request = $_SERVER['REQUEST_URI'];
$redirect = str_replace("$subfolder","category",$request);
$path = $_SERVER['SERVER_NAME'];
if (strpos($request, "$subfolder") !== false) {
$ip = $_SERVER["HTTP_CF_CONNECTING_IP"];
$my_file = '/path-to-your-file/scraperlog.txt';
$handle = fopen($my_file, 'a') or die('Cannot open file');
$data = "\n"."$ip";
fwrite($handle, $data);
header ("location: https://$path$redirect");
die();
}
}
}
?>
If Traffic Matching the URL http & https www.yoursite.com/widget-title/* , from the same IP address exceeds 1 requests per 1 minute Then Challenge matching traffic from that visitor.
So why would you want to attract cyber-attackers to your site?Honeypots are often intended to attract visitors to specific pages, not to the site as a whole. For example the front page of my test site, which is comprehensively denied in robots.txt, has a bit that looks something like this:
a.honey {display: none;}
...
<a class = "honey" href = "/honeypage.html">blahblah</a>Humans won't see the link--and neither will law-abiding robots, since they haven't seen the main page in the first place. Knowing that nobody but a malign robot will ever request the page, you know up-front that any entity making the request is up to no good. What you do with this knowledge is, as ever, up to you.
A honeypot is a computer or computer system intended to mimic likely targets of cyberattacks. It can be used to detect attacks or deflect them from a legitimate target. It can also be used to gain information about how cybercriminals operate.
You may not have heard of them before, but honeypots have been around for decades. The principle behind them is simple: Don’t go looking for attackers. Prepare something that would attract their interest — the honeypot — and then wait for the attackers to show up.
<?php
/*
Plugin Name: Javascript Form Protection
Version: 0.9
Author: V4Vendette
Description: Simple script to stop automated bots filling out comments now with password protection and encryption.
License: GPL3
*/
add_action( 'wp', 'encrypt' );
function encrypt($string, $key)
{
$result = '';
for($i=0; $i<strlen($string); $i++) {
$char = substr($string, $i, 1);
$keychar = substr($key, ($i % strlen($key))-1, 1);
$char = chr(ord($char)+ord($keychar));
$result.=$char;
}
return base64_encode($result);
}
function after_comment_form_submit_button( $submit_button, $args ) {
$password = get_option('formpassword');
if (empty($password)) {
$password = $_SERVER['HTTP_HOST'];
}
$data = get_comment_id_fields();
$whatIWant = substr($data, strpos($data, "value") + strlen("value"), 12);
$whatIWant = (preg_replace('/[^0-9]/', '', $whatIWant));
$stopbots = encrypt($whatIWant, "$password");
$submit = sprintf(
$args['submit_button'],
esc_attr( $args['name_submit'] ),
esc_attr( $args['id_submit'] ),
esc_attr( $args['class_submit'] ),
esc_attr( $args['label_submit'] )
);
$comment_id = get_comment_ID();
$submit_button = "<input id=\"verify\" name=\"verify\" type=\"hidden\" value=\"\" />$submit";
$after_submit = "
<script>
function protectForm() {
oFormObject = document.forms['commentform'];
oFormObject.elements[\"verify\"].value = '$stopbots';
}
window.onload = protectForm;
</script>
<noscript>THIS FORM REQUIRES JAVASCRIPT ENABLED</noscript>";
return $submit_button . $after_submit;
};
add_filter( 'comment_form_submit_button', 'after_comment_form_submit_button', 10, 2 );
function custom_validate_verify() {
$password = get_option('formpassword');
if (empty($password)) {
$password = $_SERVER['HTTP_HOST'];
}
$formid = $_POST['verify'];
$verifyid = encrypt($_POST['comment_post_ID'], "$password");
if(( $formid != $verifyid )) // do you url validation here (I am not a regex expert)
wp_die( __( "Error: Your comment could not be verified. Are you sure your not a robot?.") );
}
add_action('pre_comment_on_post', 'custom_validate_verify');
add_action('admin_menu', 'add_global_custom_options');
function add_global_custom_options()
{
add_options_page('Javascript Comment Form Protection', 'Comment Form Protection Password', 'manage_options', 'functions','global_custom_options');
}
function global_custom_options()
{
?>
<div class="wrap">
<h2>Protection Password</h2>
<form method="post" action="options.php">
<?php wp_nonce_field('update-options') ?>
<p><strong>Enter A Password To Protect Your Form</strong><br />
<input type="text" name="formpassword" size="45" value="<?php echo get_option('formpassword'); ?>" />
</p>
<p><input type="submit" name="Submit" value="Store Password" style=" background-color: #4CAF50; border: none; color: white; padding: 15px 32px; text-align: center; text-decoration: none; display: inline-block; font-size: 16px;"/></p>
<input type="hidden" name="action" value="update" />
<input type="hidden" name="page_options" value="formpassword" />
</form>
</div>
<?php
}
add_action('login_form','verify_login_field');
function verify_login_field(){
$number = "007";
$number = $_SESSION['number'];
$number++;
$_SESSION['number'] = $number;
$password = get_option('formpassword');
if (empty($password)) {
$password = $_SERVER['HTTP_HOST'];
}
$stopbots = encrypt($number, "$password");
?>
<input id="verify" name="verify" type="hidden" value="" />
<script>
function protectForm() {
oFormObject = document.forms['loginform'];
oFormObject.elements["verify"].value = "<?php echo $stopbots; ?>";
}
window.onload = protectForm;
</script>
<noscript>THIS FORM REQUIRES JAVASCRIPT ENABLED</noscript>
<?php
}
add_filter( 'authenticate', 'verify_authenticate', 10, 3 );
function verify_authenticate( $user, $username, $password ){
$number = $_SESSION['number'];
$password = get_option('formpassword');
if (empty($password)) {
$password = $_SERVER['HTTP_HOST'];
}
$stopbots = encrypt($number, "$password");
$loginid = $_POST['verify'];
if( $loginid != $stopbots ){
//User note found, or no value entered or doesn't match stored value - don't proceed.
remove_action('authenticate', 'wp_authenticate_username_password', 20);
remove_action('authenticate', 'wp_authenticate_email_password', 20);
//Create an error to return to user
return new WP_Error( 'denied', __("<strong>ERROR</strong>: Sorry you can't come in.") );
}
//Make sure you return null
return null;
}
X-Frame-Options: SAMEORIGIN
let javascript = "window.location.hostname"
let verifyvalue = btoa(javascript)
<?php
$var = $_GET["status"];
$_SESSION['proxy'] = $var;
?>
/* Place this at the top of file */
<?php session_start();?>
<!doctype html >
<head>
/* Create a whitelist of allowed bots feel free to add */
<?php if (preg_match('/applebot|bingbot|facebookexternalhit|googlebot/i', $_SERVER['HTTP_USER_AGENT'])) { ?>
//Paste you normal header.php code
<?php } else { ?>
<script>
var test = atob('$proxycheck');
function setSession(){ if(
test == 'www.yoursite.com'
){
xhttp = new XMLHttpRequest();
xhttp.open('GET', '/wp-content/themes/YOURTHEME/session-start.php?status=no', true);
xhttp.send();
} else {
xhttp = new XMLHttpRequest();
xhttp.open('GET', '/wp-content/themes/YOURTHEME/session-start.php?status=yes', true);
xhttp.send();
}}window.onload=setSession;
</script>
<?php $proxysession = ($_SESSION['proxy']);
if ($proxysession == 'no' ){ ?>
// Repeat Paste you normal header.php code
<?php } else {
$url = 'https://www.yoursite.com/not-authorised/?cache=0';
wp_redirect($url);
exit;
};
}; ?>
<IfModule mod_php5.c>
#Session timeout
php_value session.cookie_lifetime 0
php_value session.gc_maxlifetime 0
</IfModule>
Another simple-minded question: "1 requests per minute" is nothing -- What if it gets 10,000 requests per second? Can your widget keep up with that?
Please note this is a firewall rule so yep it will block 10,000 requests and they will never actually hit your site at all. Your other question was comprehensively answered by Lucy.
a real DDOS attack since those requests come from a botnet distributed over a multitude of IPsMatter of fact, a DDOS attack may not come from anywhere. That is, if DOS is their sole motive, and you’re the target*, they'll probably be sending an array of fake IPs, and you'll never know where they “really” originated. But unless they are extra intelligent--mercifully, most robots aren't--all those requests will have identical headers, so you'll be able to identify something.
I know I see fake Googlebots frequently as well as other bots claiming to be what they aren't.That's worthy of a thread on its own: robots that are habitually spoofed. Mercifully the most popular is Googlebot, which has a narrowly delimited crawl range* so you can easily slam the door on the fakers. I also get a lot of fake BaiduSpiders (don't remember the exact capitalization)--which is pretty funny, since I block the real thing so they don't gain anything by using a fake ID. And then there's the robot using the name of a bot operated by an established WebmasterWorld member, only the one visiting my site isn't his, and I hope the real one never comes calling because I've found it simpler to deny it by name.
How are whitelisted robots being verified?