POST var in bindParam - php

Is it safe or not to use a POST var as below:
$stmt->bindParam(':'.$_POST[$field],$val);
or I need to check POST vars before?

You should use $_POST variables as the value, not the parameter name.
The $_POST variable could contain spaces or other characters that are not valid parts of a parameter name. I'm concerned that if you are doing what you show, that you have formed an SQL query like this:
$sql = "SELECT * FROM mytable WHERE mycolumn = :" . $_POST[$field];
Which is definitely not safe.
And there's no reason for the parameter names to be set to user input like that. Parameter names should be fixed by you, the programmer:
$sql = "SELECT * FROM mytable WHERE mycolumn = :myparam";
Then you bind using the same name. By the way, as long as you're using a reasonably recent version of PHP, you don't need the colon prefix in the bind call. You only need it in the SQL.
$stmt->bindParam("myparam", $_POST[$field]);

Related

Is this update statement missing something?

I have made a database where email id and corresponding name and password is stored. I have successfully obtained a form's data.. where the user enters updated name and password. But the problem is occuring with the query which is as follows
$db = mysqli_connect(all details)...
$name = $_POST['name'];
$password = $_POST['password']:
$email = $_POST['email'];
$query = "UPDATE mytable SET name='$name',password='$password' WHERE emailid='$email'";
$result = mysqli_query($db,$query);
Though I am getting all form values succesffuly and until and unless I put the 'where' clause.It works.But obviously updates all values. i want it to work with where..but so far unsuccessful :(
you need to put {} around the variables if its surrounded by quote ''
so your query should look like this
$query = "UPDATE mytable SET name='{$name}',password='{$password}' WHERE emailid='{$email}'";
$result = mysqli_query($db,$query);
EDIT : also before saving data to database make sure to filter and validate data
You need to make sure that emailid exists in mytable, you truly intended to filter by it and in your database scheme it has a type which supports the posted data. It seems that you are sending strings, like 'foo#bar.lorem' and your emailid is an int or something in the database scheme. Check it by running
desc mytable;
You need to put curly brackets around variables if you use apostrophe around them, but as a matter of style I like to close the string and attach the $variable with a . as this coding style is closer to me personally.
If everything fails, see what is generated, by echoing out the query string, try to run that directly, see what the error is and fix until...
... until it is fixed.
Also, you do not encrypt the password and your code is vulnerable to SQL injection too. Please, read about password encryption and SQL injection and then protect your project against these dangers.
You can write your statement as:
$query = "UPDATE mytable SET name='".$name."',password='".$password."' WHERE emailid='".$email."'";
using . as string concatenating operator

Is $_SESSION safe from sql injects?

I use PDO to access my MySQL database, and want to use IN. But sadly it don't seam to work with prepare, so I wrote this function
function is_numeric_array($array){
if(!is_array($array))
return is_numeric($array);
if(is_array($array))
foreach($array as $int)
if(!is_numeric($int))
return false;
return true;
}
Then used it like this
if(!is_numeric_array($_SESSION['story'])){
die("Error, array contains non-integers");
}
$query = "(";
for($i = 0; $i<count($_SESSION['story']); $i++)
$query .= $_SESSION['story'][$i].(count($_SESSION['story'])-1 != $i ? "," : "");
$query .= ")";
//Collect all data needed
$stories = openConnection() -> query("SELECT * FROM `stories` WHERE `id` IN {$query}") -> fetchAll();
I know it, looks ugly. But I don't want any SQL injects.
You don't really have to test for the input being numeric, because in MySQL, any string e.g. '123abc' in a numeric context (like being compared to an integer column id) implicitly takes only the digits and ignores the rest. A non-numeric string like 'abc' simply has the integer value 0 because there are no leading digits.
The point is, values are safe from SQL injection if you use query parameters. Whether the inputs come from $_SESSION or another source is irrelevant. $_SESSION is neither safe or unsafe with respect to SQL injection, it's how you pass the data to your query that matters.
I would also simplify the code to format the list of parameter placeholders:
$placeholders = implode(',', array_fill(1, count((array)$_SESSION['story']), '?'));
And forget about bindParam(), just pass the array to execute().
//Collect all data needed
$storyQuery = openConnection() -> prepare("SELECT * FROM `stories`
WHERE `id` IN ({$placeholders})");
$storyQuery -> execute((array)$_SESSION['story']);
$story = $storyQuery -> fetchAll();
Re your comment:
In PDO, you can use either named parameters like :id, or you can use positional parameters, which are always ? (but don't mix these two types in a given query, use one or the other).
Passing an array to execute() automatically binds the array elements to the parameters. A simple array (i.e. indexed by integers) is easy to bind to positional parameters.
If you use named parameters, you must pass an associative array where the keys of the array match the parameter names. The array keys may optionally be prefixed with : but it's not required.
If you're new to PDO, it really pays to read the documentation. There are code examples and everything!
$_SESSION is just a way to store data on server over a session. It's not direct related with SQL injection.
Even if it's a cookie or a session , the hash that I store is alphanumeric only, for security purposes. When I'm checking the cookie/session against any type of inject / modification , I use ctype_alnum:
if (ctype_alnum($_SESSION['value']))
// exec code
else
// trigger_error
This way, no matter who is setting the SESSION value (you or the client, if you give him the possibility to), there wont be any case in which non-alphanumeric chars like comma, quotes, double quotes or whatever will be inserted.

PHP 'nothing' character

I like embedding variables in strings - "I like $verb $noun in strings!"
But then I was designing a database access script:
$sqlfragment = "SELECT * from " . $databasetableprefix . "_user";
Lovely. But what happened to my embedding variables in strings?!
I want to do something like this:
$sqlfragment = "SELECT * from $databasetableprefix_user";
But that will be interpreted as from the variable $databasetableprefix_user.
So I would use a space:
$sqlfragment = "SELECT * from $databasetableprefix _user";
But spaces aren't allowed in database table names, so that won't work.
(What I want is this resulting string: "SELECT * from cc_user", if cc is the prefix.)
Can I create this string using variable embeds? Perhaps a sort of 'nothing' character, that will stop PHP from thinking it is part of the variable name, but not carry through to the SQL?
$sqlfragment = "SELECT * from {$databasetableprefix}_user";
Wrap the variable in {} like so:
$sqlfragment = "SELECT * from {$databasetableprefix}_user";
You have to use curly brackets to tell PHP where the variable name begins and ends, as described in detail in the PHP manual.
$sqlfragment = "SELECT * from {$databasetableprefix}_user";
Also, be very careful using variables to generate SQL statements, as it can easily become a security risk if you don't carefully track the source of your variables or validate their values.

concatenate mysql select query with php variable?

I am trying to concatenate a MySQL SELECT query with PHP variable but got an error.
My PHP statement which gives an error is:
$result=mysql_query("SELECT user_id,username,add FROM users WHERE username =".$user."AND password=".$add);
and error as:
( ! ) Notice: Undefined variable: info in C:\wamp\www\pollBook\poll\login.php on line 18
Call Stack
I don't understand where I missed the code.
When I write query without WHERE clause it works fine.
The reason why your code isn't working
You are attempting to use a variable, $info, that has not been defined. When you attempt to use an undefined variable, you're effectively concatenating nothing into a string, however because PHP is loosely typed, it declares the variable the second you reference it. That is why you're seeing a notice and not a fatal error. You should go through your code, and ensure that $info gets a value assigned to it, and that it is not overwritten at some point by another function. However, more importantly, read below.
Stop what you are doing
This is vulnerable to a type of attack called an SQL Injection. I'm not going to tell you how to concatenate SQL strings. It's terrible practice.
You should NOT be using mysql functions in PHP. They are deprecated. Instead use the PHP PDO Object, with prepared statements. Here's a rather good tutorial.
Example
After you've read this tutorial, you'll be able to make a PDO Object, so I'll leave that bit for you.
The next stage is to add your query, using the prepare method:
$PDO->prepare("SELECT * FROM tbl WHERE `id` = :id");
// Loads up the SQL statement. Notice the :id bit.
$actualID = "this is an ID";
$PDO->bindParam(':id', $actualID);
// Bind the value to the parameter in the SQL String.
$PDO->execute();
// This will run the SQL Query for you.
You are missing space before "AND " and you should use single quotes as suggested in other answers.
$result=mysql_query("SELECT user_id,username,add FROM users WHERE *username =".$user."AND* password=".$add);
Updated:
echo $sql = "SELECT user_id,username,add FROM users WHERE username ='".$user."' AND password='".$add."'";
$result=mysql_query($sql);
although there is no $info variable used in the query but you need to correct the query:
$result=mysql_query("SELECT user_id,username,add FROM users WHERE username ='" . $user . "' AND password='" . $add . "'");
First from the error its looks like one of your variables is not defined. .. check it. Second surround your parameters with ' for safer syntax.
This is because the variables you are using might not have defined above
So first initialize your variables or if its coming from somewhere else(POST or GET) then check with isset method
So complete code would be
$user = 123; // or $user = isset($user)?$user:123;
$add = 123456; // or $add = isset($add)?$add:123456;
And then run your query
$result=mysql_query("SELECT user_id,username,add FROM users WHERE username =".$user."AND password=".$add);

using php variable in mysql LIKE

I want to write a mysql query something like this:
select * from books where title like
'$title_';
The $title is a php variable. when i run the above query, it throws an error saying
'$title_ variable not found'
How can I achieve this?
Thanks..
Use:
"... WHERE title LIKE '". mysql_escape_real_string($title) ."_'";
You could use:
WHERE title LIKE '{$title}_'";
..but there's a risk of SQL Injection attacks
Do it like this:
$query = "select * from books where title like '{$title}_';"
$result = mysql_query($query) or die(mysql_error());
By surrounding variable in {} you can specify that only $title is a variable and not the _. And the double-quote string will ensure that this variable gets expanded to its value.
Your query string must looks like:
$query = "select * from books where title like '".$title."_'";
Please note, the '".$title."_'
The error you are getting is because your query is taking $title and not the value of your php variable $title
Try:
"select * from books where title like '{$title}_';"
The curly braces first evaluate the variable and later add your wildcard _ to the variable value thereby providing sql query with your search criteria.
$query = "select * from books where title like '" . $title_ ."'";
$query = "SELECT * FROM books WHERE title LIKE '".$title."_';";
Do you have a variable $title_ or is it just $title?
If its just $title then:
$query = "select * from books where title like '".$title."_'";
The mysql query is merely a string. You just have to put the value of your $title php variable inside this string. The problem is that this string is followed by a character underscore that is valid in a variable name, hence you have to delimit the variable name or underscore will be included in the name.
There is several way to do it, for exemple:
$query = "select * from books where title like '${title}_'";
$query = "select * from books where title like '".$title."_'";
As OMG Ponies said, if $title came from some user input and not from some controlled part of your program (for exemple another table in database), the variable should also be protected or there is some risks of SQL injection attack (executing more than one query, and more specifically a query prepared by some hacker to be some valid SQL).
Beside attacks, there is also some other potential problems if you do not escape. Imagine what will happen for exemple if the title actually contains a quote...
I would usually do:
$query = "select * from books where title like '".addslashes($title)."_'";
but there is other variants depending the escaping context and what you want to protect from.

Categories