<?php
if (!isset($_SESSION)) {
session_start();
}
// anti flood protection
if($_SESSION['last_session_request'] > time() - 2){
// users will be redirected to this page if it makes requests faster than 2 seconds
header("location: http://www.example.com/403.html");
exit;
}
$_SESSION['last_session_request'] = time();
?>
I've already tested this script as you higher the second It Will keep redirecting to http://www.example.com/403.html without any reason.
Can anyone tell me why?
Let's think about this logically for a second...
The attacker's request is already being sent to the web-server and through to the PHP script.
The bottle-neck which causes failure in DDoS attacks is the web-server.
The idea behind a DDoS attack is just that - to cause a denial of service, in which the website/server is unable to process any new requests. So in escense, this approach is irrational.
You need to go up the ladder of request handling.
If you have a server to your disposal, it's easier. You could simply implement a rate limiting rule on the kernel firewall/iptables.
But assuming you do not have access to that, Apache is still at your disposal - although not as efficient.
Implementing a rule within .htaccess is a better solution, but still not perfect.
But depending on the DDoS attack, there's no real solution at the developer's disposal to block it.
I'm using a good anti-flood script that des not need cookies (perfect for webservices). It's not perfect against advanced DDOS attacks but it's enough for preventing beginners attacks and automatic multiple requests.
For using it, before it's needed to create "flood" folder with a "ctrl" file inside and a "lock" subfolder. Also needed to be setted with correct permissions.
Already tested by me.
define("SCRIPT_ROOT", dirname(__FILE__));
// number of allowed page requests for the user
define("CONTROL_MAX_REQUESTS", 3);
// time interval to start counting page requests (seconds)
define("CONTROL_REQ_TIMEOUT", 2);
// seconds to punish the user who has exceeded in doing requests
define("CONTROL_BAN_TIME", 5);
// writable directory to keep script data
define("SCRIPT_TMP_DIR", SCRIPT_ROOT."/flood");
// you don't need to edit below this line
define("USER_IP", $_SERVER["REMOTE_ADDR"]);
define("CONTROL_DB", SCRIPT_TMP_DIR."/ctrl");
define("CONTROL_LOCK_DIR", SCRIPT_TMP_DIR."/lock");
define("CONTROL_LOCK_FILE", CONTROL_LOCK_DIR."/".md5(USER_IP));
#mkdir(CONTROL_LOCK_DIR);
#mkdir(SCRIPT_TMP_DIR);
if (file_exists(CONTROL_LOCK_FILE)) {
if (time()-filemtime(CONTROL_LOCK_FILE) > CONTROL_BAN_TIME) {
// this user has complete his punishment
unlink(CONTROL_LOCK_FILE);
} else {
// too many requests
echo "<h1>DENIED</h1>";
echo "Please try later.";
touch(CONTROL_LOCK_FILE);
die;
}
}
function antiflood_countaccess() {
// counting requests and last access time
$control = Array();
if (file_exists(CONTROL_DB)) {
$fh = fopen(CONTROL_DB, "r");
$control = array_merge($control, unserialize(fread($fh, filesize(CONTROL_DB))));
fclose($fh);
}
if (isset($control[USER_IP])) {
if (time()-$control[USER_IP]["t"] < CONTROL_REQ_TIMEOUT) {
$control[USER_IP]["c"]++;
} else {
$control[USER_IP]["c"] = 1;
}
} else {
$control[USER_IP]["c"] = 1;
}
$control[USER_IP]["t"] = time();
if ($control[USER_IP]["c"] >= CONTROL_MAX_REQUESTS) {
// this user did too many requests within a very short period of time
$fh = fopen(CONTROL_LOCK_FILE, "w");
fwrite($fh, USER_IP);
fclose($fh);
}
// writing updated control table
$fh = fopen(CONTROL_DB, "w");
fwrite($fh, serialize($control));
fclose($fh);
}
Taken from here: https://github.com/damog/planetalinux/blob/master/www/principal/suscripcion/lib/antiflood.hack.php
just change > to <:
<?php
if (!isset($_SESSION)) {
session_start();
}
// anti flood protection
if($_SESSION['last_session_request'] < time() - 2){
// users will be redirected to this page if it makes requests faster than 2 seconds
header("location: http://www.example.com/403.html");
exit;
}
$_SESSION['last_session_request'] = time();
?>
What spudinksi said still holds true, however here is what your looking for:
<?php
if (!isset($_SESSION)) {
session_start();
}
if($_SESSION['last_session_request'] > (time() - 5)){
if(empty($_SESSION['last_request_count'])){
$_SESSION['last_request_count'] = 1;
}elseif($_SESSION['last_request_count'] < 5){
$_SESSION['last_request_count'] = $_SESSION['last_request_count'] + 1;
}elseif($_SESSION['last_request_count'] >= 5){
header("location: http://www.example.com/403.html");
exit;
}
}else{
$_SESSION['last_request_count'] = 1;
}
$_SESSION['last_session_request'] = time();
?>
For stop DDos add a null route for that ip, like this:
route add -host ???.???.???.??? reject
There is a script called IOSec, which is quite old, but it might help.
This will count page reloads & also save time after 3 seconds ....
if it gives problems or to easy for newbies to bypass then leave comment..
if(empty($_SESSION['AFsys_time']) || $_SESSION['AFsys_time'] == '0') {
$tGoal = time() + 3; // Pluss Seconds
$_SESSION['AFsys_time'] = $tGoal;
}
if(empty($_SESSION['AFsys_pReloads']) || $_SESSION['AFsys_pReloads'] == 0 ) { $_SESSION['AFsys_pReloads'] = 1; } else { $_SESSION['AFsys_pReloads']++; };
if($_SESSION['AFsys_time'] < time()){
$_SESSION['AFsys_time'] = 0; // Session Reset
$_SESSION['AFsys_pReloads'] = 0; // Session Reset
}
if($_SESSION['AFsys_pReloads'] > '5' && $_SESSION['AFsys_time'] > time()){
$_SESSION['AFsys_time'] = 0; // Session Reset
$_SESSION['AFsys_pReloads'] = 0; // Session Reset
header("location: http://www.example.com/403.html");
exit;
}
this code not work for curl looping like this. session will create again on every curl exec;
for ($i=0;$i<999999999999999;$i++){
/**/
$c=curl_init();
curl_setopt($c,CURLOPT_URL,"URL YOU WANT ATTACK");
curl_setopt($c,CURLOPT_DNS_USE_GLOBAL_CACHE,TRUE);//dns
curl_setopt($c,CURLOPT_HEADER,0);//get the header
curl_setopt($c,CURLOPT_CONNECTTIMEOUT ,10);//get the header
curl_setopt($c,CURLOPT_NOBODY,0);//and *only* get the header
curl_setopt($c,CURLOPT_RETURNTRANSFER,1);//get the response as a string from curl_exec(), rather than echoing it
curl_setopt($c,CURLOPT_FRESH_CONNECT,1);//don't use a cached version of the url
curl_setopt($c, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:11.0) Gecko Firefox/11.0');
curl_setopt($c, CURLOPT_HTTPHEADER, array('Content-type: application/x-www-form-urlencoded;charset=UTF-8' ));
echo "\n $i";
}
Session may be not work, because we haven't session coockie.
I recommend such
$load = sys_getloadavg();
if ($load[0] > 20) {
header('HTTP/1.1 503 Too busy, try again later');
die('Server too busy. Please try again later.');
}
Or you can
shell_exec('/sbin/iptables -I INPUT -j DROP -s ' . $ip);
for ddosing $ip
Related
What I want to do is to have a variable that increments by 1 after every reload. Now, I can't do cookies because I want it to increment globally, and I've tried sessions but I had no luck with them. If anyone could help me out I'd really appreciate it. I actually can't give any code samples because my tries have turned out very messy.
If you want a variable for each user, then I would definitely go with sessions :
<?php
session_start();
if (!isset($_SESSION['counter'])) {
$_SESSION['counter'] = 0;
} else {
$_SESSION['counter']++;
}
However if you want a unique variable that increases at each load (i.e the same for all users), then you could use a file to store the number of views :
<?php
if(file_exists('counter.txt'))
{
$counter_f = fopen('counter.txt', 'r+');
$count = fgets($counter_f);
}
else
{
$counter_f = fopen('counter.txt', 'a+');
$count = 0;
}
$count++;
fseek($counter_f, 0);
fputs($counter_f, $count);
fclose($counter_f);
?>
i'm sorry if my request seems silly .
i've looked for a long time for this but no luck.
basically what i'm trying to do is : i want when a visitor visits my link'http:/ /mysite. com/redirect .php' , my php script gets his ip address, checks if it exists in an array of ips stored in a file 'hits.txt', if it does then redirect him to another page say'google.com'
if it doesn't then store his ip address in the file then redirect him to another page say 'yahoo.com'.
so later when he comes back to visit again he gets redirected to google.com.
ofcourse my purpose eventually is to make a unique ip visits script.
if you have an idea how to do it without database and sql i'll be grateful, if u think it can only be done with sql then please suggest me the easiest way.
my code so far but it doesn't work :
<?php
// Unique Hits PHP Script
// ----------- March 2004
// Contact author: uniquehits#sizzly.com
$log = 'hits.txt';
$IP = getenv (REMOTE_ADDR);
$add = true;
$hits = 0;
if (!file_exists ($log)) {
echo "Error: $log does not exist.";
exit;
}
$h = fopen ($log, 'r');
if (in_array($IP, array($h))){
header("Location: http://google.com");
}
else{
$fp = fopen('hits.txt', 'a');
fwrite($fp, "'" );
fwrite($fp, $IP );
fwrite($fp, "'" );
fwrite($fp, ',' );
fclose($fp);
header("Location: http://yahoo.com");
}
fclose($h);
?>
appreciated and thankful to you guys .
You could use cookies for this.
It's probably a more reliable way than using IP adress, since a lot of people have a dynamic IP anyway.
http://php.net/manual/en/features.cookies.php
thank you , you helped very much, cookies worked very well, much appreciated.
cookies + php :)
here's the code incase someone else would need it:
<!DOCTYPE html>
<html>
<body>
<?php
$IP = getenv (REMOTE_ADDR);
$verifier = "verify";
$cookie_value = $IP;
if(!isset($_COOKIE[$verifier])) {
setcookie($verifier, $cookie_value, time() + (86400 * 30), "/"); // 86400 = 1 day
header("Location: http://google.com");
} else {
header("Location: http://yahoo.com");
}
?>
</body>
</html>
I've placed a hit counter on my page. It reads a text file, increments the number in the file, and later in the page, I output the incremented value.
$hitsFile = "hits/exps/stats.txt";
$hits = file($hitsFile);
$hits[0]++;
$fp = fopen($hitsFile , "w");
flock($fh, LOCK_EX);
fwrite($fp , $hits[0]);
fclose($fp);
My problem is that if I reload the page, the code will increment the hits. I don't want that. I thought of using session to fix that, but with session, in order the increment the hits again, I need to exit the site and visit again. I don't want that either.
I want it to increment not when I reload the page but when I revisit the page.
For example, let's say I have two-page website, Home and Contact, and on contact page I have a hit counter. I don't want the hit counter to increment if I reload(refresh) the contact page, but if I leave the contact page and visit homepage, and later revisit the contact page, I want it to increment.
In short, I don't want it to increment on page reload. Is there a way to do that?
In each of your pages, you need to write the page name in the session.
Do something like this:
$_SESSION['page'] = 'contact';
On the pages where you need to count hits, you need to check this session key.
For example, if you were on page 'contact', then $_SESSION['page'] == 'contact'.
Now when you go to visit the 'homepage':
$page = $_SESSION['page'];
if($page != 'homepage')
{
//increment your hits counter
$_SESSION['page'] = 'homepage';
}
I suggest this method, is my preferred, create in root these folders: cnt and log... then put inside cnt folder the following files cnt.php and showcnt.php...
cnt.php
<?php
##############################################################################
# Php Counter With Advanced Technology For The Prevention Of Reloading Pages #
# Version: 1.4 - Date: 13.11.2014 - Created By Alessandro Marinuzzi [Alecos] #
##############################################################################
function cnt($file) {
session_start();
global $pagecnt;
$reloaded = isset($_SERVER['HTTP_CACHE_CONTROL']) && $_SERVER['HTTP_CACHE_CONTROL'] === 'max-age=0';
$thispage = basename($_SERVER['SCRIPT_FILENAME']);
if (!isset($_SESSION['first_go'])) {
$_SESSION['first_go'] = 1;
$first_go = TRUE;
} else {
$first_go = FALSE;
}
if (!isset($_SESSION['thispage'])) {
$_SESSION['thispage'] = $thispage;
}
if ($_SESSION['thispage'] != $thispage) {
$_SESSION['thispage'] = $thispage;
$new_page = TRUE;
} else {
$new_page = FALSE;
}
$pagecnt = rtrim(file_get_contents($file));
if ((!$reloaded) && ($new_page == TRUE) || ($first_go == TRUE)) {
$fd = fopen($file, 'w+');
flock($fd, LOCK_EX);
fwrite($fd, ++$pagecnt);
flock($fd, LOCK_UN);
fclose($fd);
}
}
?>
showcnt.php
<?php
##############################################################################
# Show Counter Results - v.1.4 - 13.11.2014 By Alessandro Marinuzzi [Alecos] #
##############################################################################
function gfxcnt($file) {
global $number;
$number = rtrim(file_get_contents($file));
$lenght = strlen($number);
$gfxcnt = "";
for ($i = 0; $i < $lenght; $i++) {
$gfxcnt .= $number[$i];
}
$gfxind = "<span class=\"counter\"><span class=\"number\">$gfxcnt</span></span>";
echo $gfxind;
}
?>
Well, then edit your index.php or other php page... and put at the beginning this piece of code:
<?php session_start(); include("cnt/cnt.php"); cnt("log/index.txt"); include("cnt/showcnt.php"); ?>
Well, then edit index.php or other php page... and use this piece of code for reading counter file:
<?php gfxcnt("log/index.txt"); ?>
It's all, I hope you'll find my answer useful :) My counter can write/read multiple php pages...
Source: my blog (https://www.alecos.it/new/101/101.php)
Add session_start(); to the top.
Now change your if to this:
if (!isset($_SESSION['lastpage']) || $_SESSION['lastpage'] != $_SERVER['QUERY_STRING') {
$hits[0]++;
}
$_SESSION['lastpage'] = $_SERVER['QUERY_STRING'];
This will basically force someone to move to another page if they want to increment the counter.
Update the hit count only if the current URL is not stored in $_SESSION['url'].
After updating the hit count, store the current URL in $_SESSION['url'].
i am working on a project which one of our web application would be somehow JavaScript code to gather statistical information about visitors but as far as i know on server side PHP application i should somehow handle the code in a way that multi refresh doesn't count and counting on IP based is not a good idea since many users may have the same IP , cookie or session are also vulnerable to this issue because cookie manager can just wipe out all the cookie related to the site so PHP won't recognize the user and count it new,timeframe jobs and all other way to get-around of this issue are also as far as i know based on cookie or session or ip or a mixture of ip/referrer and all other available data from header, how can i handle it and get more reliable data from users and don't permit them to create fake stats. as i believe there must be a way (i hope so)...!?
I think cookies would be ideal for this kind of problem, but if you do not want to use that then you've got yourself a tough cookie. Unfortunately you don't have many other options since HTTP is stateless.
I would use session vars in this case since the user cannot meddle with the data saved there. There is however the risk of session hijacking, but if your site is open to that vulnerability you need to look at securing the site on a more global level that just the hit counter. The session variable is bound to your site since the data in it is saved on the server rather than in the users browser. And is bound to your user since it saves a cookie with a key in the users browser to request the data from the server.
Here is an example on how you can implement this and not worry about deleting other sessions on the site.
<?php
function hit_counter() {
if(isset($_SESSION['hit_counter'])) { // Check if the user has the hit_counter session
if(isset($_SESSION['hit_counter']['time']) && isset($_SESSION['hit_counter']['page'])) { // Check if the user has the time and the page set from the last visit
$last_time = $_SESSION['hit_counter']['time'];
$last_page = $_SESSION['hit_counter']['page'];
$now = time(); // The current UNIX time stamp in seconds
$current_page = $_SERVER['REQUEST_URI']; // The page name
/*
If the users hasn't requested this page
in the last 10 seconds or if the user
comes from another page increment the
hit counter
*/
if(($now - $last_time) > 10 || $last_page != $current_page) {
/* INCREMENT YOUR HIT COUNTER HERE */
}
}
unset($_SESSION['hit_counter']); // Delete this hit counter session
}
// And create a new hit counter session
$_SESSION['hit_counter'] = array();
$_SESSION['hit_counter']['time'] = time();
$_SESSION['hit_counter']['page'] = $_SERVER['REQUEST_URI'];
}
?>
You will never touch any of the other session variables since you're only unset()ing the hit counter variable. There is no need for you to handle session_destroy(), but you need to make sure that there is a session_start() in the beginning of every page you would like to use function in.
You could edit the script to not factor in time if you'd only want to count hits if the user comes from another page on your site.
This is as far as I can see, a hit counter with a sensible level of security for most sites. Or at the very least a good start.
Some more information about PHP sessions.
I created this
<?php
namespace Codelaby\EventDateGenerator;
class CounterVisitors
{
private $filename = "counter.txt";
private $sessionId;
private $sessionStart;
public function __construct()
{
if (session_status() == PHP_SESSION_NONE) {
session_start();
}
if (!isset($_SESSION['sessionId'])) {
$this->sessionId = md5(uniqid(rand(), true));
$_SESSION['sessionId'] = $this->sessionId;
$this->sessionStart = time();
$this->hitCounter();
} else {
$this->sessionId = $_SESSION['sessionId'];
if (!isset($_SESSION['sessionStart'])) {
$this->sessionStart = time();
} else {
$this->sessionStart = $_SESSION['sessionStart'];
}
if (time() - $this->sessionStart > 60) {
$this->sessionStart = time();
$this->hitCounter();
}
}
$_SESSION['sessionStart'] = $this->sessionStart;
}
private function saveCounter($counter = 0)
{
if (!file_exists($this->filename)) {
touch($this->filename);
}
$fp = fopen($this->filename, "w");
if (!flock($fp, LOCK_EX)) {
return;
}
fwrite($fp, $counter);
flock($fp, LOCK_UN);
fclose($fp);
}
public function readCounter()
{
if (!file_exists($this->filename)) {
touch($this->filename);
}
$fp = fopen($this->filename, "r");
if (!flock($fp, LOCK_EX)) {
return;
}
$file_size = filesize($this->filename);
if ($file_size <= 0) {
$counter = 0;
} else {
$counter = intval(fread($fp, $file_size));
}
flock($fp, LOCK_UN);
fclose($fp);
return $counter;
}
public function hitCounter()
{
$counter = $this->readCounter();
$counter++;
$this->saveCounter($counter);
return $counter;
}
public function resetCounter($counter = 0)
{
$this->saveCounter(0);
}
}
How to use
session_start() //before send headers
$counterVisitors = new CounterVisitors();
$visitors = $counterVisitors->readCounter();
echo 'visitors: ' . $visitors;
The script generate counter.txt if not exist, only increment visit if user start new session or wait 60 seconds for refresh
PROBLEM
I've got an admin panel. Currently only Mozilla is able to process log ins. Browsers like Chrome, IE, Opera won't even show any message carried through sessions thus no one is able to log in any browser but Mozilla.
SOME INFORMATION
I'm using PHP 5.3.6 on my server, PHP 5.3.5 on my local
computer.
My code is Object Oriented.
ini_set("session.use_only_cookies", 1); and
ini_set('session.cookie_secure', 1); are used in construction method
of my session class.
This website on SLL
Login process: First I gather all information from form, validate and gather data. After validation if everything is right, I send this data to login method in my session class.
public function login ($user) {
global $siteSettings;
if ($user) {
$this->id = $_SESSION['id'] = $user->id;
$this->username = $_SESSION['username'] = $user->username;
$this->fullName = $_SESSION['fullName'] = $user->fullName;
$this->group_id = $_SESSION['group_id'] = $user->group_id;
$this->groupName = $_SESSION['groupName'] = $user->groupName;
$this->lastLogin = $_SESSION['lastLogin'] = $user->lastLogin;
$this->isAdmin = $_SESSION['isAdmin'] = ($user->admin == 1) ? true : false;
$this->isAgent = $_SESSION['isAgent'] = ($user->agent == 1) ? true : false;
self::$language = $_SESSION['language'] = ($user->language != "" || $user->language != NULL) ? $user->language : self::$language;
if ($user->language != "" || $user->language != NULL) {
$_SESSION['language'] = $user->language;
}else {
if (!defined(DEFAULT_LANGUAGE)) {
$browserLang = "|".$_SERVER["HTTP_ACCEPT_LANGUAGE"];
$browserLang = getStringBetween($browserLang, "|","-", FALSE);
if (!file_exists(LANGUAGES.$browserLang.".php")) $browserLang = FALSE;
}
$_SESSION['language'] = ($browserLang) ? $browserLang : DEFAULT_LANGUAGE;
}
# When 2 Update session_id
$date = new DateTime("now");
$UpdateTime = $siteSettings->session->timeOut * 60;
$date->add(new DateInterval("PT".$UpdateTime."S"));
$_SESSION['SIDUpdateTime'] = $date->format("Y-m-d G:i:s");
# UPDATE LAST LOGIN & ADD SESSION ID
# Clear Fields
members::clearFields();
members::$fields['id'] = $_SESSION['id'];
members::$fields['lastLogin'] = date("Y.m.d G:i:s");
members::$fields['lastLoginIP'] = $_SERVER['REMOTE_ADDR'];
# GET THE SALT
$saltInfo = members::getData("id", "salt", members::$fields['id']);
# SETTING SESSION ID ENCRYPTION
crypt::setKey($saltInfo->salt);
members::$fields['sessionID'] = crypt::encode(session_id());
members::$fields['sessionIP'] = $_SERVER['REMOTE_ADDR'];
members::$fields['sessionAgent'] = $_SERVER['HTTP_USER_AGENT'];
members::save();
$this->loggedIn = true;
var_dump($_SESSION);
}
}
When I dumb the data I can see $_SESSION got some values.
Just to test it, I stopped the script where after var_dump($_SESSION); (added die();) I created test.php file and tried this;
<?php
ob_start();
session_start();
echo '<pre>';
var_dump($_SESSION);
echo '<pre>';
ob_end_flush();
?>
Output is array(0) {}
But when I try exactly the same thing with Mozilla, output of test.php is the way it should be (matching with login method's result in my session class).
I have tried from my local computer and I don't experience the same
problem.
I disabled all java script and jquery codes from the page just to
have no 'maybe' in my mind.
After dumping the data, script is stopped. That's why $_SESSION variable shouldn't change. For some reason when it is on the server only Mozilla is able to show expected result while other browsers shows NULL.
At this point I really don't know what to think of about this problem to try to solve it. All I can think of is, this problem is possibly related to server configuration. But then, PHP is server side programming. PHP shouldn't display different behavior for browsers like Jquery, CSS, HTML...
I'm sorry, I can't provide admin panel link. Considering this is an active admin panel. If necessary I could install it on another domain to let you try but I believe the information I gave above explains everything.
Thank you for your help in advance.
I had a similar problem... just enable the cookies.. so that after login the code to set the sessions will be executed and the sessions will be set. may be the sessions r not able to set...
also check this http://php.net/manual/en/function.session-cache-limiter.php
If something large doesn't work, trim it down, test & debug, and build up from there.
Does this work? (Run it twice).
<?php
session_start();
echo "Session ID: " . session_id() . "<br/>\n";
if (!isset($_SESSION['test']))
{
$_SESSION['test'] = "foobar";
echo "Setting session variable: ";
echo $_SESSION['test'];
}
else
{
echo "Restoring session variable: ";
echo $_SESSION['test'];
}
If this works in all browsers, it's got something to do with your code. An empty session might have something to do with a cookie that can't be written, for example. Also set error reporting to E_ALL | E_STRICT, so you'll see everything that goes wrong.
It turns out Mozilla FireFox is able to process some data but other browsers I tried with are not and therefore they reset the whole session with each page load.
I had no problem with my local computer but on the server I had sessions problem. I don't know why session_set_cookie_params(); and setcookie(); didn't work on the server so I had to code longer version;
private static function sessionLifeTime() {
global $siteSettings;
# HOW LONG WE WANT SESSIONS
$lifeTime = intval($siteSettings->session->timeOut) * 60;
if (isset($_SESSION['id']) && isset($_SESSION['lastActivity']) && (time() - $_SESSION['lastActivity'] > $lifeTime) ) {
// SEND INFORMATION TO USER
self::logout();
}
$_SESSION['lastActivity'] = time();
}
Replacing my method with the code above solved the problem.
Thank you all for your time, concern and interest.