mysql escape getsqlvaluestring AccID - php

In various mysql queries, the end part of the query string is:
" WHERE UserID = " . $AccID
where
$AccID = $_SESSION['UID'];
and UserID is the respecting bigint column in the specific table of the db.
So my question is : do I need to escape the $AccID like this GetSQLValueString($AccID, "text") just to be on the safe side, or there is no need to, since it's not taken from a user input ?
p.s. $_SESSION['UID'] is set during the login procedure, after a successful authentication

Yes, you should escape it. You should not database-escape it when you put it into $_SESSION (you might want to use it for other purposes), but before inserting into the query.
Your best bet would be though to use parameterized SQL instead of always escaping and building your queries through string concatenation. Get familiar with PDO. For a better world.

Related

SQL Injection on md5() [duplicate]

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.

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 Escaping Needed After Inserting Data

Do I need to use mysqli_real_escape_string when reusing data from a database for a query. The data was previously escaped so it can be safely inserted into the database. I am aware that when inserting data into a database, backslashes are removed.
Thanks.
Yes, you have to re-escape data that came from a DB when you're re-using it in another query. Consider escaping to be the equivalent of gift wrapping on a present. You "wrap" some data for the database in one query. It'll UNWRAP the data and put it in the data store. When you retrieve that data again later, the wrapping's gone and the data's "dangerous" again.
e.g. consider something like this:
$name = "Miles O'Brien";
$safe = mysql_real_escape_string($name); // name becomes Miles O\'Brien
$sql = "INSERT INTO people (names) VALUES '$safe'";
$result = mysql_query($sql) or die(mysql_error());
Now that name's in the database, but the escaping you performed is NOT PRESENT anymore - it was removed by the database as it processed the query, so if you do something like this:
$sql = "SELECT name FROM people"
$result = mysql_query($sql) or die(mysql_error());
while($row = mysql_fetch_asssoc($result)) {
$name = $row['name']; // get Miles O'Brien from the DB again
here you'll literally have retrieved Miles O'Brien with no escaping at all.
$other_sql = "UPDATE ... WHERE name=$name"; <---INJECTION HERE
}
Escaping is not something you do only with "outside" data... ANY data you insert into a query string is "outside" data, even if you just got that data from the database just a few lines of code ago.
TL;DR: You can easily inject yourself.
Yes, you need it. The escapes are only used to make the query syntactically valid, they're not part of the data that's stored in the table. Any time you're interpolating strings into a query, you need to escape it.
As an example, suppose you have a table of full names, and there's someone with the last name O'Reilly. You perform a query to get this name into $lname, and then you want to use that variable in another query, e.g.
$query = "SELECT username WHERE last_name = '$lname'";
If you don't escape the string, the resulting query will be:
SELECT username WHERE last_name = 'O'Reilly'
As you can see, the quotes are not properly balanced. You need to escape it so that it will be:
SELECT username WHERE last_name = 'O\'Reilly'
However, if you use prepared queries with placeholders for these parameters, you don't need to worry about this much at all (in fact, it would be wrong to escape a variable that's bound to a placeholder, as you will then store the backslashes). This is generally preferred.
Also, consider NOT extracting and re-storing the data at all, but moving data around using SQL itself:
INSERT INTO Table1 (last_name)
SELECT last_name
FROM Table2
WHERE ...
This is also likely to be more efficient, since the data doesn't have to move between the database and the application.
That's not what escaping means.
Escaping text means inserting escape characters so that it can be inserted into a SQL string and be interpreted as the original text.
It has no effect on the actual value, unless you use the wrong escape characters.
You need to correctly escape your text every time you concatenate it into any kind of structured language.
When using SQL, you should ideally use parameters instead of concatenation.
There are a lot of misunderstanding on the topic.
People keep using improper words, and a real danger coming from such a confusion.
escaping being confused with safety
data being confused with strings
formatting being confused with trusting
One have to sort these matters out.
Otherwise we still have an accepted answer implying that using mysql_real_escape_string does produce a "safe" variable. While it is not.
Just remember to validate properly all user inputted data that you plan on using and don't allow html or javascript code to be inserted. You also need to keep in mind XSS attacks, not just MySQL Injections. A good way to prevent xss is using htmlspecialchars() to convert HTML characters into HTML entities.

Filtering out MySQL query in PHP

Hey there, I'm doing some queries to a MySQL database that involves some user-input.. And I was wondering how to prevent injection attacks, like, for example, if someone were to type
"; a-MySQL query here;"
It would be executed, this would allow people access to compromise my system. I'm wondering how i could protect against things like this, possibly create a function that filters out the query looking for bad statements? or perhaps not allowing the ; character?
To sum it all up:
Whats the common practice now adays to prevent injection attacks?
How should I go about it?
How effective will this solution be against people who know what they are doing from changing my database.
The only way is to properly escape user-submitted data. Others have pointed out some ways of doing so.
There's another way: prepared statements and placeholders. Prepared statements are supported by every modern PHP database interface, including mysqli and PDO.
Let's use PDO as a demonstration. Let's say we wanted to update a bit of data in the table foo submitted by a user.
$sql = 'UPDATE foo SET bar = ? WHERE user_id = ?';
$sh = $db->prepare($sql);
$sh->execute(array( $_POST['bar'], $_SESSION['user_id'] ));
The variables in the array passed to execute replace the question mark placeholders in the query. When this happens, they are automatically escaped and quoted. You don't need to manually escape them to make them safe to put in the database!
On the other hand, you will still need to filter them for unexpected content, like HTML, Javascript, letters where you expect numbers, etc. Making data safe to insert into the database is only half of the battle.
An even better way than calling a mysql_escape_string variant is to use bound queries in PDO, so that it's impossible to forget or miss a case since PDO will do the escaping for you when circumstances require it.
See for more:
http://www.electrictoolbox.com/php-pdo-bound-placeholders/
They best solution is to run every piece of input from the wild (user) through this function PHP.net: MySQL Real Escape String This will clean up most - if not all - Injection issues seen today. You would simply need to do something like the following:
$var = mysql_real_escape_string($_GET['var']);
$query = "INSERT INTO foo (var) VALUES (\"$var\");
It's always good practice to force type casting on variables you know should be a type. For instance a numerical identifier:
$id = (INT)$_GET['id'];
or
$id = ( is_numeric($_GET['id']) ? (INT)$_GET['id'] : -1; // replace -1 with FALSE, or NULL, etc
Which will force that variable to be an Integer so you won't end up with $id being "foo" or some other non-numeric.

update mysql db through form in php

I am getting this error,
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ' address='xxxxx', city='sssssssss', pincode='333333333', state='Assam', count' at line 1
Thanks in advance.
http://dpaste.com/hold/181959/
your WHERE clause is wrong, you don't write WHERE a=1, b=2, c=3 you want WHERE a=1 AND b=2 AND c=3
additionally your logic is flawed, because your WHERE clause would usually be something more like WHERE id = x (at the moment you're updating a row in a table, where the row data is already the same as that which you're updating it to - if that makes any sense? :) )
furthermore, learn to escape your sql strings properly or you leave yourself vulnerable to sql injection
As well as the problem explained by oedo, you've also got severe SQL injection problems. You need to use mysql_real_escape_string to encode strings for insertion into an SQL statement, not htmlspecialchars. Or use parameterised queries.
htmlspecialchars() is for HTML-encoding text just before you output it into an HTML page. You should not HTML-encode strings for storage in the database.
Firstly, don't you have some kind of unique identifier for your users? Maybe a customer-id of some kind? You could use that to identify the customer in the WHERE clause to make your SQL more clear.
Secondly, do you expect that your user to write all the company EXACTLY like it is in the database? Because that is what you expect from them with your current design.
You need to identify the record by using an ID, not the field values. If you look to a lot of websites, usually they send the ID to identify a record. Like edit.php?id=1284, or view.php?id=1284, etc.
In short you will have a form that you fill up with the values that are in the database for that record ID. If you edit it, you write a edit query like:
$UpdateQuery = "UPDATE customer SET name = '" . $name . "', address = '" . $address . "' ....... WHERE id = " . intval($_GET['id']);
The reason I add intval is because that will only allow numeric values to pass through. As mentoined by bobince, watch out for SQL injections and let mysql_real_escape_string pass through all of your string values you enter in the query too.

Categories