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.
Related
I found similar questions but can't solve my problem yet. Here is the relevant code:
$query = "SELECT * FROM conceptos WHERE descripcion = '$descripcion'";
if ($result = mysql_query($query,$connection)){
if (mysql_num_rows($result) > 0){
//Do something
} else {
die($query);
exit;
}
} else {
die(mysql_errno() . ' - ' . mysql_error());
exit;
}
I don't have problems with the connection or the permissions, because this code snippet is inside a loop and the other queries enter the "Do something" section. But when I take the echoed query and execute it in phpMyAdmin, it returns 1 value as expected. Why? What reasons can lead to this behavior? Thanks in advance for any advice.
I had this problem and found that it was because I junked up my database by copy/pasting directly to the database from MS Word. Pasting had inserted special slanted apostrophes that PHPMYADMIN could apparently parse but my php code could not. Once I replaced those with a standard single quote, all was well.
Try this "SELECT * FROM conceptos". If it's worked, you have bad query in "WHERE ..."
Are you sure your query is searching for the right description? The double quotes should expand all internal variables, but you do have single quotes as well in case there is a copying to stackoverflow issue.
This will ensure that the description is expanded in case.
$query = "SELECT * FROM conceptos WHERE descripcion = '" . $descripcion . "'";
Secondly, have you validated the variable contents you are using, as suggested by #crotos?
The mysql_ are also deprecated, so you should use PDO, or at the least, mysqli_.
You can try to setup the general query log of your mysql server and see what queries are really executed. See http://dev.mysql.com/doc/refman/5.1/en/query-log.html
Also, check your encodings. Maybe your mysql connection is in ISO8859-1 and your table fields are in UTF-8 (or the opposite). Do you have any accents or special characters in your data?
i also faced this problem and got it solved using:
mysqli_query($con,$query);
instead of
mysql_query($query);
coz its depreciated
source:
File Downloading error from database php
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 's website.
mysql_query("UPDATE Scholarships2 SET Requirements2 = '$requirements2'
WHERE scholarshipID = '$sID'")
or die("Insert Error1: ".mysql_error());
I read other Stackoverflow questions/answers on this subject but cannot find the reserved word I am using.
$sID is just an int while, $requirements2 is
$regex = '/<h4>Requirements<\/h4>([\n\n\n]|.)*?<\/table>/';
preg_match_all($regex,$data,$match);
$requirements2 = $match[0][0];
for the right syntax to use near 's website
This means it's complaining about the bit of your query that is 's website. "Where is that bit in your query?", I hear you ask.
Well, one of those variables in there contains something like Bob's website and the fact that you're blindly injecting that into your query will give you something like:
UPDATE Scholarships2 SET Requirements2 = 'Bob's website' ...
This particular query will not go down well with the SQL parser :-)
Other possibilities that don't immediately choke the parser will also not go down well with your customer base when little Bobby Tables steals or deletes your credit card database.
See this link for a fuller explanation and strategies for avoidance. In your case, that's probably going to involve mysql-real-escape-string.
In other words, you'll need something like:
mysql_query(
"UPDATE Scholarships2 SET Requirements2 = '" .
mysql_real_escape_string($requirements2) .
"' WHERE scholarshipID = '" .
mysql_real_escape_string($sID) .
"'"
) or die("Insert Error1: ".mysql_error());
As an aside, if $sID is just an integer (and not subject to injection attacks), you could probably remove the quotes from around it. I don't think it matters with MySQL (due to its "everything is a string" nature) but your query won't be portable to other DBMS'.
It depends on the values you have in your variables
Depending on the data type here is what you can do
$requirements2 = mysql_real_escape_string($requirements2); // escape string
$sID = (int)$sID; // force integer
the problem is if you have a string in your $requirement and it contains a single quote ' it will break your sql statement.
Here is something i often do to organize my code.
$sql = "UPDATE Scholarships2 SET Requirements2 = '%s'
WHERE scholarshipID =%d";
$sql = sprintf($sql,
mysql_real_escape_string($requirements2),
(int)$sID
);
Are you just taking form fields in from a POST or AJAX query? It sounds like you have a string containing 's website.
Make sure you run your code though mysqli_escape_string.
You need to escape whatever input you are getting in $requirements2
You can do this by
$req2=mysql_real_escape_string($requirements2);
mysql_query("UPDATE Scholarships2 SET Requirements2 = '$req2'
WHERE scholarshipID = '$sID'")
or die("Insert Error1: ".mysql_error());
This will escape any special characters like the apostrophe found in $requirements2
The problem is that your $requirements2 variable contains a single quote (the error message shows it when it says near 's website - presumably you're inserting something like welcome to Sal's website). When MySQL encounters this character, it's interpreting it as the termination of the entire string.
For example, if you substituted the phrase Welcome to Sal's website into your query where $requirements2 currently is, your query would look like this:
UPDATE Scholarships2 SET Requirements2 = 'Welcome to Sal's website'
As you can see, this results in a quoted string Welcome to Sal with the rest of the string hanging off the end not a part of anything. That's the part that the error is complaining about.
You really need to switch to PDO and prepared statements, otherwise you're leaving yourself wide open to these types of errors, including SQL injection which is a Very Bad Thing.
Prepared statements allow you to specify queries with placeholders where dynamic data can be placed. This extra data is then passed to PDO in a separate function where PDO/the database can determine the best way to sanitize it so that it doesn't get misinterpreted as part of the query structure itself.
So using %27 you can just SQL inject even though data is sanitized with mysql_real_escape_string
%27) SQL INJECTION HERE %2F*
What to do?
Edit with example:
$sql = sprintf("SELECT *, MATCH(post) AGAINST ('%s*' IN BOOLEAN MODE) AS score FROM Posts WHERE MATCH(post) AGAINST('%s*' IN BOOLEAN MODE)",
mysql_real_escape_string($_GET['searchterm']),
mysql_real_escape_string($_GET['searchterm']));
$results = $db->queryAsArray($sql);
If you pass in %27) SQL INJECTION HERE %2F* to the searchterm querystring, I get outputted on the page:
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 'BOOLEAN
MODE)' at line 1
Thanks everyone for finding the problem in the db class..
Reasoning from the method name queryAsArray, it seems that you’re using this DbBase class from the comments of the MySQL functions manual page. If so, it’s the query method that removes the escape character from the escaped quotation marks:
function query($sql, &$records = null){
$sql = str_replace(array('\\"', "\\'"), array('"', "'"), $sql);
// …
}
Then it’s not a miracle that your example works (I simplified it):
$input = "', BAD SQL INJECTION --";
$sql = "SELECT '".mysql_real_escape_string($input)."'";
var_dump($sql); // string(33) "SELECT '\', BAD SQL INJECTION --'"
// everything’s OK ↑
$sql = str_replace(array('\\"', "\\'"), array('"', "'"), $sql);
var_dump($sql); // string(32) "SELECT '', BAD SQL INJECTION --'"
// Oops! ↑
The note mentioned in our manual has been marked for deletion. Once it propagates across all of the mirrors in our network, it will no longer appear attached to the official documentation.
~ Daniel P. Brown
Network Infrastructure Manager
http://php.net/
It's best to not to build statements like this at all, and instead use queries with parameters using mysqli or PDO. This will deal with the problem of MySQL injection and one day (not yet, unfortunately) it will perform better too, because the queries are cached without parameters, meaning you only got one query in the cache instead of dozens of different queries because of a single input value changing all the time. Other databases make use of this since long, but MySQL just managed not to make parameterized queries slower since the latest version.
It doesn't look plausible that %27 will actually terminate the string. It seems more like a possibility to embed quotes inside a string, but I'm not sure.
To be sure, I decided to sacrificed my server and test this. When I enter %27 in an input field and textarea that are escaped using mysql_real_escape_string and are then inserted in the database, I get no errors. The text %27 is just inserted. So no problem at all.
You are wrong. No injection possible here.
By following these three simple rules
Client's encoding properly set by mysql_set_charset()
Data being escaped using mysql_real_escape_string()
And enclosed in quotes
you can be sure that no injection possible
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.
Good Morning everyone,
I am using an update command in php to update data in mysql. This is my code:
$sql=mysql_query("UPDATE blpublication SET JournalName = '$_POST[journal]', AcceptanceDate = '$_POST[acceptancedate]', PublishedDate = '$_POST[publisheddate]', Comment = '$_POST[comment]'
WHERE JobNo = '$_POST[jobno]'");
if (!mysql_query($sql,$con))
{
die('Error: ' . mysql_error());
}
echo "record Updated";
It does updates the field but, it gives me the following error. And i can not figure it out why am i getting this error.
"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 '1' at line 1"
Can you help me in this
Best
Zeeshan
Can you tell us what the exactly output of $sql is? By the way, BIG security hole there. You should always escape query inputs namely:
$journal = mysql_real_escape_string($_POST['journal']);
$acceptance_date = mysql_real_escape_string($_POST['acceptancedate']);
$publish_date = mysql_real_escape_string($_POST['publisheddate']);
$comment = mysql_real_escape_string($_POST['comment']);
$job_no = intval($_POST['jobno']); // assuming jobNo is a number
$sql = <<<END
UPDATE blpublication
SET JournalName = '$journal',
AcceptanceDate = '$acceptance_date',
PublishedDate = '$publish_date',
Comment = '$comment'
WHERE JobNo = $jobno
END;
mysql_query($sql);
if (mysql_error()) {
die("Error executing query '$sql': " . mysql_error());
}
echo "record Updated";
I would sanitize your input first. This could lead to some very nasty errors such as what you are experincing and malicious attacks. Look up SQL Injection.
I think the problem is that you're running mysql_query twice. The first time it works and returns 1 (true), which you assign to $sql. Then you call mysql_query again, passing $sql (which equals 1). Of course "1" is not a valid SQL query, so you get the syntax error.
I wholeheartedly agree that you must sanitize those inputs!
Similar to the following post, i believe when you have any object or array syntax, you need to put in braces.
SET JournalName = '${_POST[journal]}'
edit: and yes, as others pointed out you are risking sql injection.
First of all, your code is prone to SQL injection, escape your POST values:
$journal = mysql_real_escape_string($_POST['journal']);
And to actually debug your query, we need the query itself. Add an echo() statement before the actual execution of the query and post the result, the POST values possibly contain some unexpected value.
Your general UPDATE syntax looks ok, except for the obvious injection possibilities, but you need to output $sql. One of your variables probably has a quote in it or some other issue like that....
Looking at the SQL UPDATE statement in your code, one thing leaps out at me. The table name is blpublication, are you maybe missing a 't', i.e. tblpublication?
Also you should really sanitise your input, otherwise you're going to be a victim of a SQL injection attack.
Try concatenating the $_POST values. Im not sure if including them without quoting the key is possible?
$sql= mysql_real_escape_string("UPDATE blpublication SET JournalName = '".$_POST['journal']."', AcceptanceDate = '".$_POST['acceptancedate']."', PublishedDate = '".$_POST['publisheddate']."', Comment = '".$_POST['comment']."'
WHERE JobNo = '".$_POST['jobno']."'");
$result = mysql_query($sql);
Note: mysql_* commands are depreciated. You should switch over to mysqli_*.