php: grabbing user info from database, is this code secure? - php

So i was wondering if i this is OK or if theres another better and secure solution to grab info from the database.
if (isset($_SESSION['user_id'])) {
$string = mysql_query("SELECT * FROM users WHERE id = '$_SESSION[user_id]'");
$v = mysql_fetch_array($string);
}
Because I was thinking maybe its possible to hack the "session" and change user_id to another and woops they get access to any user...
Thank you

This depends on how the user_id gets into the Session in the first place.
As a rule of thumb, you should never place any unsanitized values into a query.
You should at least use mysql_real_escape_string.
Even better would be not to use the old and outdated mysql extension but mysqli's prepared statements.

I suggest escaping the user_id, just to be sure. You should also test if any rows were found (optional, depends on usage).

Every data coming from the user should be filtered, and never used directly in a query; this would avoid SQL injection.
Suppose the content of $_SESSION['user_id'] is ' OR id = '12' //; the query would become SELECT * FROM users WHERE id = '' OR id = '12' //'. Supposing that the user account with ID 12 has particular permissions that allow the user to delete content from the site, you can imagine the consequences.

Related

Does md5 stop SQL Injection

Ok,
So, i'm a little unsure on this.
I have a url parameter username.
and I have this statement
SELECT * FROM users WHERE user_hash = md5($_GET['username'])
Is this secure?
Upon account creation an md5 hashed version of the username and the password are stored.
I'm confused as this seems so simple, if md5 stops sql injection why isn't username and password always saved in hash form?
Yes, this will avoid SQL injection, because md5() always returns a string of hex code.
But it isn't a general solution to SQL-injection. You would have to encode almost all the data in your tables in MD5 format. For instance,
$sql = "UPDATE users SET fullname = '" . md5($_GET['fullname']) . "'
WHERE id = '" . md5($_GET['id']) . "'";
But MD5 is a one-way hash, so there would be no way of displaying the full name that was stored this way.
Short answer is no, MD5 does not prevent SQL injection. Proper coding is the best way to handle this.
Reason being in this case is that your query string parameter is allowing direct access to the sql. E.g. what if the user sends you:
?username=%27a%27);DROP%20TABLE%20users;%20--
That fakes the MD5 function out and drops the users table. Of course they have to know somethings about your database in order to do this. The correct way to handle it would be to MD5 the value before it went into the SQL. In PHP it would be something like this:
$username = $GET['username'];
$hashed_username = md5($username);
$sql = "SELECT * FROM users WHERE user_hash = '$hashed_username'"
Or the best solution would be to use bound variables in queries where you let the SQL libraries handle the translation. If you are using PHP, look into PDO bindParam, http://php.net/manual/en/pdostatement.bindparam.php
BTW, your SQL won't work because you would need to quote (') the get variable in the SQL.
I'm confused as this seems so simple, if md5 stops sql injection why isn't username and password always saved in hash form?
The reason is because simple operations like searching for a user with a particular name would be impossible.
SELECT * FROM users where user LIKE '%cat%'
Would find all users with the word cat within it.
Also simple administration would be impossible, you can't even view a roster of all users.

MySQL - insertion multiple insertions, page stops working

I have made a makegroup.php site which is supposed to create a group, and put the person in the connection table between UserID and GroupID.
..but I am not sure how to go on. The logged in user is saved in session variable $usid, but how what about GroupID? How do I fetch that right after on another page? Need I make this in steps? Including quick DB scheme.
Thanks in advance.
I guess GrouID is autonumeric?
So you leave db create the id for you.
Also loos like you are trying to concat the $groupname value
$sql = "INSERT INTO group (Groupname) VALUES ('".$groupname."') ";
But you dont want do that because that method is vulnerable to SQL Injection attack
Use parametrized values instead
How can I prevent SQL injection in PHP?

Hackable sql query

I was running a site I purchased that I thought was fairly unhackable. However, after having an attack, I found it was not. He informed me of the vulnerability, however my question is what user input could have been done to get all the users usernames like he did? Here is the code...
$un=$_GET['username'];
$q=$db->query("SELECT * FROM users WHERE login_name='$un' OR username='$un'");
I realize that this is highley hackable. Therefore, I changed the site over to prepared statements to prevent this from happening again. I just want to know what he could have entered to get all the users usernames.
Someone posted the script on github, you can find it here:
https://github.com/sat312/Mafia-Game-Script/blob/master/checkun.php
' OR 1=1;
In the URL:
/yourScript.php?username=%27%20OR%201%3D1%3B
The idea is that since data is mixed with the command, you can just finish the command with data.
You get $un from the user, so I can type anything I want and it'll get substituted into your query. It's called a SQL Injection attack.
Lets say $un = ' OR 1 = 1;-- then your query becomes:
SELECT * FROM users WHERE login_name='' OR 1 = 1;--' OR username='' OR 1 = 1;--'
What will happen? this gets executed:
SELECT * FROM users WHERE login_name='' OR 1 = 1;
This will return every row in the table.
He may have used the GROUP_CONCAT statement in MySql which basically groups a column in multiple rows into a single row (see Can I concatenate multiple MySQL rows into one field? for more information). He may have terminated the original SQL statement or UNIONED it with his own and added a LIMIT and ORDER BY to ensure his result got returned and commented out the remained of the original statement.
This is one possibility, but there are probably a few others.

How people can use this security hole?

I have browser game. There is message send form.
I didn't make real escape string function to the "message_content" variable.
There is any option, that the user could make after the insert of the message, any update ?
I mean that the user could write a sql code in the message_content that can UPDATE values in the sql? Like update users set gold = '9999' where username = 'my_username'
THANKS ALOT....
And that it only a question. Don't worry i already made mysql_real_escape_string...
Please learn about using parametrized queries, preferably with the PDO module, to protect your web app. http://bobby-tables.com/php has examples to get you started.
The mysql_query function doesn't allow the execution of multiple statements at once. So the often mentioned example of Robert'; DROP TABLE Students; -- won’t work.
This also means that the exploitation is restricted to the statement type. So if the injection point is in an INSERT statement, the vulnerability can only be exploited to insert arbitrary values into that specific table.
However, one can still inject arbitrary data from the database into that table. And if the attacker addresses the message to himself, he will be able to read arbitrary data from the database and may also be able to read and write arbitrary files on the server.
If you don't escape the user input the following can happen:
Imagine this query:
SELECT * FROM user WHERE login='$login'
where $loginis the user's input.
Now the user insers the following content in the variable: '; DROP TABLE user; --
The following query will be executed:
SELECT * FROM user WHERE login=''; DROP TABLE user; --'
It's a very generic example, but I hope you get the idea

PHP with SQL Injection

Ok, starting fresh >
For our first assignment in a System Security class, we have to hack into the professors "cheaply organized" sql database. I know the only user is "admin" and picking a random password, the select statement generated in the php is:
select user_id from user where user_username = 'admin' AND user_password = md5('noob')
Now, I go for the basic starting point of trying to hack the crappy login with "admin'--"
select user_id from user where user_username = 'admin'--' AND user_password = md5('noob')
but the actual value being pushed to the database is
select user_id from user where user_username = 'admin\'--' AND user_password = md5('noob')
which doesn't help. The server uses POST to get the values from the form. I've already bypassed any value processing on my side of the send by disabling javascript.
There does not appear to be anything in the php that modifies the input in any way.
Assuming the select statement is part of a login form, then most likely it's generated something like this:
$user = $_POST['username'];
$pwd = $_POST['password'];
$query = "SELECT .... WHERE user_username='$user' AND user_password=md5('$pwd')";
which means, you could hack in by entering:
noob') or ('a'='a
for the password, giving you
SELECT .... AND user_password=md5('noob') or ('a'='a')
^^^^^^^^^^^^^^^^^-- your contribution
The actual password might not match, but 'a' will always equal itself, so the where clause will succeed and match a record based purely on the username and return the admin user's user_id.
As others had mentioned the escaping that you see is not the OS, but some form of encoding done in PHP (likely magic quotes, but could be a straight call to addslashes()).
Basically what you need to do is send in a form of quote that will not be escaped. You should research why one would use mysql_escape_string() rather than addslashes() and/or check this out: http://forums.hackthissite.org/viewtopic.php?f=37&t=4295&p=30747
Try ' OR 1; -- as user name. Imagine what the SQL query from such a user name looks like.
This has nothing to do with the operating system. The operating system simply runs the PHP package. PHP is what does sanitization, etc.
Have you tried submitting the following string for user_username?:
admin' OR 1=1-- #assuming mysql
Would yield a query:
select user_id from user where user_username = 'admin' OR 1=1 --' AND user_password = md5('noob')
In mysql (assuming the database type), -- is a comment, so everything after 1=1 is ignored. As a result, you've successfully gained access.
If php magic quotes are on, however, this will be slightly more difficult. You will need to submit characters outside of utf-8 or attempt overflows or submitting null bytes.
You could also try a bit of googling after entering a string that will error out the admin and use part of message that comes back as the key words.
You could also use the http://gray.cs.uni.edu/moodle/mod/forum/discuss.php?d=106 fourm to ask questions so the whole class can benifit!
if you can figure out how to upload files that would be great! I want to get c99.php up to really do some damage!
you could also try some "hash" verse "dash dash"

Categories