login (security through obscurity) – weird PHP script

This was the idea with which I have won the regional web apps contest… well actually I did a CMS but the security part of it was the most appreciated. Maybe because it was weird, you’ll see…

Classical Login scripts
What exactly do classical login scripts do… they get the password from the database by querying it with the username (SQL Injection possibility) and after that they compare the retrieved password with the one submitted by the user. If they match either the website sets a cookie, or a variable in the current session…

Weird/Reverse Login script
The main thing that I wanted to achieve was to get rid of any SQL Injection vulnerability. How did I do this? I didn’t use the classical query username in database and get the respective password; instead I searched all the usernames that had the password sent by the current user and then scanned through the list for the username, if not found no such username exists…

As far as I see through this method there is no SQL Injection possibility, no need of mysql_real_escape_string() or to worry about hex encoded strings, etc.

Weird/Obscure Cookie
The login process isn’t complete, not until we do not set a normal cookie with “strange” information in it, or should we say obscure information for everybody except the webmaster =).

As for the secret key…. it has to be secret because if it is not, a person on the same network as yours could forge a cookie to gain access.

Cookie verifier
This is used to check the authenticity of the cookie, I bet you already have an idea on how it looks:

It’s not a great thing, could have used sessions or the classical login method with many filters (addslashes(), mysql_real_escape_string())… but I didn’t, it was perfect for me because I am a fan of the principle: “security through obscurity” and also got more points because they wanted creativity… in everything design/development. And because I’m not a designer I had to use my creativity on development. Some of you maybe will like it, others will see it as plain stupidity, and the rest of you won’t even care… but still, it helped me won the contest…

Posted in: Secure Coding, Security Software


Latest Posts:

GKE Auditor - Detect Google Kubernetes Engine Misconfigurations GKE Auditor – Detect Google Kubernetes Engine Misconfigurations
GKE Auditor is a Java-based tool to detect Google Kubernetes Engine misconfigurations, it aims to help security & dev teams streamline the configuration process
zANTI - Android Wireless Hacking Tool Free Download zANTI – Android Wireless Hacking Tool Free Download
zANTI is an Android Wireless Hacking Tool that functions as a mobile penetration testing toolkit that lets you assess the risk level of a network using mobile.
HELK - Open Source Threat Hunting Platform HELK – Open Source Threat Hunting Platform
The Hunting ELK or simply the HELK is an Open-Source Threat Hunting Platform with advanced analytics capabilities such as SQL declarative language, graphing etc
trape - OSINT Analysis Tool For People Tracking Trape – OSINT Analysis Tool For People Tracking
Trape is an OSINT analysis tool, which allows people to track and execute intelligent social engineering attacks in real-time.
Fuzzilli - JavaScript Engine Fuzzing Library Fuzzilli – JavaScript Engine Fuzzing Library
Fuzzilii is a JavaScript engine fuzzing library, it's a coverage-guided fuzzer for dynamic language interpreters based on a custom intermediate language.
OWASP APICheck - HTTP API DevSecOps Toolset OWASP APICheck – HTTP API DevSecOps Toolset
APICheck is an HTTP API DevSecOps toolset, it integrates existing tools, creates execution chains easily and is designed for integration with 3rd parties.

22 Responses to login (security through obscurity) – weird PHP script

  1. madmax April 29, 2007 at 9:57 am #

    Wow mate this is really nice!!

    I’ve always thought that the classical method was the only method and for preventing SQL Injection possibility we would have to use filters like mysql_real_escape_string().

    This is a really nice and new and most importantly SECURE method

    Hats off to U!!

  2. depi April 29, 2007 at 10:31 am #

    Nice method, congrats!

  3. Kris April 29, 2007 at 10:36 am #

    But seriously, that is a pretty neat idea you had there, well done with winning the contest!
    I try to make hard-to-crack login scripts as well, but this has to be the best way i’ve seen.

    Reminds me that i need to get around to finishing that boring ASP project i had for college…

  4. Daniel April 29, 2007 at 1:06 pm #

    Erm.. what if you had lots of users say 10,000 (not really many but enough to quantify my point)? You would have to retrieve 10,000 records where a WHERE username = ‘user’ would only retrieve one, it’s a waste of resources.

    SQL injection is something solved very simply! All you have to do is apply mysql_real_escape_string to the username and there is no way a user can use SQL injection. I would recommend reading up on SQL injection before spreading FUD like this.

    If you was using a database abstraction class, it could do this for you so you would never have to worry about SQL injection again.

  5. Rob April 29, 2007 at 1:39 pm #

    ‘ … it was perfect for me because I am a fan of the principle: “security through obscurity” ‘

    Please do not get a job in security.

  6. Simson April 30, 2007 at 8:45 am #

    “security through obscurity” is not a good thing.
    You need to study more…

  7. Gareth Heyes April 30, 2007 at 8:54 am #

    Can anyone see the major problem here? If you check the entire database for a password then you can scan all passwords to see if it works. Increasing brute force attacks success rate.

    I hope this was just an experiement and not intended for real world usage, anyone reading this should understand that it would create a security hole on a web site.

  8. Sandeep Nain May 1, 2007 at 12:22 am #


    Although, the trick you used to is something different and unique but is not worth to be used in big applications having thousands of users. Not just security, But even if you look at it from query performance perspective, Its not efficient. Nobody wanna make password field indexed.


  9. Clif May 1, 2007 at 2:08 pm #

    As some of the other posters said, flipping through all user instances where passwords are equal is a bad idea. You shouldn’t see any issues on a small site, but this won’t scale well at all. Just consider the massive number of users who use passwords like “password”, “abc123”, etc…

    If you really want ‘obscurity’ (read hashing), hash both the user name AND the password. Either combine them with or have them in separate fields. If you choose separate fields, you’ll never get more than one result (IF user names are unique!). You’ll have to add some extra logic if you combine them though. md5(“foo” & “bar”) == md5(“fo” & “obar”)

  10. backbone May 1, 2007 at 4:43 pm #

    As you all said it it may be a resource consuming script on big websites where we have many users, but as I am not going to implement it in distributed web apps you should not worry… If anyone who has read this is going to implement this after seeing your comments (which I thank) I don’t think they are going to use them on large community websites…

    mysql_real_escape_string can be bypassed with hexadecimal encoding… so this is more secure… I would recommend reading up on bypassing before spreading FUD like this.

    I used password strength enforcing in the CMS. So when you registered, you had to use a password which contains at least two lowercase letters, two uppercase letters, and two number… also the minimum length would be of 6 letters…

  11. Mitchell May 1, 2007 at 6:24 pm #

    As predicted, I’m one of the peeps out there who aren’t a fan of this script, thought you get an A for creativity.

    That aside, this won’t work correctly in the case of two or more people having the same password. In the first iteration of the while loop, it checks to see if the username is the one that was passed in. If not it relocates (theoretically) back to the login screen with an error message. So if 3 people had the same password, and the first result was not the person logging in, then they will never be able to login.

    while($fetch=mysql_fetch_array($query)) {
    if($fetch[0]!=$uname) {
    header(“Location: somewhere”);
    else {
    …set a weird cookie…

  12. backbone May 1, 2007 at 7:35 pm #

    Thanks Mitchell, haven’t noticed it… anyway I re adapted the script, so now it should work correctly… I’m happy they didn’t realize this at the contest, because neither did I…

  13. Mitchell May 1, 2007 at 8:00 pm #

    This doesnt do anything, and there is a single equal sign as opposed to a double:

    if($ok=1) {
    //do nothing
    else {
    //nothing because $ok is allready 0

  14. backbone May 3, 2007 at 1:06 pm #

    that’s how my logic works…. why do you think it’s a weird script? ;) …anyway I’ve put your double equals, don’t blame me if I use to write single equals…

  15. UndiFineD May 3, 2007 at 2:01 pm #

    He man, that was a great idea.
    Unfortunatly there was a little flaw when I wrote it like this 2 years ago.

    Some employees had the same password.
    That was a sad day for me :(
    I solved it by comparing an array of userids in a loop.
    until the userid was found or the array was empty.

    set your $ok=0; in the loop, this helps against

    stay creative :)

  16. backbone May 3, 2007 at 8:14 pm #

    10x UndiFineD added that to the loop… as I knew just really old,old,old while(1) { write(‘old’); } versions of PHP where vulnerable to this…

  17. UndiFineD May 3, 2007 at 10:25 pm #

    I’ve been out of the lamp loop for a while…

    moved on to data centre management.

    oh and my login script was for an intranet environment,
    just to be clear on the query mess.
    Still, I think this is an ok solution, for some situations.
    And creativety should be sponsored and welcomed with open arms.
    There aren’t enough developers and designers and some them lack proper guidans thru proper management and training.

  18. bl May 7, 2007 at 5:22 pm #

    I agree with those that think this is a bit overkill and think that there are better solutions.

    1. Loop through the results like the person said above.

    2. Use mysql_real_escape_string() Like someone else said

    3. or, don’t allow anything except for word chars in their username, and use preg_replace(‘/[^\w]/’, ”, $usr);

    That will strip any non-word chars out thus sanitizing it on the way in, which is a technique used time and time again.

    I admit though, it is pretty clever.

  19. Sank September 9, 2007 at 3:35 am #

    I don’t understand why you go through the trouble of looping instead of just letting the database do it for you?

    $build = "SELECT * FROM usr WHERE uname='".$uname."' AND passwd='" .md5($passwd). "';

    If zero rows returned, done. Else 1 row returned, done.

  20. Sandeep nain September 9, 2007 at 7:15 am #

    Hi sank

    Yes you are right he could have used the method you suggested (and most of the developers use it the same way) but it opens up the chances of sql injection..

    where as the script written by backbone reduces that risk but on the other hand this script lacks performace… As this script gonna give a shocking performance on a table with 1000s of users….

    irony is …. he got a prize for this script… but still its a good try from his side

  21. Sank September 9, 2007 at 8:15 pm #

    As long as you remove quotes and slashes and whatnot, you should be able to prevent the injection.

  22. Sandeep nain September 10, 2007 at 1:37 am #

    Yes you are right and thats what Backbone has tried to explain above.

    he clearly mentions that in the script he has given you need not to do that…

    Backbone said:
    As far as I see through this method there is no SQL Injection possibility, no need of mysql_real_escape_string() or to worry about hex encoded strings, etc

    and he is trying to implement security through obscurity…