Reputation: 75
If I choose lots of files tactics,
then I become to have directory
traversal security problem?
I need to write login system,
and lots of file tactics means
make lots of id files and use scandir.
so the directory would have
aaa.txt (contents is aaa_pass)
bbb.txt (contents is bbb_pass)
ccc.txt (contents is ccc_pass)
and when someone enter his id,
the system scandir the directory,
then find the id files.
but hey, what if he enters as
"../../important.txt" ?
then he could access to the ../../important.txt ?
Upvotes: 2
Views: 630
Reputation: 6552
If you have no other choice than to use this file-password system (assuming you have to for one reason or another), in addition to creating some kind of obfuscated file names, you may also want create files with the same extension as your server-side language just in case - for example, if you are using PHP, your file name would be john.php (or obfuscated 'john'), and contents might be something like this:
<?php
exit; // or maybe even a header redirect --
/*password goes here*/
?>
Of course your file-read routine will need to parse our the phrase inside the comment block.
This way, if someone DOES somehow arrive at that file, it will never render.
Upvotes: 1
Reputation: 57805
You could perform some validation of the username before you use it as part of a path - for example to only allow letters and numbers you could do something like this using a regular expression:
if (!preg_match('/^[a-zA-Z0-9]+$/', $username)) {
//username is not valid
} else {
//username is ok to use
}
Another way you could do it is to hash the username before you read or write it, for example:
$hash = sha1($username);
This way, the user can have anything as their username and there will be no danger of them manipulating the behaviour of your file lookup. A username of "../../important.txt"
would give you a hash of "48fc9e70df592ccde3a0dc969ba159415c62658d"
, which is safe despite the source string being nasty.
Upvotes: 1
Reputation: 36
At first glance, it seems like you are going down a somewhat strange path for writing a login system. I'm not sure plain text files in a directory on the filesystem is a wise path to take if for no other other reason than that it's abnormal and you'rer likely to overlook many of the subtleties that are already thought through in more common authentication systems. If you wanted to store the passwords hashed and salted, for instance, you'd need to think through how to implement that in your scheme and you could make a mistake that would lead to a security problem. Using a good PEAR library or even the Zend_Auth component from Zend Framework, though, would give you a clear and well-documented starting point.
Anyway, assuming you have your reasons for the arrangement you describe in your question, the basename() function is likely what you want in this case. It will strip everything but the filename itself so that they can't do a directory traversal attack like you describe in your question.
So if the input from the user is:
../../important
You can run:
$cleanUsername = basename($input);
$filename = '/path/to/password/files/' . $cleanUsername . '.txt';
if (file_exists($filename)) {
[...]
}
Make sense?
Upvotes: 2