[SHARE] More secure php scripts L2J 

Newbie Spellweaver
Joined
Oct 25, 2006
Messages
13
Reaction score
0
I've seen a lot of php scripts posted around here for account registration and other such things that are all vulnerable to SQL injection.

If you don't know what SQL injection is, all you need to know about it as it relates to your server's website is that a malicious user could use your own php scripts to modify your server's database or potentially even take full control of your MySQL database.

So I've spent some time writing more secure php scripts for use on my own website and decided to share them here.

One word of caution: SQL Injection may still be possible if a user finds a way to pass a "change charset" command to your MySQL database. I can't think of a way to do that through any of these scripts, so they *should* be safe.

Account registration:

PHP:
<?php
//set host, username and password for MySQL
$dbhost = "localhost";
$dbuser = "YOURMYSQLUSERNAME";
$dbpass = "YOURMYSQLPASSWORD";
 
//connect to MySQL or return an error
$conn = mysql_connect("$dbhost", "$dbuser", "$dbpass")
or die('Could not connect: ' . mysql_error());
 
//set database name
$dbname = "l2jdb";
 
//select database or return an error
$dbselect = mysql_select_db("$dbname") 
or die ('Could not select database');
 
//get username and password info from the form, protecting against SQL injection
$pass = mysql_real_escape_string($_POST["pass"]);
$confirm = mysql_real_escape_string($_POST["confirm"]);
$user = mysql_real_escape_string($_POST["name"]);
 
//validate user input
if(!preg_match('/^[a-zA-Z0-9]{5,20}$/',$user)) {
die ('Error: Usernames can only contain alphanumeric characters and must be between 5 and 20 characters in length.');
}
 
if(!preg_match('/^[a-zA-Z0-9]{5,20}$/',$pass)) {
die ('Error: Passwords can only contain alphanumeric characters and must be between 5 and 20 characters in length.');
}
 
if($pass != $confirm) {
die ('Error: Passwords do not match.');
}
 
//make sure user doesn't already exist and if it doesn't, add new record to the database
$result = mysql_query("SELECT login FROM accounts WHERE login='$user'");
 
if(mysql_num_rows($result)>0) {
die ('Error: Username already exists.');
}else{
mysql_query("INSERT INTO accounts (login, password, access_level) VALUES ('".$_POST['name']."', '".base64_encode(pack('H*', sha1($_POST['pass'])))."', 0)")
or die ('Error: ' . mysql_error());
}
 
//report successful registration
echo "Account created successfully.";
 
//close MySQL connection
mysql_close();
 
?>

Save this as acc.php and then use the following html to add the account registration form to your webpage

Code:
<form action="acc.php" method=post>
UserID: <input type="text" name="name" size=20><br><br>
Password: <input type="password" name="pass" size=20><br><br>
Confirm Password: <input type="password" name="confirm" size=20><br><br>
<input type=submit name="submit" value="Create"></form>

The script has built in protection against SQL injection and also forces the user to submit a username and password that are between 5 and 20 characters in length, and limits them to only alphanumeric characters.

Password reset scripts are even more subject to SQL injection exploits, so here is a (to the best of my knowledge) secure password reset script.

PHP:
<?php
 
//set host, username and password for MySQL
$dbhost = "localhost";
$dbuser = "YOURMYSQLUSERNAME";
$dbpass = "YOURMYSQLPASSWORD";
 
//connect to MySQL or return an error
$conn = mysql_connect("$dbhost", "$dbuser", "$dbpass")
or die('Could not connect: ' . mysql_error());
 
//set database name
$dbname = "l2jdb";
 
//select database or return an error
$dbselect = mysql_select_db("$dbname") 
or die ('Could not select database');
 
//get username and password info from the form, protecting against SQL injection
$user = mysql_real_escape_string($_POST["name"]);
$currentpass = mysql_real_escape_string($_POST["currentpass"]);
$newpass = mysql_real_escape_string($_POST["newpass"]);
$confirm = mysql_real_escape_string($_POST["confirm"]);
 
//username and password should already be valid and newpass and confirm should match or this script will die
//so just validate the newpass and then check to see if newpass and confirm are the same
if(!preg_match('/^[a-zA-Z0-9]{5,20}$/',$newpass)) {
die ('Error: Passwords can only contain alphanumeric characters and must be between 5 and 20 characters in length.');
}
 
if($newpass != $confirm) {
die ('Error: New passwords do not match.');
}
 
//encrypt the passwords
$currentpass = base64_encode(pack('H*', sha1($currentpass)));
$newpass = base64_encode(pack('H*', sha1($newpass)));
 
//if the user input passed all the checks, make sure the account exists and then update the password
$result = mysql_query("SELECT login,password FROM accounts WHERE login='$user' AND password='$currentpass'");
 
if(mysql_num_rows($result)>0) {
mysql_query("UPDATE accounts SET password='$newpass' WHERE login='$user' AND password='$currentpass'");
echo "Password succesfully updated."; 
}else{
die ('Error: Account does not exist or password is incorrect.');
}
 
//close MySQL connection
mysql_close();
 
?>

Save the preceding as changepass.php and use the following HTML to insert a change password form into your website.

Code:
[SIZE=2][SIZE=2]<form action="changepass.php" method=post>[/SIZE]
[SIZE=2]UserID:<input type="text" name="name" size=20><br><br>[/SIZE]
[SIZE=2]Password: <input type="password" name="currentpass" size=20><br><br>[/SIZE]
[SIZE=2]New password: <input type="password" name="newpass" size=20><br><br>[/SIZE]
[SIZE=2]Confirm password:<input type="password" name="confirm" size=20><br><br>[/SIZE]
[SIZE=2]<input type=submit name="submit" value="Update Password">[/SIZE]
[/SIZE]

This script uses the same protection as the registration script, and should be safe against all the SQL injection exploits that I can come up with.

Server status scripts don't take any input from the user, and thus are not susceptible to SQL injection, but here is a server status script that is tested and working, and as a bonus will use graphics to display your server status.

PHP:
<?php
 
//set server, port and timeout information
$server = "localhost";
$portg = "7777";
$portl = "2106";
$timeout = "1";

//try to open a connection to the game and login server 
$game = @fsockopen("$server", $portg, $errno, $errstr, $timeout);
$login = @fsockopen("$server", $portl, $errno, $errstr, $timeout);
 
//let us know if the servers are up or not 
echo $game ? "<img src=\"gameonline.jpg\">" : "<img src=\"gameoffline.jpg\">";
echo $login ? "<img src=\"loginonline.jpg\">" : "<img src=\"loginoffline.jpg\">";
 
 
?>

All you have to do with this one is create a few graphics and insert the preceding php directly into your HTML whever you want the server status displayed. If the script isn't self-explanatory, the graphics you need to create are gameonline.jpg, gameoffline.jpg, loginonline.jpg and loginoffline.jpg.

And last but not least, here is a little script that will display the number of users currently online as a graphic on your webpage.

PHP:
<?php
 
//set host, username and password for MySQL
$dbhost = "localhost";
$dbuser = "YOURMYSQLUSERNAME";
$dbpass = "YOURMYSQLPASSWORD";
 
//connect to MySQL or return an error
$conn = mysql_connect("$dbhost", "$dbuser", "$dbpass")
or die('Could not connect: ' . mysql_error());
 
//set database name
$dbname = "l2jdb";
 
//select database or return an error
$dbselect = mysql_select_db("$dbname") or die ('Could not select database');
 
//select all records from the characters table where that character is currently online
$chars = mysql_query("SELECT online FROM characters where online='1'") or die ('Query failed: ' . mysql_error());
 
//count how many online characters there are
$rows = mysql_num_rows($chars);
 
//convert the number of online characters to a string
$count =(string)$rows;
 
//convert each digit in the string to a graphic
for ($i=0; $i < strlen($count); $i++) { echo('<img src="' . $count{$i} . '.jpg">'); } 
 
//close MySQL connection
mysql_close();
 
?>

Save this as onlineplayers.php and then insert the following code into your html where you want to display the number of online players.

PHP:
<?php
include 'onlineplayers.php';
?>

Now all you need to do is create a graphic for each digit and save them as 0.jpg, 1.jpg, 2.jpg, 3.jpg, 4.jpg, 5.jpg, 6.jpg, 7.jpg, 8.jpg, and 9.jpg. The script will find the number of players currently online and use the graphics you created to diplay the number on your page.

All 4 of these scripts are tested and working. I'm using them on my own webpage right now. I'd post a link so you could see them in use, but I believe that's against the forum rules. If you need any help, leave a message in this thread and I'll do what I can for you. As long as you follow all the instructions, you shouldn't have any trouble.


 
Account Creation page to write self is easy , with and without E-mail activation ....

Search an Character Reset Script ( Set lv 1 from lv 80 )
 
Account Creation page to write self is easy , with and without E-mail activation ....

Search an Character Reset Script ( Set lv 1 from lv 80 )

I find your English a little bit difficult to understand. Do you mean that you are looking for a script to change the level of a character? I could write that for you. But if you can handle account activation with email verification, such a script should be within your capabilities. At any rate, if you need help with it, drop me a reply here and I'll write one for you.
 
I find your English a little bit difficult to understand. Do you mean that you are looking for a script to change the level of a character? I could write that for you. But if you can handle account activation with email verification, such a script should be within your capabilities. At any rate, if you need help with it, drop me a reply here and I'll write one for you.


Hehe no thx ^^ I have written it by myself ^^ Look in my sigature , in this post is a Demo Link , there is the TopList of my Reset Script ;)



@fabrrp :

Learning by doing , look in other scripts and experience with the code , best way to learning fast :P


@threadreaper :
Yeah yeah , but reset is reset , not wipe , not unstuck , reset is set character lv to 1 from 80 , set exp to 0 , set all other noob stats , dont delete Skills , dont delete Adena,Items,Weapons,Armors and Miscs, set new Class , new Race and new Sex ;)
 
Heya, I am expriencing this problem while trying to create new acc.

Error: Unknown column 'access_level' in 'field list'

Any idea how to fix it?
 
have injection sql :
all sql queries must end on ; is end of line no one can add code or -- to remove all other lines down the sql query. And u dont check for " and ' some one can add malicious code in form imput.
Read this into php help:
mysql_escape_string()
addslashes()
str_replace()
 
Any feedback on this?
Is it safe?
I was used these scripts on my server but somehow we were hached!
I had many php scripts (statistics etc) so I can't be sure how they did hacked us.
 
Fix for this error :

"Error: Unknown column 'access_level' in 'field list'"

Replace acces_level into acceslevel from acc.php
 
LOL unescaped $_POST !!! in acc.php
PHP:
mysql_query("INSERT INTO accounts (login, password, access_level) VALUES ('".$_POST['name']."', '".base64_encode(pack('H*', sha1($_POST['pass'])))."', 0)")
 
Back