Secure a flat file using a .php extension

I need to store some sensitive data (user names and passwords) in a flat file. I don’t want to make any use of databases because this would defeat the whole purpose of the project. Of course, the passwords will be md5 encrypted in the file, but this wouldn’t be enough.

This neat little login system, Micro Login System, seems to have the basic stuff for me to start with but, as said it stores the user info in a text file.

The contents of userpwd.txt would have been:

admin:3089af3a625carf15ed2a1a93684413ffa
user1:75580656a394292460ebb4b036ebeaf1
user2:c67ac4665947cd23ff7d1d180b8e41d5

That’s user : md5( password ).

I was concerned about this because anyone who knew about the system could have entered address/userpwd.txt in the address box and gotten that info.

My solution

Php files are pretty secure right? They’re processed on the server before the client gets the output. How about giving the file a php extension instead of txt?

Of course this wouldn’t be enough, because the output would be exactly the same as the file’s contents. But now that it’s a php, we can write php code in it. What if the userpwd.php looked like this:

<?php die(); ?>
admin:3089af3a625carf15ed2a1a93684413f
user1:75580656a394292460ebb4b036ebeaf1
user2:c67ac4665947cd23ff7d1d180b8e41d5

The login system can be made to ignore the first line when doing its thing, because it runs server side and can read the contents of userpwd.php as it is on the server (like it was reading the txt version of the file), so there’s no problem here.

But if a client tries to open userpwd.php in his browser, the die(); function will be executed when the server processes the php code in the file and the script is terminated, thus outputing a blank page.

Optional stuff

The header(“HTTP/1.0 404 Not Found”), is an attempt to mislead anyone trying to type in the file name by sending the browser a 404 Page Not Found status. I even went as far as adding an error message as a parameter for the die function that looks like the default html for a 404 error in most browsers:

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> <html><head> 
</head><body>
<h1>Not Found</h1>
<p>The requested URL was not found on this server.</p>
</body></html>

So our userpwd.php would look like this:

<?php header("HTTP/1.0 404 Not Found"); die("<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> <html><head> n n</head><body> n<h1>Not Found</h1> n<p>The requested URL was not found on this server.</p> n</body></html>"); ?>
admin:3089af3a625carf15ed2a1a93684413f
user1:75580656a394292460ebb4b036ebeaf1
user2:c67ac4665947cd23ff7d1d180b8e41d5

And now, if anyone were to open the file in their browser, they’ll get a page with this source code:

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> <html><head> 
</head><body>
<h1>Not Found</h1>
<p>The requested URL was not found on this server.</p>
</body></html>

Conclusions

The most secure .txt file is a .php file

So let’s take a look at it again…

If you don’t need/don’t want to use mySQL or any other database but have some sensitive data to store in a flat file:

  • give it a .php extension
  • it should have this text on the first line:
<?php die();  ?>

Optional: Or to fake it into looking like a 404 Not Found page, it should have this first line (instead of the above):

<?php header("HTTP/1.0 404 Not Found"); die("<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> <html><head> n n</head><body> n<h1>Not Found</h1> n<p>The requested URL was not found on this server.</p> n</body></html>"); ?>

Think different?

Can you think of any reason for this not be secure?

Posted in blog Tagged with: , ,
12 comments on “Secure a flat file using a .php extension
  1. Jez says:

    Hey, im not sure if I have mis-understood your problem but if you want to store data purely for use within a PHP script for user validation why not just store all of the information in a associative array in a separate PHP file? i.e.

    $users = array(
    'admin' => 'c080af3a615carf15ed2a1a91684413g',
    'user1' => '75580656a394292460ebb4b036ebeaf1'
    );
    

    As those variables are now stored within the PHP file to access them its as simple as including the user file within your main PHP file to access the information. e.g.

    include('userinfo.php');
    
    if ($users[$_POST['username']] == md5($_POST['password'])){
    //user and password ok
    }else{
    //user doesnt exist or password is wrong
    }
    

    This also means there is no way to access this information except for altering the file, however if anyone tries to browse to it, nothing will be revealed. Sorry for the long post, hope that helps and I haven’t completely misread the situation!

  2. LGR says:

    Interesting idea. Another thought is to store the data file, text or php of the web root so it is not accessible from the browser at all. The scripts would still be able to include it and process it. If you have to store it in the web accessible folders, you could probably place it in some obscure folder name and use htaccess to prevent any direct access to it. Just some thoughts.

  3. Dean says:

    Just placing the file outside of your web root folder will secure it plenty. No need for all the extra stuff!

  4. Stefan says:

    @Jez: The problem is that these information should have to be stored in such a way that would make them easily comprehensible (readable, deletable, updatable) by other scripts. Like a CSV (comma separated values) or in this case, colon separated values.
    It should allow to easily simulate the main operations you could do on the data in a database for example… at a very simplified level, of course.

    This is because someone should be able to manage the users, users should be able to manage their own accounts and so on.

  5. Stefan says:

    @dean: I thought about that too. But it would complicate things a little for the general public. Nonetheless, I agree, it’s a safe classic method.

    @LGR: Same thing, about the root folder.
    And as for the obscure folder… I’m planning to release the final product open source. So anyone who would know that a site uses this could study the scripts and file structure and exploit it.
    And speaking of which, one more step regarding security, is to encourage users to change the name of their data file.

  6. Dean says:

    You could just use htaccess to block access the file in question. The general public would not have to deal with the technical issues as you could ship the product with the htacess file in place already (have the flatfile inside a seperate folder to avoid conflicts with already existing htaccess files (read: so you dont overwrite them).

  7. Dean says:

    Another point. If, for some reason the server is not configured correctly to process php files server side then it is entirely possible that the raw php source file could be sent to the user (this happened to facebook a while back)

  8. Sorin says:

    why don’t you try SQLite.. it’s not server side dependable.. and you can use a mySQL programing interface :D
    anyway.. thanks for the tip with the 404 header.. very nice ideea

  9. Stefan says:

    @Sorin: As I was saying, using a database would defeat the whole purpose of the project I was working on (and is almost complete, just one more stinkin’ bug to solve).
    The project is something like cushycms.com, only not self hosted and more customizable, and the thing should be stupid simple to set up—just setting the password and an FTP upload.

  10. webteh says:

    .txt file and proper rewrite rules whan accesing .txt file

  11. PHPNewbie says:

    Hi,

    I’m just a PHP Newbie, but could you just chmod
    the datafile access to read/write for owner only or
    something like that, which in this case would be the
    PHP script that created the data file and is using
    it for logins?

    Aren’t there are some host that don’t let you have
    access to .htaccess and/or php.ini! So changing those
    files wouldn’t help.

    I like your idea about using a php file as a data file with
    the header/die. You can read the file one line at a time
    without having to load the whole data file into memory.

    How is your project going?

    Newbie.

  12. Stefan says:

    @PHPNewbie: Indeed, you can use .htaccess to restrict the access to that file.

    Think of this as just another way of doing it, in case maybe httaccess doesn’t suit you. I guess I was also thinking httaccess files can get a bit tricky for some users seeing how most web hosts hide them and FTP clients don’t show hidden files (unless you change that in the settings), or how you can’t create a new .htaccess file under Windows as you would any other normal file with a normal extension.