so, I'm using one query to get the profile photo, i'm using the follow query:
$sql = "SELECT photo FROM users WHERE login = '$username'";
I already tried many ways to do, with and without the inverted commas.
$sql = "SELECT `photo` FROM `users` WHERE `login` = '$username'";
Next code is like:
$result = mysqli_query($link, $sql);
echo "<script>console.log('photo: ".$sql."');</script>";
When I check the console i see this error:
Uncaught SyntaxError: missing ) after argument list
When I do the query with just "select photo from users" it returns a value.
On another page I use the same code to get the permissions and it returns a value that I want
$sql = "SELECT permission FROM users where login = '$username'";
$result = mysqli_query($link, $sql);
if ($result->num_rows > 0) {
while ($row = mysqli_fetch_array($result)) {
$save = $row[0];
}
}
Permission Column is int;
Photo Column is varchar;
Since the query contains single quotes, you can't use single quotes around the argument to console.log(), because the quote in the query will terminate the JavaScript string.
Put double quotes around the JS string.
echo "<script>console.log(\"photo: ".$sql."\");</script>";
Your javascript console is wrapped in ' quotes, and your '$username' value is also using these single quotes so this is causing a problem.
Therefore; if you want to export this SQL string to your console, you need to escape these single quotes or to use alternative quotes in your javascript.
This issue is better resolved by Barmar's Answer.
BUT:
Best Practise; you should NOT be outputting SQL strings to your browser at all. This is a potentially severe security hole. Instead (especailly if your SQL server is 'localhost') you should be outputting your SQL data to your PHP error logs:
$result = mysqli_query($link, $sql);
//echo "<script>console.log('photo: ".$sql."');</script>";
error_log("Query Output: ".print_r($sql,true));
Then in your IDE or secured server connection (SFTP etc.) then you can access the PHP Error Logs and view the SQL more safely.
See also: Where does PHP store the error log? (php5, apache, fastcgi, cpanel)
Related
Why do I see in several examples of mysql queries via php the syntax:
$q = "CREATE TABLE '$tablename' ('$t_id_name')";
or things similar to that? I'm asking about the single quotes around the variable names. Is this required in MySQL strings? If I echo the string, it seems to expand the variables whether the quotes are there or not.
And would this pose a problem if this were done for something that was intended to be an integer?
To answer your question, the quotes are necessary, but not to expand the variable. A typical SQL query would look like this:
$q = "SELECT * FROM `table` WHERE `first_name` = 'user3475234'";
Now, consider the following example:
<?php
$tablename = "users";
$user = "user3475234";
$q = "SELECT * FROM `$tablename` WHERE `first_name` = '$user'";
echo $q;
This will display: SELECT * FROM `users` WHERE `first_name` = 'user3475234'. Note that the quotes weren't necessary to output the string, but they were a necessary part of the query.
That being said, code like this opens your script to SQL injection. I won't explain too much about it, since there are plenty of resources discussing it, but consider the example where someone's username is user3475234' OR 1==1--. This username will effectively return all users in the table.
You must use backticks (`) for field or table name especially if the field or table name are same with mysql command. And you need to use single-quote (') for value.
This is bizarre, I'm changing some code from mysql to mysqli functions cause of php 5.5+, in these two basic examples, mysql_query had no ' single quote nor ` backtick and worked fine.
$sql = "SELECT * FROM `".$table."`"; // requires: ` ` or fails
$result = mysqli_query($con,$sql);
$sql = "SHOW TABLES LIKE '".$table."'"; // requires: ' ' or fails
$result = mysqli_query($con,$sql);
Can someone explain why?
EDIT: I guess the essence of my question is that: Both functions worked fine without any kind of quotes with mysql_query, and both failed mysqli_query without some kind of quotes. Meaning I will have to fiddle around with half my query's when changing from mysql_ to mysqli_
In your first select statement you are trying to select a table by it's name, hence it will accept the name either with ` or without them, but now with single or double quotes. These should work :
$sql = "SELECT * FROM `table_name`";
$sql = "SELECT * FROM table_name";
In the second case you need to pass in a string to be compared by the like statement hence you need to surround it either with single ' or double " quotes:
$sql = "SHOW TABLES LIKE 'string'";
$sql = "SHOW TABLES LIKE \"string\"";
Edit:
Check out this previous answer on SO as well:
Using backticks around field names
Edit 2:
Since we (me and in comments) suggested that backticks are somehow optional, keep in mind that as a best practise use them whenever you can since although it will allow you to pass most queries without them, some queries using MySql reserved words would break when containing mysql reserved words
I am having a problem in my php file named JO-dashboard.php. It displays the error presented below the code.
Here is my code:
<?php
$link = connectToDB();
$strXML = "<chart caption='Factory Output report' subCaption='By Quantity' pieSliceDepth='30' showBorder='1' formatNumberScale='0' numberSuffix=' Units'>";
$strQuery = "select DISTINCT profile from vgprofile";
$result = mysqli_query($link, $strQuery) or die(mysqli_error());
if($result) {
while ($ors = mysqli_fetch_array($result)) {
$strQuery = "select sum(MT) as totalLM from tbljocreator where PROFILE =" . $ors['profile'];
$result2 = mysqli_query($link, $strQuery) or die(mysqli_error());
$getresult2 = mysqli_fetch_array($result2);
$strXML .= "<set label='" . $ors['profile'] . "' value ='" . $getresult2['totalLM'] . "' />";
mysqli_free_result($result2);
}
}
mysqli_close($link);
$strXML .= "</chart>";
echo renderChart("FusionCharts/Column3D.swf", "", $strXML, "JoCreator", 450, 300, false, true);
?>
THE ERROR IS IN:
$result2 = mysqli_query($link, $strQuery) or die(mysqli_error());
In the browser it shows:
Warning: mysqli_error() expects exactly 1 parameter, 0 given in C:\xampp\htdocs\LearningFusionCharts\MyFirstChart\JO-dashboard.php on line 29
the mysqli_error function requires a parameter. http://us3.php.net/mysqli_error
p.s clean up your code and using tabs :)
The initial problem
You have to pass the connection object to the function mysqli_error, like this:
$result = mysqli_query($link, $strQuery) or die(mysqli_error($link));
And this...
$result2 = mysqli_query($link, $strQuery) or die(mysqli_error($link));
Note: your code must have another problem that will be revealed after you do this. PHP wouldn't be executing the part of mysqli_error if there weren't an error in the query or something related to it.
The hidden problem
In fact, I have reasons to think* the problem is that $ors['profile'] is string, and therefore it should be between quotation marks in the query string:
$strQuery = 'select sum(MT) as totalLM from tbljocreator where PROFILE = "' . $ors['profile'] . '"';
*: This was confirmed in the comments. The error was:
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 'RIVETS' at line 1
In this case RIVETS is the value of $ors['profile'] and evidently it is an string, ergo it must go between quotation marks...but that doesn't mean it is safe.
SQL Injection
We could say that your code is correct, the same code will probably work is the data where different. Yet, since the values you are putting in the query string may not be entirely safe (even with the data comming from the database), you will have to escape the dangerous characters.
This is put in evidence by the error you got:
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 '"CUTTING DISC 4""' at line 1
In this case, the variable $ors['profile'] got the string CUTTING DISC 4". This value is comming from the database and is causes a problem. It contains 4" meaning four inches, but Mysql sees the quotation marks (") and thinks that that is the end of the string, and tries to interpret whatever comes after the quotation marks as SQL.
If this input weren't from the database, but form the user... it would be worst... a malicious user could take adventage of it to execute arbitrary commands in the database. The potential of this kind of attack is overwhelming.
I recommend the video Hacking Websites with SQL Injection - Computerphile, it is a very good introduction to SQL injection for those beginners to web security, database security or information security in general. To learn more about what can be potentially be done with this kind of attack, read SQL Injection Walkthrough (DVWA) by Trenton Ivey.
Preventing SQL Injection - The old way
The old way to solve this problem is to escape the characters. SQL allows to do so by using the backslash character (\). So, in this example you would have to pass 4\" instead of 4". But that is the tip of the iceberg, there are plenty of security problems with it.
Something you could do for ease of migration is to declare a function to sanitize the data you send to the database, the idea is to escape any possibly treating character... in fact there is a function for that in PHP (mysql_real_escape_string):
$strQuery = 'select sum(MT) as totalLM from tbljocreator where PROFILE = "' . mysql_real_escape_string($ors['profile']) . '"';
The problems with the old way
But mysql_real_escape_string is deprecated and should not be used in new development (you would notice it is not form mysqli... ), this function has some quirks of itself too... for example there is no way to tell that function what character encoding you are using (it uses whatever the databases is using), and there has been reports of problems with it when using multibyte characters. That is the old way to solve this.
Here goes another recommendation: The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets by Joel Spolsky. I understand if you don't want to read... get another video: Characters, Symbols and the Unicode Miracle - Computerphile
Preventing SQL Injection - The new and improved way
With that said, the correct solution is to migrate to prepared statements, they are not really that hard with mysqli, it would be something like this:
$strQuery = 'select sum(MT) as totalLM from tbljocreator where PROFILE = ?';
if($stmt = $link->prepare($strQuery))
{
//s for string
//i for integer
//d for double (or float)
$stmt->bind_param('s', $ors['profile']);
if (!$stmt->execute())
{
die mysqli_error($link);
}
}
else
{
die mysqli_error($link);
}
Read more about Prepared Statements at PHP.net.
Just change
mysqli_error()
to
mysqli_error($link)
in each of the places where it occurs.
ie 4th line:
$result = mysqli_query($link, $strQuery) or die(mysqli_error($link));
and 8th line:
$result2 = mysqli_query($link, $strQuery) or die(mysqli_error($link));
Replace
mysqli_error()
by
mysqli_error($link)
By the way, if the error message is as clear, you don't need to ask here. Just read the manual.
I am trying to enable users to change their password.
I keep getting the user name and password are not in the file and I suspect the password is not correctly readable by the script, maybe because of the md5 encryption. Is there any error on my SQL query?
$query = "SELECT * FROM users WHERE name='$e' AND pass='".md5($p)."'";
$result = mysql_query($query) or die ("Error in query: $query. ".mysql_error());
$num = mysql_num_rows($result);
Instead of building up your query with concatenation, you should look into using PHP Data Objects (PDO).
Not only will it likely fix your error, it will also fix your current Sql Injection vulnerability.
I have the following query:
var_dump($id); // string '51' (length=2)
$sql = "SELECT * FROM table WHERE id=$id";
$result = mysql_query($sql, $db);
$myrow = mysql_fetch_array($result);
var_dump($myrow) // null (NOT OK)
When I change the $id for a hard-coded value(51) it works:
$sql = "SELECT * FROM table WHERE id=51";
$result = mysql_query($sql, $db);
$myrow = mysql_fetch_array($result);
var_dump($myrow); // array 0 => string '51' (length=2) (OK)
It's as if the $sql is not getting parsed correctly. It is a very old site, could it be something to do with the PHP version the site was originally created for?
$sql = "SELECT * FROM table WHERE id=".$id;
// ALSO WORKS. But I am not really looking forward to doing a FIND & REPLACE
EDIT:
The site has hundreds of these types of queries. It is an old site that was developed my somebody else. I was wondering if there was an INI setting or something that has been switched between PHP versions that I can switch back.
Thanks
PHP Version: PHP5.2
The site was build for version 4.something.
rather than writing query like this
$sql = "SELECT * FROM table WHERE id=$id";
you can use this alternative also..
$sql = "SELECT * FROM table WHERE id='".$id."'";
use this please :
SELECT * FROM table WHERE `id` = $id
insert ` in both side of id
register_globals was turned off. I know the security implications but I have it on its own virtual server and haven't got time right now to fix it.
In htaccess:
php_flag register_globals on
Apart from the fact, that queries should be escaped (in this case casting to integer will suffice) or preferably created through prepared statements, my guess would be that it is the query that fails.
PHP have parsed double quoted strings since the beginning, so try outputting the value of $sql to see what gets sent to MySQL.