Is this PHP code exploitable? [duplicate] - php

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Are mysql_real_escape_string() and mysql_escape_string() sufficient for app security?
So basically I have a qryName in the URL
eg: mysite.com/qryName=WHAT
if (isset($_GET['qryName']))
{
$qryName = mysql_real_escape_string(filter($_GET['qryName']));
}
$urldata = mysql_fetch_assoc(mysql_query("SELECT * FROM gangs WHERE ShortName = '" . $qryName . "' LIMIT 1"));
$urldata is the code so it pretty much selects from the database. Note that in the database, the qryName has no spaces, special chars etc..
Just wondering if that is exploitable?

It is safe since you properly escape the value - unless....
...you do not initialize the variable and have register_globals enabled. In that case someone can use a cookie or POST value to send you an arbitrary value for $qryName containing evil SQL statements.
But since you probably just posted a snipped and do initialize the variable before that if statement (you do, right?!), your code is safe. Consider using prepared statements (with PDO) though instead of escaping - they make your code more readable, too.

Why don't you add one extra piece of validation or take out the isset and check if it only contains letters for example
if(ctype_alpha($_GET['qryName'])) {
$qryName = mysql_real_escape_string(filter($_GET['qryName']));
}
http://php.net/manual/en/function.ctype-alpha.php

Have you considered using something like PDO? My understanding is that when using PDO and bound variables, SQL injection is not possible. There are also other advantages worth considering.
A similar PDO query would be:
$data=array($_GET['qryName']);
try {
$STH = $this->DBH->prepare('SELECT * FROM gangs WHERE ShortName = ? LIMIT 1');
$STH->execute($data);
while($row = $STH->fetch()) {
$var1=$row->FieldName;
}
}
catch(PDOException $e) {echo $e->getMessage();}
You add the variables to the array ($data) and they are bound in order to each question mark in the SQL statement.

Related

Updating sql table using php [duplicate]

This question already has answers here:
How can I prevent SQL injection in PHP?
(27 answers)
Closed 6 years ago.
I have a table (core_customer_information) and I want to create a SQL query in php that uses the variable $code and updates the activated field in my table.
$code = mysqli_real_escape_string($conn, $_GET['code']);
$check = mysqli_query("SELECT * FROM core_customer_information WHERE activation_code='$code' AND activated='1' ");
if ( mysqli_num_rows($check) == 1)
{
die ('The account has already been activated');
}
else
{
$activate = mysqli_query("UPDATE core_customer_information SET activated='1' WHERE activation_code='$code'");
echo ('Your account has know been activated <br>');
echo $code;
}
First of all, I check whether the activated is equal to 1, in which case the account is classed as activated, and if not, I then create an UPDATE query to update the activated field of this class.
My problem is that the query isn't updating my table and I'm unsure where the problem is at.
I would appreciate if someone could take a look for me please.
I would recommend you use mysqli_real_escape_string as it escapes the string taking into account the current connection charset as stated by the page:
This function is used to create a legal SQL string that you can use in an SQL statement. The given string is encoded to an escaped SQL string, taking into account the current character set of the connection.
To prevent most mysql injection methods you should do the following:
$code = mysqli_real_escape_string($link, $_GET['code']);
If you should ever use an adapter like ADODB or some other, I'd recommend you use prepared statements and their methods of preventing SQL injection.
It's not totally clear from your question what language you will be using to launch the SQL queries (since the only tags are sql and mysql at the moment...)
But if the language is similar to Java then you can use something similar to Java's PreparedStatement. (See https://docs.oracle.com/javase/7/docs/api/java/sql/PreparedStatement.html)
A PreparedStatement is safer than simple concatenation of dynamic variables into sql Strings.

How i can make my code secure from SQL Injection [duplicate]

This question already has answers here:
How can I prevent SQL injection in PHP?
(27 answers)
Closed 9 years ago.
I know i am not secure when i am using this code so anything i can add in my code?
I have tried my self sql injection they are somewhere working but not much as i dont have much knowledge about sql injection. but as hacker are more smart so they can really hack my website.
Url looks like this :
http://example.com/profile.php?userID=1
php
$userID = $_GET['userID'];
$userID = mysql_real_escape_string($userID);
$CheckQuery = mysql_query("SELECT * FROM tbl_user WHERE id='$userID'");
$CheckNumber = mysql_num_rows($CheckQuery);
if ($CheckNumber !== 1)
{
header("Location: tos.php");
}
I tried:
http://example.com/profile.php?userID=1'
which hide many things on site.
when i tried
http://example.com/profile.php?userID=1' UNION SELECT * FROM tbl_user; with havij it was hacked
Thanks :|
use mysqli::prepare or at least sprintf
mysql_query(sprintf("SELECT * FROM tbl_user WHERE id='%d'", $userID);
$db = new mysqli(<database connection info here>);
$stmt = $db->prepare("SELECT * FROM tbl_user WHERE id='?'");
$stmt->bind_param("id", $userID);
$stmt->execute();
$stmt->close();
Dont use mysql_* functionality at all.
Use PDO or mysqli.
http://php.net/PDO
http://php.net/mysqli
PDO will escape your data for you.
But for your current code:
$userID = $_GET['userID'];
$userID = mysql_real_escape_string($userID);
if(ctype_digit($userID))
{
$CheckQuery = mysql_query("SELECT * FROM tbl_user WHERE id='$userID'");
$CheckNumber = mysql_num_rows($CheckQuery);
if ($CheckNumber !== 1)
{
header("Location: tos.php");
}
} else {
// THE USER ID IS NOT ALL NUMBERS, CREATE AN ERROR
}
I know i am not secure when i am using this code
This statement is wrong.
As a matter of fact, this very code is pretty secure.
And none of the codes you provided below would do any harm. Why do you think it is not secure?
This way is not recommended, yes. And the way you are using to format your queries may lead to injection for some other query. But the present code is perfectly secure.
As long as you are enclosing every variable in quotes and escape special chars in it - it is safe to be put into query.
Only if you omit one these two rules (i.e. escape but don't quote or quote but don't escape) - you are in sure danger. But as long as you're following both, you're safe.
The only reason for "hacking" I can guess of is a single quote used in HTML context. In some circumstances it can "hide many things on the page". But for the SQL, with the code you posted here, it's harmless
Look, out of this link
http://example.com/profile.php?userID=1'
your code will produce such a query
SELECT * FROM tbl_user WHERE id='1\''
which is quite legit for mysql and will even return a record for id=1, as it will cast 1' to 1 and find the record. This is why there is no redirect to tos.php.
So, the problem is somewhere else.
either there is a code that does not follow the rules I posted above
or this problem is unrelated to SQL at all - so, you are barking wrong tree and thus still keep whatever vulnerability open
Most likely you have to echo your values out
u can try type casting the value
<?php
$CheckQuery = mysql_query("SELECT * FROM tbl_user WHERE id='".(int)$userID."'");
?>

Escaping quotes in PHP [duplicate]

This question already has answers here:
How to include a PHP variable inside a MySQL statement
(5 answers)
Closed 3 years ago.
How do I escape quotes in PHP when trying to query a MySQL database?
Without adding addslashes on every value:
$fname = addslashes("Value's with quote''s'");
$lname = addslashes("Value's with quote''s'");
The proper way is using prepared statements, e.g. via PDO.
If you can't do that, you have to process all values which are passed into a database query with mysql_real_escape_string() - and no, doing that simply on all $_POST data is not an option since that would render them unusable for HTML output, etc. You could create a $_ESC or something similar though... but note that this variable will not be superglobal!
You ought to escape special characters (not only quotes) on every string value (it's useless to escape values you're not going to enclose in quotes in a query. Those values require another treatment).
To avoid boring repetitive typing you can apply an escaping function to array items in a loop.
In case you're using MySQL and for INSERT/UPDATE queries, you can use this helper function:
function dbSet($fields) {
$set = '';
foreach ($fields as $field) {
if (isset($_POST[$field])) {
$set .= "`$field`='" . mysql_real_escape_string($_POST[$field]) . "', ";
}
}
return substr($set, 0, -2);
}
It is used like this:
$id = intval($_POST['id']);
$table = 'users';
$fields = explode(" ","name surname lastname address zip fax phone");
$query = "UPDATE `$table` SET ".dbSet($fields).", `date`=NOW() WHERE id=$id";
Also don't forget to set proper encoding using mysql_set_charset() as it's required for the mysql_real_escape_string() function.
A good idea would be using PDO prepared statements as described here.
It will automatically escape those characters.
Firstly, don't use addslashes() - it is not recommended for use with escaping DB query strings because it doesn't escape everything that actually needs to be escaped; there are some characters that can still get through.
The correct solution depends on the database you're using. Assuming you're using MySQL, the correct function to use instead of addslashes() is mysql_real_escape_string().
You probably notice that using this on every line is even more verbose than addslashes(), so it doesn't really answer your question.
If your fields are all separate variables (as per your example), then you're really stuck with doing that for a bunch of lines of code.
If you're using an array (eg $_POST), then you can do it in a loop, which will make things a lot neater - you can do things like this:
foreach($_POST as $key=>$value) {
$sqlstrings[$key]="`".$key"` = '".mysql_real_escape_string($value)."'";
}
$sql = "update table ".implode(' ',$sqlstrings)." where id=".$update_id;
A more up-to-date method for doing SQL is to use an object model rather than manually building the queries. PHP has a number of libraries that may help: mysqli is an improved MySQL library, and PDO is a database-neutral library. Either of these would give you much better security and flexibility than building the SQL code directly. However if you already have a lot of code in place then they would represent a fairly significant overhead of code changes, so you may want to go with the mysql_real_escape_string() option discussed above in the short term. I do recommend investating them them though.

Make this query safe? [duplicate]

This question already has answers here:
Closed 13 years ago.
Possible Duplicate:
Best way to stop SQL Injection in PHP
I have seen some of examples that use something called a PDO to make a query safe from sql-infection, or others that use real_escape, but they all seem to be incomplete or assume some knowledge. So I ask, take this simple update query and make it safe from sql-injection.
function updateUserName($id,$first,$last)
{
$qry = 'UPDATE user SET first = "'.$first.'", last = "'.$last.'" WHERE id = '.$id;
mysql_query($qry) or die(mysql_error());
}
Basically, you have to :
escape string, with mysql_real_escape_string
make sure integer really are integers ; for instance, using intval.
Which, in your specific case, would give something like this :
$qry = 'UPDATE user SET first = "'
. mysql_real_escape_string($first)
. ' ", last = "'
. mysql_real_escape_string($last)
. '" WHERE id = '
. intval($id);
Of course, this is considering that last and first are varchar, and that id is an integer.
As a sidenote : when an SQL error (this is also true for whatever kind of error you can thing about) occurs, you should not display a technical error message and just let the script die.
Your users will not understand that technical error message -- they won't know what to do with it, and it's not their problem.
Instead, you should log (to a file, for instance) that technical error message, for your own usage ; and display a nice "oops an error occured" page to the user.
This is the better query:
$qry = 'UPDATE user SET first = "'.mysql_real_escape_string($first).'", last = "'.mysql_real_escape_string($last).'" WHERE id = '.intval($id);
Use mysql_real_escape_string for strings and intval for numbers in your queries to make them safer.
mysql_real_escape_string + sprintf
$qry = sprintf('UPDATE user SET first = '%s', last = '%s' WHERE id = %d', mysql_real_escape_string($first), mysql_real_escape_string($last), $id);
I like it that way.
You could wrap all your variables in mysql_real_escape_string(). PDO (PHP Data Objects) is a better solution though, if it's available in your environment. You can find these docs here.
PDO will make your code more Object-Oriented and automate some of these tasks for you. Some good sample code of PDO preparing statements can be found deeper into the docs here.

PHP Cookie Security Question

I have the following code that is presenting a 'word-of-the-day',
As I am relatively new to php coding, I wanted to make sure that there weren't any
security issues for how I am selecting from my database from the cookie value. Thanks.
if ($word_of_the_day) {
$wotd = $wpdb->get_results("SELECT term,definition FROM glossary WHERE term = '{$word_of_the_day}'");
foreach ($wotd as $term) { }
}
elseif ($_COOKIE['WOTD']) {
$word_of_the_day = htmlspecialchars(addslashes($_COOKIE['WOTD']));
$wotd = $wpdb->get_results("SELECT term,definition FROM glossary WHERE term = '{$word_of_the_day}'");
foreach ($wotd as $term) { }
}
else {
$wotd = $wpdb->get_results("SELECT term,definition FROM glossary ORDER BY RAND() LIMIT 1");
foreach ($wotd as $term) {
setcookie("WOTD", $term->term, time()+86400);
}
}
Well if $word_for_the_day comes from user input, there's your first problem. Do this before you use it:
$word_for_the_day = mysql_real_escape_string($word_for_the_day);
Your cookie actually looks OK. The htmlspecialchars() and addslashes() calls, in the context you're using them, don't appear vulnerable to SQL injection or XSS attacks.
You should check out mysql_real_escape_string: "Escapes special characters in a string for use in a SQL statement". You don't have to do the stuff that you're doing with htmlspecialchars and addslashes manually. Are you familiar with SQL injection security risks? If the variable that you're including in the SELECT statement, $word_of_the_day, comes from the user, then you have a potential SQL injection problem.
addslashes is extremely weak. First thing, run everything you query from the db through mysql_escape_string to prevent sql injection. That's just the basics.
if($word_of_the_day){
$word_of_the_day = mysql_escape_string($word_of_the_day);
$wotd = $wpdb->get_results ("SELECT term,definition FROM glossary WHERE term = '{$word_of_the_day}'");
Also, cookies in general aren't very secure no matter how secure code you write. For a much more secure solution, I recommend you use PHP sessions ($_SESSION). You can store variables in this superglobal variable and it will stay there between page loads.
http://www.php.net/manual/en/session.examples.basic.php
After that, you may want to protect against session hijacking or poisoning if you're really going for it
Another option you could consider would be to store the id of the word, instead of the word itself in the cookie. That way, it can only ever be an integer. Of course, using the word is fine too, as long as you mysql_real_escape_string it first, I just wanted to offer another option.
One of the safest ways is to use the PDO MySQL functions, which implements parameters:
$db = new PDO('mysql:host=hostname;dbname=defaultDbName', 'username', 'password');
$stmt = $db->prepare('SELECT term,definition FROM glossary WHERE term = :wotd');
if ($stmt) {
if ($stmt->execute(array(':wotd' => $word_of_the_day))) { //This is safe for any input method
$info = $stmt->fetchAll();
foreach($info as $row) {
//Whatever
}
}
}
The PDO drivers does the correct escaping / quoting according to the data type in the table.
Where does $word_of_the_day come from? If it comes from user input, you are open to SQL injection.

Categories