Here is the mysql insert the I am running in php. I have removed the part giving the error but then I get a error on the next piece. I am not seeing what is diffrent to cause the error.
$fields="adv_exchange SET synum='".$synum."', worknum='".$_POST['worknum']."', user_id='".$current_user->ID."', f_name='".$current_user->user_firstname."', l_name='".$current_user->user_lastname."', email='".$current_user->user_email."', regnum=".$_POST['regnum'].", item='".$item."', qsver='".$_POST['qsver']."', flashrom='".$_POST['flashrom']."',expansion='".$_POST['board']."', rdisplay='". $_POST['rdisplay']."', screen_model='".$_POST['screen_model']."', p_hardware='".$_POST['cable']."', pcolor='".$_POST['pcolor']."', pname='".$_POST['pname']."', kboard='".$_POST['kboard']."', ip='".$_POST['ip']."', reg_name='".$_POST['reg_name']."', mem=".$_POST['mem'].", dt_server='".$_POST['dt_server']."', alert='".$_POST['alert']."', ows='".$_POST['ows']."', w_date='".$_POST['w_date']."', flashromver='".$_POST['flashromver']."', s_size='".$_POST['s_size']."', mag='".$_POST['mag']."', rcard='".$_POST['rcard']."', kvsid=".$_POST['kvsid'].", finger='".$_POST['finger']."', stand_alone='".$_POST['stand_alone']."', standards='".$_POST['standards']."', profile='".$_POST['profile']."', man_date='".$_POST['man_date']."', l_sn='".$_POST['l_sn']."', misc='".$_POST['misc']."', problem='".$_POST['problem']."'";
then $query = "insert into $fields";
I receive back
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 ' item='JS900CV', qsver='', flashrom='',expansion='', rdisplay='', screen_model='' at line 1
Blockquote
if I echo the $query I get this:
insert into adv_exchange SET synum='SY5135', worknum='123456', user_id='2', f_name='REMOVED', l_name='REMOVED', email='REMOVED', regnum=, item='JS900CV', qsver='', flashrom='',expansion='', rdisplay='', screen_model='', p_hardware='', pcolor='', pname='', kboard='', ip='192.168.1.16', reg_name='', mem=, dt_server='', alert='', ows='', w_date='', flashromver='', s_size='', mag='', rcard='', kvsid=3, finger='', stand_alone='', standards='', profile='', man_date='', l_sn='', misc='misc test\r\n', problem='gen test'
Depending on what I enter in the error is changing spots in my statement. Not all fields are used the form is dynamic that is supplying the data so the fields are dependent on what options are selected. On a side note in case of concern about using $_POST to insert directly into mysql, I sanitize the array first. Any help would be greatly appreciated.
Look at regnum=,. You don't provide a value for regnum. Either leave it out entirely or set it to an appropriate value.
You're using a very, very bad approach to MySQL databases: manually creating the queries. You should really use prepared statements instead: this issue will be resolved as well.
Don't use mysql_* functions, use PDO instead.
Your code would look like this (simplified):
// This holds the query
$statement = $pdo->prepare('INSERT INTO adv_exchange SET synum=?, worknum=?, etc=?, problem=?');
// This executes it with the given arguments. It's 100% injection-proof and safe. In fact, it's also faster.
$statement->execute(array($synum, $_POST['worknum'], $_POST['therest'], $_POST['problem']));
regnum=".$_POST['regnum']." is causing the problem. When it is undefined, you get regnum=, in the SQL query
A bigger concern is that you are not escaping your inputs. Either use mysql_real_escape_string around them, or better, use prepared statements.
You need to SET regnum=SOMETHING.
Currently it's empty.
Related
I'm having a problem when trying to add a URL to a mySQL database.
The string is a URL:
http://pbs.twimg.com/profile_images/1708867059/405000_10150426314376065_707061064_8645107_703731598_n_normal.jpg
The error I get is:
Error description: 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 '://pbs.twimg.com/profile_images/1708867059/405000_10150426314376065_707061064_86' at line 1
It seems as though it won't allow me to add a URL, I presume there is something wrong with some of the characters but I don't know what?
My SQL is:
INSERT INTO accounts (name,consumerkey,consumersecret,pic_url) VALUES ($twitterID,$consumerkey,$consumersecret,$picture_url)"
You cannot truly solve this kind of problem by adding a few characters (like ' or ") to your bespoke sql string!
Instead, get to know the real way to write sql in php (it's like a very badly kept secret), which is to use PDO statements. This will allow you to use placehoders like (:twitterID, :consumerKey, :consumerSecret, :pictureUrl) which will accept complex variables such as urls and any of the crap users send in much more gracefully.
In the long run, this will save you a lot of trouble and time.
You need to quote string values and any other character that SQL will complain about, in this case it's the colon; see further down below.
($twitterID,$consumerkey,$consumersecret,'$picture_url')
or
('".$twitterID."','".$consumerkey."','".$consumersecret."','".$picture_url."')
if you wish to quote all the values.
Sidenote: You can remove the quotes around the variables that are integers.
I.e.:
This based on, and without seeing how the rest of your code looks like:
$picture_url = "http://pbs.twimg.com/profile_images/1708867059/405000_10150426314376065_707061064_8645107_703731598_n_normal.jpg";
The error states that it is near : - near being just that, the colon.
...right syntax to use near '://pbs.twimg.com
^ right there
You can also use:
VALUES ($twitterID, $consumerkey, $consumersecret, '" .$dbcon->real_escape_string($picture_url) . "')";
$dbcon is an example of a DB connection variable and based on mysqli_ syntax.
Something you haven't stated as to which MySQL API you are using.
Plus, your present code is open to SQL injection.
Use prepared statements, or PDO with prepared statements.
This question already has answers here:
Getting raw SQL query string from PDO prepared statements
(16 answers)
Closed 6 years ago.
In PHP, when accessing MySQL database with PDO with parametrized query, how can you check the final query (after having replaced all tokens)?
Is there a way to check what gets really executed by the database?
So I think I'll finally answer my own question in order to have a full solution for the record. But have to thank Ben James and Kailash Badu which provided the clues for this.
Short Answer
As mentioned by Ben James: NO.
The full SQL query does not exist on the PHP side, because the query-with-tokens and the parameters are sent separately to the database.
Only on the database side the full query exists.
Even trying to create a function to replace tokens on the PHP side would not guarantee the replacement process is the same as the SQL one (tricky stuff like token-type, bindValue vs bindParam, ...)
Workaround
This is where I elaborate on Kailash Badu's answer.
By logging all SQL queries, we can see what is really run on the server.
With mySQL, this can be done by updating the my.cnf (or my.ini in my case with Wamp server), and adding a line like:
log=[REPLACE_BY_PATH]/[REPLACE_BY_FILE_NAME]
Just do not run this in production!!!
You might be able to use PDOStatement->debugDumpParams. See the PHP documentation .
Using prepared statements with parametrised values is not simply another way to dynamically create a string of SQL. You create a prepared statement at the database, and then send the parameter values alone.
So what is probably sent to the database will be a PREPARE ..., then SET ... and finally EXECUTE ....
You won't be able to get some SQL string like SELECT * FROM ..., even if it would produce equivalent results, because no such query was ever actually sent to the database.
I check Query Log to see the exact query that was executed as prepared statement.
I initially avoided turning on logging to monitor PDO because I thought that it would be a hassle but it is not hard at all. You don't need to reboot MySQL (after 5.1.9):
Execute this SQL in phpMyAdmin or any other environment where you may have high db privileges:
SET GLOBAL general_log = 'ON';
In a terminal, tail your log file. Mine was here:
>sudo tail -f /usr/local/mysql/data/myMacComputerName.log
You can search for your mysql files with this terminal command:
>ps auxww|grep [m]ysqld
I found that PDO escapes everything, so you can't write
$dynamicField = 'userName';
$sql = "SELECT * FROM `example` WHERE `:field` = :value";
$this->statement = $this->db->prepare($sql);
$this->statement->bindValue(':field', $dynamicField);
$this->statement->bindValue(':value', 'mick');
$this->statement->execute();
Because it creates:
SELECT * FROM `example` WHERE `'userName'` = 'mick' ;
Which did not create an error, just an empty result. Instead I needed to use
$sql = "SELECT * FROM `example` WHERE `$dynamicField` = :value";
to get
SELECT * FROM `example` WHERE `userName` = 'mick' ;
When you are done execute:
SET GLOBAL general_log = 'OFF';
or else your logs will get huge.
What I did to print that actual query is a bit complicated but it works :)
In method that assigns variables to my statement I have another variable that looks a bit like this:
$this->fullStmt = str_replace($column, '\'' . str_replace('\'', '\\\'', $param) . '\'', $this->fullStmt);
Where:
$column is my token
$param is the actual value being assigned to token
$this->fullStmt is my print only statement with replaced tokens
What it does is a simply replace tokens with values when the real PDO assignment happens.
I hope I did not confuse you and at least pointed you in right direction.
The easiest way it can be done is by reading mysql execution log file and you can do that in runtime.
There is a nice explanation here:
How to show the last queries executed on MySQL?
I don't believe you can, though I hope that someone will prove me wrong.
I know you can print the query and its toString method will show you the sql without the replacements. That can be handy if you're building complex query strings, but it doesn't give you the full query with values.
I think easiest way to see final query text when you use pdo is to make special error and look error message. I don't know how to do that, but when i make sql error in yii framework that use pdo i could see query text
I have no idea about PHP security, but if I add an ' to the input in my POST method form.
I'm getting the following message:
Warning: mysql_fetch_object(): supplied argument is not a valid MySQL result resource in /usr/local/www/login.php
Is that a SQL injection? If so, how it can be abused by the "hackers" ?
That means you're vulnerable to SQL injection, and your code is not doing sufficient checking for errors.
An absolute barebones "safe" bit of code would be:
<?php
... connect to db ...
$stringval = mysql_real_escape_string($_GET['param']);
$sql = "SELECT somefield FROM sometable WHERE otherfield='$stringval'";
$result = mysql_query($sql) or die(mysql_error());
better yet is to stop using the mysql functions and switch to PDO and parameterized queries. They handle the injection problems for you automatically.
The root cause of your error message is that your query has caused a syntax error. When a query fails outright like that, mysql_query() returns a boolean FALSE value, not a statement handle.
Since you lack any kind of error checking, you blindly took that boolean false and passed it on to the fetch function, which has rightfully complained that you didn't provide a result handle.
You should escape any user input before passing it to mysql. Use the PHP function mysql_real_escape_string() to escape any user input before adding it to your query. Here is the link to PHP manual for mysql_real_escape_string()
Update: Yes, what others are saying about using prepared statements or mysqli is much better that using the mysql extension.
Here are a few links on MySQL Injection which I found:
http://www.php.net/manual/en/security.database.sql-injection.php
http://25yearsofprogramming.com/blog/2011/20110205.htm
https://www.owasp.org/index.php/SQL_Injection_Prevention_Cheat_Sheet
This question already has answers here:
Getting raw SQL query string from PDO prepared statements
(16 answers)
Closed 6 years ago.
In PHP, when accessing MySQL database with PDO with parametrized query, how can you check the final query (after having replaced all tokens)?
Is there a way to check what gets really executed by the database?
So I think I'll finally answer my own question in order to have a full solution for the record. But have to thank Ben James and Kailash Badu which provided the clues for this.
Short Answer
As mentioned by Ben James: NO.
The full SQL query does not exist on the PHP side, because the query-with-tokens and the parameters are sent separately to the database.
Only on the database side the full query exists.
Even trying to create a function to replace tokens on the PHP side would not guarantee the replacement process is the same as the SQL one (tricky stuff like token-type, bindValue vs bindParam, ...)
Workaround
This is where I elaborate on Kailash Badu's answer.
By logging all SQL queries, we can see what is really run on the server.
With mySQL, this can be done by updating the my.cnf (or my.ini in my case with Wamp server), and adding a line like:
log=[REPLACE_BY_PATH]/[REPLACE_BY_FILE_NAME]
Just do not run this in production!!!
You might be able to use PDOStatement->debugDumpParams. See the PHP documentation .
Using prepared statements with parametrised values is not simply another way to dynamically create a string of SQL. You create a prepared statement at the database, and then send the parameter values alone.
So what is probably sent to the database will be a PREPARE ..., then SET ... and finally EXECUTE ....
You won't be able to get some SQL string like SELECT * FROM ..., even if it would produce equivalent results, because no such query was ever actually sent to the database.
I check Query Log to see the exact query that was executed as prepared statement.
I initially avoided turning on logging to monitor PDO because I thought that it would be a hassle but it is not hard at all. You don't need to reboot MySQL (after 5.1.9):
Execute this SQL in phpMyAdmin or any other environment where you may have high db privileges:
SET GLOBAL general_log = 'ON';
In a terminal, tail your log file. Mine was here:
>sudo tail -f /usr/local/mysql/data/myMacComputerName.log
You can search for your mysql files with this terminal command:
>ps auxww|grep [m]ysqld
I found that PDO escapes everything, so you can't write
$dynamicField = 'userName';
$sql = "SELECT * FROM `example` WHERE `:field` = :value";
$this->statement = $this->db->prepare($sql);
$this->statement->bindValue(':field', $dynamicField);
$this->statement->bindValue(':value', 'mick');
$this->statement->execute();
Because it creates:
SELECT * FROM `example` WHERE `'userName'` = 'mick' ;
Which did not create an error, just an empty result. Instead I needed to use
$sql = "SELECT * FROM `example` WHERE `$dynamicField` = :value";
to get
SELECT * FROM `example` WHERE `userName` = 'mick' ;
When you are done execute:
SET GLOBAL general_log = 'OFF';
or else your logs will get huge.
What I did to print that actual query is a bit complicated but it works :)
In method that assigns variables to my statement I have another variable that looks a bit like this:
$this->fullStmt = str_replace($column, '\'' . str_replace('\'', '\\\'', $param) . '\'', $this->fullStmt);
Where:
$column is my token
$param is the actual value being assigned to token
$this->fullStmt is my print only statement with replaced tokens
What it does is a simply replace tokens with values when the real PDO assignment happens.
I hope I did not confuse you and at least pointed you in right direction.
The easiest way it can be done is by reading mysql execution log file and you can do that in runtime.
There is a nice explanation here:
How to show the last queries executed on MySQL?
I don't believe you can, though I hope that someone will prove me wrong.
I know you can print the query and its toString method will show you the sql without the replacements. That can be handy if you're building complex query strings, but it doesn't give you the full query with values.
I think easiest way to see final query text when you use pdo is to make special error and look error message. I don't know how to do that, but when i make sql error in yii framework that use pdo i could see query text
This question already has answers here:
Getting raw SQL query string from PDO prepared statements
(16 answers)
Closed 6 years ago.
In PHP, when accessing MySQL database with PDO with parametrized query, how can you check the final query (after having replaced all tokens)?
Is there a way to check what gets really executed by the database?
So I think I'll finally answer my own question in order to have a full solution for the record. But have to thank Ben James and Kailash Badu which provided the clues for this.
Short Answer
As mentioned by Ben James: NO.
The full SQL query does not exist on the PHP side, because the query-with-tokens and the parameters are sent separately to the database.
Only on the database side the full query exists.
Even trying to create a function to replace tokens on the PHP side would not guarantee the replacement process is the same as the SQL one (tricky stuff like token-type, bindValue vs bindParam, ...)
Workaround
This is where I elaborate on Kailash Badu's answer.
By logging all SQL queries, we can see what is really run on the server.
With mySQL, this can be done by updating the my.cnf (or my.ini in my case with Wamp server), and adding a line like:
log=[REPLACE_BY_PATH]/[REPLACE_BY_FILE_NAME]
Just do not run this in production!!!
You might be able to use PDOStatement->debugDumpParams. See the PHP documentation .
Using prepared statements with parametrised values is not simply another way to dynamically create a string of SQL. You create a prepared statement at the database, and then send the parameter values alone.
So what is probably sent to the database will be a PREPARE ..., then SET ... and finally EXECUTE ....
You won't be able to get some SQL string like SELECT * FROM ..., even if it would produce equivalent results, because no such query was ever actually sent to the database.
I check Query Log to see the exact query that was executed as prepared statement.
I initially avoided turning on logging to monitor PDO because I thought that it would be a hassle but it is not hard at all. You don't need to reboot MySQL (after 5.1.9):
Execute this SQL in phpMyAdmin or any other environment where you may have high db privileges:
SET GLOBAL general_log = 'ON';
In a terminal, tail your log file. Mine was here:
>sudo tail -f /usr/local/mysql/data/myMacComputerName.log
You can search for your mysql files with this terminal command:
>ps auxww|grep [m]ysqld
I found that PDO escapes everything, so you can't write
$dynamicField = 'userName';
$sql = "SELECT * FROM `example` WHERE `:field` = :value";
$this->statement = $this->db->prepare($sql);
$this->statement->bindValue(':field', $dynamicField);
$this->statement->bindValue(':value', 'mick');
$this->statement->execute();
Because it creates:
SELECT * FROM `example` WHERE `'userName'` = 'mick' ;
Which did not create an error, just an empty result. Instead I needed to use
$sql = "SELECT * FROM `example` WHERE `$dynamicField` = :value";
to get
SELECT * FROM `example` WHERE `userName` = 'mick' ;
When you are done execute:
SET GLOBAL general_log = 'OFF';
or else your logs will get huge.
What I did to print that actual query is a bit complicated but it works :)
In method that assigns variables to my statement I have another variable that looks a bit like this:
$this->fullStmt = str_replace($column, '\'' . str_replace('\'', '\\\'', $param) . '\'', $this->fullStmt);
Where:
$column is my token
$param is the actual value being assigned to token
$this->fullStmt is my print only statement with replaced tokens
What it does is a simply replace tokens with values when the real PDO assignment happens.
I hope I did not confuse you and at least pointed you in right direction.
The easiest way it can be done is by reading mysql execution log file and you can do that in runtime.
There is a nice explanation here:
How to show the last queries executed on MySQL?
I don't believe you can, though I hope that someone will prove me wrong.
I know you can print the query and its toString method will show you the sql without the replacements. That can be handy if you're building complex query strings, but it doesn't give you the full query with values.
I think easiest way to see final query text when you use pdo is to make special error and look error message. I don't know how to do that, but when i make sql error in yii framework that use pdo i could see query text