CAPTCHA with no $_SESSION

Due to the nature of the stateless behavior of HTTP, managing the current state of a connected user is a tricky scenario to handle in web site development or rather in web application development.

Few solutions are in place already and $_SESSION is one of the ways available in PHP. $_SESSION, the global array is not my favorite choice but it is handy. The sever based session management approach is not 100% reliable but it would do the work in most of the cases.

On the other hand, distinguishing user inputs versus inputs from malicious bots seems quite challenging these days. Simple tricks such as “honeypot” are quite old and easy to overcome, of course bots are now capable enough to skip “honeypots” without much effort. Then comes much promising solutions such as Google’s new invention, reCAPTCHA where a sophisticated techniques can identified the origin of the inputs blocking spams on your site, web application etc.

However life is not that easy, there are plenty of scenarios where we need to come up with our own strategy to deal with these inputs. If you cannot use reCAPTCHA or any other 3rd party CAPTCHA solution then the best would be implementing one of your own. This is the riskiest but there can be instances that this is the only way forward. I was in such a situation few months back and I though of sharing how I overcame it.

Avoiding $_SESSION

It is not hard to find plenty of tutorials to follow, implementing simple CAPTCHA verification in PHP. Almost every solution is based on $_SESSION, using server based sessions, a global array in PHP. This is easy and simple. Few lines of code would do the trick. As same as the way mentioned in this article. I am not a fan of server based sessions therefore I wanted to skip it.

In this post I am trying to explain how I solved the stateless issue without using server based sessions.

Breaking the Problem

The main issue that we need to solve is identifying the legitimate requests/ inputs and filter out the rest. In order to achieve this, when the relevant input form has been requested by a client, the server adds an image which is a human readable text. Bots may not be able to identify what is in it. Then the user inputs the code and sends the request to the server. As it is not possible to include the verification code in the client side request, the server doesn’t know what has been sent earlier. That is where server based sessions comes for the rescue. It is possible to store the verification code in a session variable.  Then when the user has submitted the form, the server can simply checks if the entered verification code value matches the value in the session. If so it is a human, test passes. Since we are trying to omit using server based sessions, we need to come up with a way to identify what has been sent earlier.

Solution

Step 1

Following is a typical code snippet (captcha.php) to create the CAPTCHA image. It is pretty straight forward and it can be seen that the verification code has been assigned to the session variable, $_SESSION[‘rand_code’] = $string;

<?php
session_start();

$string = '';

for ($i = 0; $i < 5; $i++) {     // this numbers refer to numbers of the ascii table (lower case)
$string .= chr(rand(97, 122)); }   
$_SESSION['rand_code'] = $string;   
$dir = 'fonts/';   
$image = imagecreatetruecolor(170, 60); 
$black = imagecolorallocate($image, 0, 0, 0); 
$color = imagecolorallocate($image, 200, 100, 90); // red 
$white = imagecolorallocate($image, 255, 255, 255);   imagefilledrectangle($image,0,0,399,99,$white); 
imagettftext ($image, 30, 0, 10, 40, $color, $dir."arial.ttf", $_SESSION['random_code']);   
header("Content-type: image/png"); 
imagepng($image); 
?>

Following shows how it has been included in the HTML, client side.

<form action="<?php echo $_SERVER['PHP_SELF']; ?>
" enctype="multipart/form-data" method="post"><input name="name" type="text" />

<input name="email" type="text" />

<textarea name="message"></textarea>

<img src="captcha.php" />

<input name="code" type="text" />

<input name="submit" type="reset" value="Send" />
</form>

When analyzing the HTML code, you will soon realize that the code can be exploited simply with a Cross Site Scripting (XSS) attack as it barely uses $_SERVER[‘PHP_SELF’] in form action. I will not be focusing on that since I am not going to use sessions here. Following is the modified prototype version.

Step 2

I have changed the client side code as follow. Notice that a hidden filed has been introduced. A randomly generated number with hash coded act as the reference id here. The reference has been passed when creating the CAPTCHA image and also it gets submitted when the user submits the form.

<?PHP
require_once 'dataBaseConnection.php';
<form action="verify.php" enctype="multipart/form-data" method="post">
Name: <input name="name" type="text" />

Email <input name="email" type="text" />

Message
<textarea name="message"></textarea>

<!--?PHP   $captchaId = sha1(rand(1000000,9999999).time());  dataBaseConnection::registerReference($captchaId);  $path='captcha.php?ref='.$captchaId;   ?--> <img src=""<?PHP" /> "/>
Enter the above code
<input name="c_id" type="hidden" value="<?PHP echo $captchaId; ?>" />

<input name="code" type="text" />

<input name="submit" type="submit" value="Send" />

and then the captcha.php has been modified too.

<?php
$string = '';
$refCode = '';

if(isset($_GET['ref']))
{
$refCode = $_GET['ref'];
}else{
die('<error>NO REF CODE FOUND !</error>');
}

for ($i = 0; $i < 8; $i++)
{
// this numbers refer to numbers of the ascii table (lower case)
$string .= chr(rand(97, 122));
}

$dir = 'fonts/';

$image = imagecreatetruecolor(170, 60);
$black = imagecolorallocate($image, 0, 0, 0);
$color = imagecolorallocate($image, 10, 10, 10); // red
$invColor = imagecolorallocate($image, 200, 200, 200); // invisible_ink
$white = imagecolorallocate($image, 255, 255, 255);

imagefilledrectangle($image,0,0,399,99,$white);
for($i=0; $i<100; $i++) 
{ 
imagettftext ($image, 20, rand(0,10), 0, $i*10, $invColor, $dir."ts.ttf", 'xxxxxxxxxxxxxxxxxxxxxxxxx'); 
} 
imagettftext ($image, 30, 2, 10, 40, $color, $dir."ts.ttf", $string);
header("Content-type: image/png"); 
imagepng($image); 
require_once 'dataBaseConnection.php'; dataBaseConnection::addVerificationCode($refCode, $string); //store the reference and the code in the database 
?>

The static methods dataBaseConnection::registerReference stores the reference code which will later be an input to captcha.php. The system automatically logs the timestamp and set the status of the record to ‘CREATED’. Then in the captcha.php file static method dataBaseConnection::addVerificationCode adds the generated verification code to the relevant reference .

Step 3

Then comes the verify.php code which validates the entered code against the code in the database.

<?php require_once 'dataBaseConnection.php'; if(isset($_POST['submit']))   {  	$enteredCode=trim($_POST['code']);  	$referenceCode=trim($_POST['c_id']);     $dataSet = dataBaseConnection::getCode($referenceCode);     $timeTaken = time() - $dataSet['pvt_created_date'];     if($timeTaken>$dataSet['pvt_life_time'] || $dataSet['pvt_captcha_status']!='CREATED')
    {
    	die('expired code');
    }

    //var_dump($referenceCode); die($enteredCode);
	if($enteredCode==$dataSet['str_verification_code'])
	{
		dataBaseConnection::updateCode($referenceCode,'VERIFIED');
		echo 'verified';//this is a human
		//Process the input as this is a legit request
	}else{
		dataBaseConnection::updateCode($referenceCode);
		echo 'not verified';//most probably not a human
	}
}
?>

If both codes match then the static method dataBaseConnection::updateCode changes the status of the verification code to ‘VERIFIED’ in the database while the status has been set to ‘USED’ for the verification code if they dont match. That expires the verification code and it will not be possible to use it again. Further there is a check to make sure that the code has not been expired too.

How secure this is

It is not difficult to train a bot to reading CAPTCHAs. Therefore to make this much stronger it is required to have an image with higher entropy.

Another weak point is, the reference code is getting exposed to the attacker. However there reference number has no relationship with the code. Therefore the attacker cannot predict the code by cracking the reference code. This is possible as we store the reference and the verification code in the database.

An attacker cannot use a brute force attack as the status of the verification code has been updated after an attempt has been made disregarding the results. So once tried the code is set to expired. Setting lifetime of the code can be used to limit the time available for the attacker to crack the image. In this case 300 seconds.

Further it is required to restrict direct access to captcha.php file from the outside, simply using .htaccess entry. Otherwise it is possible to carry out a Denial-of-service attack targeting the generation of the captcha image which in return could have lead to a database failure.

It is important to track client details but will discuss it in another post.

Conclusion

How to implement a captcha verification solution without using server based sessions has been discussed above. Complete source code can be found here. Please check it out and let me know any flaws you observe. This is a mere implementation of the concept and no other aspects were considered when developing the code and no proper testing has been carried out. Therefore if you are going to use it in your code please be careful unless you know what you are doing.

Advertisements

Finding MAC Address (MAC Filtering cont.)

One of my friends has read the article on MAC Filtering and inquired an easy way to find out the MAC addresses of the devices. This the easiest I came across so far.

You need to log into the admin panel of the router, find the place which shows the connected/ (or history of the connected devices). It gives the list of MAC addresses along with some identification. (Eg: in my routers home page it shows the device history with MAC addresses and an identification tag, it says AA:BB:CC:DD:EE:FF and iPhone, so I figured out it is my wife’s. The dumbest thing in my home, ohhh no not the wife I meant, but the iPhone)

Get the list and add it to the MAC filter. It is simple.

Any better idea? Please comment !

Wifi Security: Enable MAC Filtering

Some months back I wrote an article regarding the Wifi security and in this article I am trying to explain MAC Filtering on Dialog 4G router. I updated this list in my router few days back and though of sharing.

What is MAC Filtering?

It is easy to understand. It is a list with MAC addresses of physical devices. If your device MAC address is in the list, the access granted (given that you enter the password correctly if the hotspot is password protected).

Analogy: You got a ticket(password) for a VIP Club party but unfortunately someone has stolen it. The person who stole it then go to the part and present the ticket at the reception. No MAC Filtering enabled: He is in the party. But if the MAC Filtering is enabled, then he is asked for the NIC to verify the authenticity of the person who holds the ticket. As his NIC number (MAC Address) is not in the list, unfortunately no partying this time. I hope you got the point. This is how exactly MAC Filtering works. But you see the flaw here. If the person who stole the ticket is wise enough to forge the NIC (given that he knows the NIC number of the legitimate ticket holder) then most probably he will be taken into the club. Simple, isnt it? So make sure you keep tickets for parties safe 😛

Is MAC filtering safer?

Not really, it is not the strongest security feature to nag hackers or intruders. BUT something is better than nothing.

When MAC Filtering can be used?

If you know the MAC address of the devices which are used to access your wifi router (legitimate users) then this feature can be used. What should be done is maintain a ledger of MAC Addresses against the devices.

How to break this feature?

Breaking this is simple.

  1. Get the password of the router. Find it, that is also not difficult.
  2. Use a network sniffing tool and find out a MAC address which has the access.
  3. Then forge the MAC address and pretend that you are a legit user.
  4. And connect, enjoy free internet !!

** There is other ways of bypassing the MAC filtering feature, please google if you are interested.

How to set up this feature?

Following is a step by step guide. (Please note the interfaces shown below can be different/ or may not be the exact as below)

Access your route and login as the admin. It is simple as browsing the default IP of the router which is 192.168.8.1

Then enter admin credentials and you are in.

First of all you need to enable MAC filtering.

Enable_MAC_Filtering

Then you need to add MAC addresses to the MAC Filter list.

Allow_list_MAC_Filtering

MAC address is some string like this AA:BB:CC:DD:EE:FF

You need to find it in your device and add it accordingly.

MAC_Filtering_list

SO using MAC Filtering is simple.

Recommendation

This is a small security feature that works well with your home wifi router if you keen on blocking unwanted access. All you have to do is find out MAC address of the devices and add it. I really recommend this if you are living in an apartment, shared houses and etc…

Remember, door locks are not 100% safe. Even though you lock the door when you leave home. And if the intruder is motivated enough, a door lock cannot stop him. But it gives a basic security over others. MAC Filtering is as same as this anology.

Enjoy MAC Filtering………

 

Wifi Security : In a nutshell

Wifi Security is a vast subject and of course a tiny sub set of cyber security which of course a sub set of IT security as a whole.

Well, no system in this world is safe. Therefore it is better to employ some security over your wifi router before someone steals your expensive data bundle. The best part is, smart intruders consume, may be 10% of your quota, even you dont have a chance to notice it.

“Is that the end of the story? Who cares about data, I have enough so it is better someone uses it”…..

I know you are person with a big heart. BUT do you know what the intruder is doing? May be he gets access to deep-web, running a web site that sells drugs or running a brute force bot, manning a DoD attack bot, or simply maintain a fake FB account, who knows? By the law, you are responsible for all this traffic, because you are the owner of the router. Scared enough? Good !!

So before it is too late, use some security features to block the unwanted access. Bear in mind, something is better than nothing. A mantra in security. Fortunately we are not living in Singapore, so anyone can try accessing any wifi network (not using the traffic but there is no law refrain the attempts to access the wifi network).

I composed a list of few security measurements that can be employed in your family Wifi router. Most of them are easy to employ. Just check the list below….

Choose the SSID wisely and dont make it public

SSID – Service Set Identifier. SSID is the name of the network you see. Do not use a SSID which is easy to guess. For an example dont use your home number or your name or your pet’s name. They are easy to guess. I mean the owner of the router. Use some arbitrary SSID which is not easy to crack using social engineering techniques. Then dont make it public. As an additional feature, broadcasting the SSID can also be stopped. In that case you need to enter the SSID manually as it is not visible when wifi is turned on in your device. It facilitates invisibility of the network for those who dont know youe SSID. Ideal for your home network.

Save energy, switch the router off when you leave home

Do not keep your wifi router running 24×7. Switch it off when you dont use it. Even before you sleep. This is a good practice.

Wifi router is not an ornament

Keep the router in a safe place where the public cant reach. Ideally not the living room.

Why? I did remove the sticker which was on the router which had the password and details. So cant I keep it in the living room? so that my neighbors know I have a wifi router.”

This is good. I would do the same if I owned a wifi router in 1980’s or 1990’s. But no more. Because, if they can see your router it reveals the model of the router. It is a good info and it narrows down the effort of the intrusion.

Never keep using the routers default password

Change the password of the router as soon you start using it. Never use the default password even though it seems very strong. It is very easy to crack it if the intruder knows the model of the router you are running.

Use a strong password and change it frequently

Are you a fan of “abc123” password or “1234567890” or ……………………………….??

Well it is time for a change, use a strong password. I mean a password with a higher entropy. And change it frequently. Lets say at least once a month. Higher the frequency, it is much safer.

Use MAC Filtering

This is a standard security feature to prevent intruders (at least theoretically). If you need more info just google.

Use strong encryption 

Fan of WEP (Wired Equivalent Privacy). God bless you. Less than 5 minutes the encryption can be broken. Not sure, ok try using a free tool like aircrack. Use WPA/ WPA-2 (Wi-Fi Protected Access) instead. At least it is better than WEP.

Use a firewall

Using a firewall is a good idea, go for a software firewall if you cant afford a hardware firewall. Some routers are equipped with firewalls. Check it !

Use extra layers/ tools/ hardware

This is the best security measurement, but very expensive. May be not suitable for a home but must have for the wifi network in your office.

Update firmware of the router

Keep the router’s firmware up to date as much as possible, this is very important and not that difficult too.

Be vigilant and keep monitoring

Even though the above measurements are in place, they are useless without proper monitoring. So make it a habit of checking the device history log in your router, at least. It tells you which devices has been connected to the router in past few days. If there is a suspicious device check for it.

Well this is the list I came up with. If you have anything which has not been listed here please use comments.

10 Things Every Man Should Have in their backpack

I recently went through a blog article reading “10 Things Every Woman Should Have in Her Purse” (link included at the bottom), and instantly I started thinking as men, what should we keep with us in our backpacks. I used to carry my backpack almost everywhere as much as possible and I have few things inside which really save my days, few times. For your info I am listing few most important and must have items in your backpack.

  1. Some Notes (Money) – It is good to keep some cash ready in the bag so that in an emergency it can be used. When it is used do not forget to refill.
  2. Some wet tissues – It is good to have some wet tissues to wipe out
  3. A Knife – Swiss knife is ideal, otherwise a small knife with a cover, can be used to cut papers, any fruit, a bag and list grows. However be extra careful when carrying it and entering to high security zones.
  4. Apirin, Paracetamol or Pain Killer – You never know when you need it, for headache it would be the relief.
  5. A pen – This is very important and serve you well, so keep a pen with you in all time.
  6. Emergency contact info card – With proper info it is good to have an emergency contact card, so that others can use it to contact your family members in case you are in such a position.
  7. Hand sanitizer – Handy thing to have a bottle of liquid sanitizer so that you can be “bacteria free”
  8. A Lighter – Disregard whether you smoke or not. If you are smoking it is obvious that you need to carry it. anyway if you are not it is good to have one so that it can be used in any emergency or in a need. Matches are not an option since they get wet and become unusable in few days.
  9. Some business cards – You will meet many people on the way, good to have some cards so that you can expand your network easily rather than making others memorizing your details.
  10. Some chocolates/ snacks – I hate being in hunger specially when travelling, good to have some snack to enjoy when you are hungry. i usually keep some chocolates and a snack. Because chocolate gives you instant strength if needed.

Apart from above I always keep my keys inside in a safe place and bank tokens. Apart from that if possible I usually carry my diary so that I can write down anything important and since my check book is attached to the diary it gives me extra advantage.

More importantly the list has no order, I think everything is much important, and required when you are in a situation.

In womens’ listing it includes lipsticks, sanitation towels, baby wipe, mace spray apart from the above. Ladies, you may read it at http://en.amerikanki.com/things-every-woman-should-have-in-her-purse

Some interesting proposals – Fedora Summer Coding

GSoC 2014, already started students proposal filtering. While going through submitted proposals, I found following are quite interesting and well drafted. For reference purposes I though of including few URLs, in future if anyone wants to refer to some GSoC proposals towards the Fedora project.

Isitfedoraruby by Axilleas – http://fedoraproject.org/wiki/GSOC_2014/Student_Application_Axilleas/Isitfedoraruby

Free Media Project by Dulanja – http://fedoraproject.org/wiki/GSOC_2014/Student_Application_Dulanja/FreeMedia

 

Sinhala version of GSoC 2013 flyer can be downloaded

It is around 24 hours announcing GSoC 2013 program by Google program admins. By the way it is good to see the Sinhala version of the program information flyer is available to download on the wiki and it is one out of 14 there at the moment.

Use following link to access it and it is in PDF format.

http://code.google.com/p/google-summer-of-code/downloads/detail?name=GSoC2013FlyerA4.si.pdf

Feel free to translate it for your language as well, here is the link for instructions.

http://code.google.com/p/google-summer-of-code/wiki/GsocFlyers

screen-print of wiki