Sign in to follow this  
CProgrammer

[web] php and users

Recommended Posts

Well Im making a user loogin system. Obviouslz I have to save user data somewhere. I see two options here: 1: I store user data in a database(mysql) 2: I have a folder per user and store it in a file. I prefer version 2 for the login system. Any reason not to go with number 2? -CProgrammer

Share this post


Link to post
Share on other sites
If you have access to a database, I'd recommend that you went that route. If you had user-specific files (avatars, etc) you would probably want to store that under their own directory, but for a login system a database is the way to go.

Share this post


Link to post
Share on other sites
I agree the database may be the normal way to go. But I think 2 isquite easy to overlook and I have most of the code for this from another project.
My main concern is efficieny and SECURITY. Is 1 more secure than 2. Does 2 have problems when the number of users grows.?

/CProgrammer

Share this post


Link to post
Share on other sites
How exactly do you propose to do #2?

Will it be a directory for the username with perhaps a file containing the password, another containing profile data, etc? Such a system would be difficult to alter (mass rename of all the files) - it may also be difficult to perform administration queries on the users. For example, how would you query all users that have xyz property? It can be done, but it means iterating files and directories to get your information - very slow in comparison to a SQL query.

I agree that files are useful for some things. An example is evoWeb, I'm storing a lot of my content as flat text files that's read in at page view time. It allows me to keep generations of the text with little problems and allows me to make backups easily. However, I'm moving it into a SQL version soon because of potential problems that exist in a multi-user environment. For example, imagine that 3 people are trying to read a file whilst it's being edited - you may try and commit your edit part-way through a read, and vice versa. Even worse, what happens when two administrators are trying to edit the file? You need a database mechanism in place to ensure that the status is maintained correctly. I could have a database layer on top of the flat file content layer to manage it, but in your situation this solution for user profiling has little benefit.

Why not try out both versions in a sandbox environment to perhaps get a better understanding of which method would work for you better?

Share this post


Link to post
Share on other sites
Doing it in a MySQL database would be easier to not only use and create but also administer. Also doing it in files would require you to change the file permissions. You might want to check out my database class.

Using that class, you'd come up with something like:


// Connect to the database
$database = new Database("DBUSERNAME", "DBPASSWORD", "DB");

// See if the username and password exist
$database->Query("
SELECT * FROM tblUsers
WHERE cUsername = '$username'
AND cPassword = '$password'
");
if($database->NumRowsInResult() == 0){
// User Doesn't Exist
} else {
// Username and password are correct
}




Also remember that PHP.net is the best resource for anything PHP. I strongly recommend using phpMyAdmin.

Share this post


Link to post
Share on other sites
Quote:
Original post by CProgrammer
Well Im making a user loogin system. Obviouslz I have to save user data somewhere.
I see two options here:
1: I store user data in a database(mysql)
2: I have a folder per user and store it in a file.

I prefer version 2 for the login system. Any reason not to go with number 2?

-CProgrammer


Generally speaking, the database solution will be faster, easier to implement, more robust and much much more secure.

#2 can and will become a problem for several reasons:
- File systems tend to slow down when you have a lot of files/folders. I wouldn't like to see a folder with a subfolder for each of a few thousand users. Even with few users, databases would be noticeably faster.
- It will get really messy if people try to read from it while other try to write to it. Databases are practically made to handle these things. File systems aren't.
- File systems aren't particularly secure in general.
- #2 would be really messy to manage as well, especially as the number of users grows, and if you want to create some kind of statistics on your users, or search for a certain group of users.

There's really no reason to use #2 for this, unless of course you don't have access to a database. #2 is reinventing the wheel, and it won't be a particularly efficient wheel at that... ;)

Share this post


Link to post
Share on other sites
Quote:
Original post by Rob Loach
Doing it in a MySQL database would be easier to not only use and create but also administer. Also doing it in files would require you to change the file permissions. You might want to check out my database class.

Using that class, you'd come up with something like:

*** Source Snippet Removed ***

Also remember that PHP.net is the best resource for anything PHP. I strongly recommend using phpMyAdmin.


No, no and no. You would NEVER use that SQL query as it is. It's a perfect target for a SQL injection attack.

I would go the SQL route however. You can still have the good ol' home dir for the user, but for storing passwords and profile information, the DB is just plain cleaner, and more secure.

Share this post


Link to post
Share on other sites
SQL Injection == World of pain.

Click and this might be useful to read and understand how it works to make sure you're not falling foul of the problem.

Basically, the user can escape the SQL string and insert their own SQL statement to falsely validate their own credentials - nasty stuff.

A way round this would be to alter the login process completely from the method Rob suggested and retrieve the record for the user and validate the password script-side and NOT in the SQL itself. You also want to check for SQL string terminators in things such as the username to ensure no malicious injection goes on there. Basically, don't trust anything the user sends to be valid - always verify it in script before it goes anywhere near your database.

Disclaimer: You are NOT encouraged to go around trying this sort of stuff out. This information is provided to help secure your own sites from such attacks

[Edited by - evolutional on November 12, 2004 2:54:17 PM]

Share this post


Link to post
Share on other sites
Quote:
Original post by Washu
No, no and no. You would NEVER use that SQL query as it is. It's a perfect target for a SQL injection attack.

I would go the SQL route however. You can still have the good ol' home dir for the user, but for storing passwords and profile information, the DB is just plain cleaner, and more secure.

Thanks, Washu, for giving a valid solution to this problem. I'm assuming removing all "untrustable" characters from the string given would eliminate all possibilities of exploiting....

So something like this:

function FixUserInput($input){
$sChars = array(
"=", "-", "+", "?", "'",
'"', "#", "(", ")", ",",
"*", "/", "[", "]"
);
return str_replace($sChars, "", $input);
}

You'd of course add any other characters you don't find trustable.

Share this post


Link to post
Share on other sites
Why not just use the mysql_escape_string and mysql_unescape_string functions? I believe it was designed to provide an easy way to prevent SQL Injection without sacrificing characters or having to write your own functions. Maybe I'm missing something here...

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Do it script side and use PHP's string manipulation functions and some beefy regular expressions.

Share this post


Link to post
Share on other sites
Quote:
Original post by Apocryphiliac
Why not just use the mysql_escape_string and mysql_unescape_string functions? I believe it was designed to provide an easy way to prevent SQL Injection without sacrificing characters or having to write your own functions. Maybe I'm missing something here...
Thanks, Apocryphiliac. For anyone who needs it.

Share this post


Link to post
Share on other sites
fundamentally flawed.

Preventing sql injection attacks by filtering 'untrusted characters' is a flawed approach. You would have to filter for all types of characters which mysql recognizes.

The best way to do this is through the use of prepared statements.

This forces the SQL query to be 'compiled' on the server without parameters. You then submit the parameters separately and this permits the server to operate on the parameters without fear of the parameters being interpreted as server commands.

Although it is not a good database, even mysql supports this.

Share this post


Link to post
Share on other sites
Quote:
Original post by ChaoticCanuck
Although it is not a good database, even mysql supports this.


Not fully (eg: as well as SQL Server) and only in version 5.0, which unfortunately puts them well beyond the reach of most people who purchase hosting. I've noticed the trend that most MySQL service providers will stay at least one (often more) stable version behind the current in order to ensure that it truly is stable. Upgrading an entire server farm to the new version and potentially affecting all of your customers is a dangerous thing.

But yes, I do agree - Stored Procedures should be the way to do this sort of thing.

Share this post


Link to post
Share on other sites
Quote:


14.7 SQL Syntax for Prepared Statements

Support for server-side prepared statements was added in MySQL 4.1. This support takes advantage of the efficient client/server binary protocol, provided that you use an appropriate client programming interface. Candidate interfaces include the MySQL C API client library (for C programs) or MySQL Connector/J (for Java programs). For example, the C API provides a set of function calls that make up its prepared statement API. See section 22.2.4 C API Prepared Statements. Other language interfaces can provide support for prepared statements that use the binary protocol by linking in the C client library. (The mysqli extension in PHP 5.0 does this, for example.)


Then again, anyone using mysql for 'serious' web development needs to re-evaluate their understanding of security and web development. The "ease of use" that mysql offers does not justify the snail like development of the project, and the lack of features, especially when a well documented, free package such as PostGres is available.

Share this post


Link to post
Share on other sites
Quote:
Original post by ChaoticCanuck
Then again, anyone using mysql for 'serious' web development needs to re-evaluate their understanding of security and web development.


Care to elaborate on that? I have never ever had any problem with MySQL so far and I use it quite a lot.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this