Vile Works

Secure a Flat File Using a .php Extension

Here’s the deal: 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?…

scroll down to the conclusion to skip the whole story

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 header("HTTP/1.0 404 Not Found"); 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:

die("<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\"> <html><head> \n<title>404 Not Found</title> \n</head><body> \n<h1>Not Found</h1> \n<p>The requested URL was not found on this server.</p> \n</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<title>404 Not Found</title> \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 ware 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>
    <title>404 Not Found</title>
</head>
<body>
    <h1>Not Found</h1>
    <p>The requested URL was not found on this server.</p>
</body>
</html>

Background story

I’m gonna start working on a simple CMS which I’ll be releasing open source. Now this should be really simple as in:

  • user already has his/her own site (probably a static html site)
  • user uploads a folder to his/her root dir via ftp—and that’s all, without having any database involved
  • pages are editable in certain ways by a script in that folder

And that about covers it (until further development). But before I actually start putting things together I was exploring possibilities and ran into this.

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<title>404 Not Found</title> \n</head><body> \n<h1>Not Found</h1> \n<p>The requested URL was not found on this server.</p> \n</body></html>"); ?>

If you’re interested in the login system I’ve been talking about, you can download it and read a tutorial explaining how it works here: Micro Login System.

Think different?

Can you think of any reason for this not be secure? Do you think I’m reinventing the wheel here?
Mention it in a comment here, or leave me a private note via my contact form if you think I’m missing anything.

7 Comments Comments RSS Trackback URL

  1. Gravatar Icon Jez

    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!

    Reply to this comment
  2. Gravatar Icon LGR

    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.

    Reply to this comment
  3. Gravatar Icon Dean

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

    Reply to this comment
  4. Gravatar Icon Stefan

    @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.

    Reply to this comment
  5. Gravatar Icon Stefan

    @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.

    Reply to this comment
  6. Gravatar Icon Dean

    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).

    Reply to this comment
  7. Gravatar Icon Dean

    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)

    Reply to this comment

Leave a Reply


info Vile Works uses Gravatars to display the avatars. You can get an account and have your avatar displayed on any site that supports it. We use the email address you provide when commenting to identify your avatar.