Help With Php Ip Ban Script
- DoomyCheese
-
DoomyCheese
- Member since: Aug. 25, 2006
- Offline.
-
- Forum Stats
- Member
- Level 09
- Blank Slate
I have a contact form on my website that is rather exploitable, I've implemented the below code into the page as a means of stopping spammers (incoming mail includes the senders IP), but it's a pain to add new bans.
<?php
$banned = array("70.248.51.77", "75.156.110.47");
if (in_array($_SERVER['REMOTE_ADDR'], $banned)) {
header( 'Location: banned.html' ) ;
exit;
}
?>
What I would really like is a form in which I can easily add/remove bans to this script. Can anyone help me with this?
- Loccie
-
Loccie
- Member since: Feb. 27, 2004
- Offline.
-
- Forum Stats
- Member
- Level 16
- Blank Slate
You're going to have to save the IPs in some sort of database if you want to save them. The form can then save it to the databse and the ban script can get all the info from the database.
- Fruitpastles
-
Fruitpastles
- Member since: Oct. 13, 2005
- Offline.
-
- Forum Stats
- Member
- Level 10
- Blank Slate
Hi,
I wrote you something the otherday in school. I only just remembered, I'll see if I can get it.
- Fruitpastles
-
Fruitpastles
- Member since: Oct. 13, 2005
- Offline.
-
- Forum Stats
- Member
- Level 10
- Blank Slate
<?php
/**********************************************
* AUTHOR: Craig Kewley
* E-MAIL: fruitpastles@gmail.com
* DESCRIPTION: IP Address ban functionality
***********************************************/
//*********************
// SETTINGS
//*********************
//change me :)
define("USERNAME", "user1");
define("PASSWORD", "pass1");
define("SALT", "ksjf94w38auja8q93u");
define("FILE_NAME", "bans.txt");
define("BAN_MESSAGE", "<b>Access Denied</b><br/>");
//*********************
// FUNCTIONS
//*********************
//LOGIN - checks username and password
function login($username, $password)
{
//if username and password were correct
if($username == USERNAME && $password == PASSWORD)
{
//encrypt password
$code = crypt(USERNAME, SALT);
//start session
session_start();
//set auth cookie with code
setcookie("auth", $code);
//fill session var with code
$_SESSION['auth'] = $code;
//regen session id
session_regenerate_id();
//login successful
return true;
}
else //credentials incorrect
{
//login failed
return false;
}
}
//logout - destroys login info
function logout()
{
//if logged in
if( isLoggedIn() )
{
//initialize session
session_start();
//destroy session
session_destroy();
//fill the session global empty
$_SESSION = array();
//set expiration in the past
$expires = mktime(0, 0, 1, 1, 1990);
//remove auth cookie
setcookie("auth", "", $expires);
}
return true;
}
//ISLOGGEDIN - check if logged in
function isLoggedIn()
{
//ensure new session is not set if not logged in
if( isset($_COOKIE['auth']) && !isset($_SESSION['auth']) )
{
session_start(); //initialize session
}
//check if session and cookie exist
if( !isset($_SESSION['auth']) || !isset($_COOKIE['auth']) ) //or not xor
{
return false;
}
else
{
//if hashes are the same
if($cookieCode == $sessionCode)
{
return true;
}
else //codes don't match
{
//destroy login files
logout();
//codes dont match - return false
return false;
}
}
}
//ISBANNED - checks if user has been banned
function isBanned($ip)
{
//get list of bans and split into array
$bans = getBans();
$bans = explode(";", $bans);
//check if ip is in ban list
if( in_array($ip, $bans) )
{
return true;
}
else
{
return false;
}
}
//ADDBAN - add ban to list
function AddBan($ip)
{
//open file
$fs = fopen(FILE_NAME, "a");
//prep string ';' delimiter
$toWrite = $ip. ";";
//overwrite data in file with new
fwrite($fs, $toWrite);
//close file
fclose($fs);
return true;
}
//REMOVEBAN - remove ban from list
function RemoveBan($ip)
{
//prep ip - ';' delimiter
$ip .= ";";
//get ban list
$bans = getBans();
//replace the string if found
$bans = str_replace($ip, "", $bans);
//open file
$fs = fopen(FILE_NAME, "w");
//overwrite with new complete + new data
fwrite($fs, $bans);
//close
fclose($fs);
}
//GETBANS - returns list of bans
function getBans()
{
//if file has data
if( filesize(FILE_NAME) != 0)
{
//open file
$fs = fopen(FILE_NAME, "r");
//get list from file
$bans = fread($fs, filesize(FILE_NAME) );
//close
fclose($fs);
//return data - i suppose i could return it as an array or summit but cba now ;P.
return $bans;
}
else //file contains no data
{
return false;
}
}
//REDIRECT - redirect user
function redirect($location)
{
//check if http headers already sent
switch( headers_sent() )
{
//if not then redirect using header
case false:
header("Location: " . $location);
break;
//else use meta refresh
case true:
echo('<meta http-equiv="refresh" content="0;url=' . $location . '">');
break;
}
//output link incase of fail
die('<a href="' . $location . '"><b>Click here to continue...</b></a>');
}
//*********************
// Main
//*********************
//--GRAB THE ACTION VARIABLE
(isset($_GET['act'])) ? extract($_GET) : $act = NULL;
//--PROCESS ACTION VARIABLE
switch($act)
{
//--LOGIN
case "login":
if( !isset($_POST['username']) || !isset($_POST['password']) )
{
echo('<form action="?act=login" method="post">
Username: <input type="text" name="username"><br>
Password: <input type="password" name="password"><br>
<input type="submit" value="login">');
}
else
{
if( login($_POST['username'], $_POST['password']) )
{
redirect("?act=main");
}
else
{
die("Incorrect Username or Password.<br>
<a href='?act=login'>Re-try...</a>");
}
}
break;
//--LOGOUT
case "logout":
logout();
redirect("?");
break;
//--ADD
case "add":
if( isLoggedIn())
{
AddBan($_POST['ip']);
redirect("?act=main");
}
else
{
redirect("?");
}
break;
//--REMOVE
case "remove":
if( isLoggedIn())
{
RemoveBan($_GET['ip']);
redirect("?act=main");
}
else
{
reidrect("?");
}
break;
//--MAIN
case "main":
//LOGIN STUFF
if ( !isLoggedIn() )
{
redirect("?");
}
else
{
echo( "<b>" . ucfirst(USERNAME) . "</b>(<a href='?act=logout'>Logout</a>)<br><br>");
}
//BAN LIST STUFF
if( !getBans() ) //if list is empty
{
echo('<table cellspacing="1" border="1">
<tr> <td>IP</td> <td>Remove</td> </tr>
<tr> <td colspan="2" align="center">None</td> </tr>
</table><br><br>');
}
else //list the bans
{
//get bans
$bans = getBans();
//split into array
$bans = explode(";", $bans);
//table start
echo('<table cellspacing="1" border="1">
<tr> <td>IP</td> <td>Remove</td> </tr>');
foreach($bans as $id => $ip)
{
if($ip != "")
{
//output for each ban
echo('<tr> <td>'. $ip .'</td> <td> <a href="?act=remove&ip='. $ip .'">Remove</a> </td> </tr>');
}
}
//end table
echo('</table><br><br>');
}
//add ban form
echo('<form action="?act=add" method="post">
IP: <input type="text" name="ip"><br>
<input type="submit" value="Add">
</form>');
break;
//--DEFAULT - check username
default:
if( isBanned( $_SERVER['REMOTE_ADDR'] ))
{
die(BAN_MESSAGE);
}
}
?>
To use just put the following on the first line the file you want to protect: (after changing "PATH_TO")
<?php require("PATH_TO/ipban.php"); ?> - henke37
-
henke37
- Member since: Sep. 10, 2004
- Offline.
-
- Forum Stats
- Member
- Level 30
- Blank Slate
I have to say, that looks like a very profesional script. Too bad it has one sevre bug, you never set $cookieCode (and the other variable).
Each time someone abuses hittest, God kills a kitten. Please, learn real collision testing.
- Fruitpastles
-
Fruitpastles
- Member since: Oct. 13, 2005
- Offline.
-
- Forum Stats
- Member
- Level 10
- Blank Slate
At 6/12/08 05:46 AM, henke37 wrote: I have to say, that looks like a very profesional script. Too bad it has one sevre bug, you never set $cookieCode (and the other variable).
Oh god! Now I just feel stupid. I took the isLoggedIn() function from another one of my scripts and changed it. In my other one, I run a check on the data coming in through the cookie and session, before assigning them to the, now unset, variables.
Normally I would have spotted that but it was rushed slightly, stupid that I didn't use error_reporting(E_ALL); as well. Although looking at it, It would have been difficult for somebody to set $_SESSION['auth'] without knowing the login information.
Anyway Thanks a lot for pointing that out :)!
@DoomyCheese
Replace the Logout(); and isLoggedIn(); function with the following:
//logout - destroys login info
function logout()
{
//initialize session
session_start();
//destroy session
session_destroy();
//fill the session global empty
$_SESSION = array();
//set expiration in the past
$expires = mktime(0, 0, 1, 1, 1990);
//remove auth cookie
setcookie("auth", "", $expires);
return true;
}
//ISLOGGEDIN - check if logged in
function isLoggedIn()
{
//ensure new session is not set if not logged in
if( empty($_COOKIE['auth']) || empty($_SESSION['auth']) ) //or not xor
{
session_start(); //initialize session
}
else
{
return false; //not logged in
}
//check if both empty - will equal if both are
if( empty($_COOKIE['auth']) || empty($_SESSION['auth']) )//or not xor
{
//are empty - destroy
logout();
//redirect
redirect("?");
}
//if hashes are the same
if($_COOKIE['auth'] == $_SESSION['auth'])
{
return true;
}
else //codes don't match
{
//destroy login files
logout();
//codes dont match - return false
return false;
}
} - henke37
-
henke37
- Member since: Sep. 10, 2004
- Offline.
-
- Forum Stats
- Member
- Level 30
- Blank Slate
Now some comments contradicts other comments and the actual code.
Each time someone abuses hittest, God kills a kitten. Please, learn real collision testing.
- Fruitpastles
-
Fruitpastles
- Member since: Oct. 13, 2005
- Offline.
-
- Forum Stats
- Member
- Level 10
- Blank Slate
At 6/13/08 12:45 PM, henke37 wrote: Now some comments contradicts other comments and the actual code.
Meh it works, the first empty check should be isset though. Doesn't look like the authors coming back anyways.
At 6/13/08 02:48 PM, bagoverhead wrote: giving crutches to a cobra >.<
Matter of opinion...its just a little more convenient.
I don't understand the reason you have to get so annoyed when I PM you to ask the meaning of your comments either?


