SQL reserved word in an $array resulting in Error - mysql

I'm having a problem when I try to insert an array that has a reserved word on it.
It's really wierd I might say, take a look:
$sql="INSERT INTO sites (cat_id, cat_title, cat_parent, title, image, site_name, description) VALUES ('$_POST[cat_id]','$_POST[cat_title]','$_POST[cat_parent]','$title','$image','$site_name','$description')";
The array is comming from a opengraph fetch that I created but it's not important, the question is that sometimes when the array $title, for example, or $image has a reserved word like "use" on it, the sql return the error "Error: You have an error in your SQL syntax; check the manual that corresponds...."
so that's the case:
when the array $title = http://techcrunch.com/2012/08/28/flipboard-hits-20-million-users-3-billion-flips-per-month/ <---- it don't work and I receive the error above.
when the array is $title = http://techcrunch.com/2012/08/27/google-nexus-7-is-now-available-in-france-germany-and-spain/ <---- it works fine!
so I think that probably because theres a 'reserved word' in the array $title sometimes (or any other array that I'm using) that is returning the error... So theres any way that I could protect my arrays from this error?
Thanks! :)
EDIT:
SOLUTION
Ok! I followed the #dystroy and #tadman advice and used PDO instead of the regular mysql connection... I don't know if I'm totally secure against SQL injetion or attacks but it solve my problem with the reserved words. Now I can insert whatever content I have in an $array to the database.
If someone end up here with the same problem, that's what I did (please complain if you guys find any awkwardness):
$dbh = new PDO("mysql:host=MYHOST;dbname=MYDATABASE", "USER", "PASS");
$query = "INSERT INTO sites (cat_id, cat_title, cat_parent, title, image, site_name, description) VALUES (:cat_idpost, :cat_titlepost, :cat_parentpost, :titlepost, :imagepost, :site_namepost, :descriptionpost)";
$stmt = $dbh->prepare($query);
$stmt->bindParam(':cat_idpost', $cat_id);
$stmt->bindParam(':cat_titlepost', $cat_title);
$stmt->bindParam(':cat_parentpost', $cat_parent);
$stmt->bindParam(':titlepost', $titlepost);
$stmt->bindParam(':imagepost', $imagepost);
$stmt->bindParam(':site_namepost', $site_namepost);
$stmt->bindParam(':descriptionpost', $descriptionpost);
$cat_id = $_POST['cat_id'];
$cat_title = $_POST['cat_title'];
$cat_parent = $_POST['cat_parent'];
$titlepost = $title;
$imagepost = $image;
$site_namepost = $site_name;
$descriptionpost = $description;
$stmt->execute();
Thank you guys! :D

Always use prepared statement to insert strings in a database. Never simply concatenate them.
The problem isn't only reserverd words but all kind of errors (or attacks) due to special values or characters. Don't try to escape all this yourself : The database will handle that for you if you use a prepared statement.
Look at those samples based on today's recommended library for PHP/MySQL (PDO) : http://www.php.net/manual/en/pdo.prepared-statements.php

Escape reserved words like title with accents

Related

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 - at line 1

I have this issue here with my code, and cant find where the problem actually is, has anyone had similar issue?
<?php
include("db.php");
if(isset($_POST['submit']))
{
$name=$_POST['namename'];
$job=$_POST['job'];
$message=$_POST['message'];
$insert=mysql_query("insert into commenttable(name,job,message)values('$name','$job','$message')")or die(mysql_error());
header("Location:../home.php");
}
?>
this is running on localhost
Server type: MySQL
Server version: 5.5.42 - Source distribution
forgot to mention that if I post simple comment such a "Hello" it works fine, but when i try to post comment like this
<INPUT TYPE="IMAGE" SRC="javascript:alert('XSS');">
for a attack it wont work and I get the error message.
Im doing this for small attack project, this is why i need to get this to work.
Thanks!
If your code fails when you are trying to insert the text <INPUT TYPE="IMAGE" SRC="javascript:alert('XSS');"> then obviously, what is happening is what Uueerdo suggested in his comment: the single quote right before "XSS" is interpreted by MySQL as the closing single quote of the string, leaving you with a dangling XSS');', which is, of course, a syntax error.
There are two ways to overcome this problem:
Programmatically escape the single quotes. This would be quite tricky if you were to do it by yourself, but there ought to be some library function in PHP for that, so it would look like message = escape_for_sql( message ). (Sorry I am not reproducing the dollar signs, I am allergic.)
Better yet, use a parameterized query, where you construct your query using a "?" in place of each value, signifying a parameter to the query, then you supply the value for each parameter, and then you execute the query. I don't know how this is done in PHP, search for "parameterized query PHP".
To extend #Mike's answer, the correct prepared-statement PHP syntax would be, using the mysql driver:
None. Don't use the mysql driver. It's been deprecated since forever.
Using mysqli:
// You need to define the following $db_* vars elsewhere
$dbh = new mysqli($db_host, $db_user, $db_password, $db_name;)
$query = "INSERT INTO commenttable (name, job, message) VALUES (?, ?, ?)";
$stmt = $dbh->prepare($query);
$stmt->bind_param($name, $job, $message);
$stmt->execute();
// When you're finished...
$stmt->close();
Using PDO:
// Edit the connection string as appropriate for your installation
$dbh = new PDO('mysql:host=mydbhost;dbname=whatever', $db_user, $db_password);
$query = "INSERT INTO commenttable (name, job, message) VALUES (:name, :job, :message)";
$stmt = $dbh->prepare($query);
$params = array(':name' => $name, ':job' => $job, ':message' => $message);
$stmt->execute($params);
// PDO has no explicit close() call.
I leave error handling as an exercise for the reader. Hope that helps.

PHP Registration to MYSQL Database

I have a problem here..
Im currently building a website(blog) where I want people to be able to register. And I want that information to be sent to my MYSQL
This is some of the code:
<?php
$query="INSERT INTO Medlemmar(namn, epost)
VALUES("$_GET[namn]", "$_GET[epost]")";
if (!mysqli_query($mysql_pekare,$query))
{
die("Error: " . mysqli_error($mysql_pekare));
}
echo "Du har lagt till kunden I databasen";
?>
But for some reason i get error on the "VALUES" part.. That im missing a syntax.. WTF am i missing?! Been stuck with this for 1+ hours.. Just had to turn here, usually a quick response! Thanks!
edit: "Parse error: syntax error, unexpected T_VARIABLE"
There are syntax errors all over the place... This needs some work.
<?php
$query = "INSERT INTO Medlemmar(name, epost) VALUES(\"".$_GET['namn']."\", \"".$_GET['epost']."\")";
That should fix the query... You need to learn how to escape \" double quotes so they can be used in the actual query.
try
VALUES ('".$_GET[a]."', '".$_GET[b]."')
or ' and " exchanged.
You are forgetting the single quotation marks around each value
The way you're managing registration is extremely insecure. If you were to set the namn and epost value to a sql query (like SELECT FIRST (username) FROM user_table) then it would execute that as behalf of the original sql query.
if you set username to SELECT FIRST (username) FROM user_table then it would return the first username in the user_table
To avoid this from happening you can use prepared statements which means that you specifically assign a sql query with a placeholder value and then you apply a value to the placeholder.
This would mean that you force the sql query to only execute what you've told it to do.
E.g. You want to JUST INSERT into a table and only do that and nothing else, no SELECT and no table DROP well in that case you create the prepared INSERT query with a placeholder value like this.
$db = new PDO('mysql:host=localhost;dbname=database_name', 'database_user', 'database_user_password');
// Create the register statement for inserting.
// Question mark represent a placeholder for a value
$register = $db->prepare('INSERT INTO users_table (username, password) values (?, ?)');
// Execute the register statement and give it values
// The values need to be parsed over in a array
$register->execute(array("test_user", "test_password"));
I'm not the best at explaining but if you want to understand what EXACTLY is going on here then this is a pretty good article which explains it in more detail.

How to insert result of mysql_real_escape_string() into oracle database?

For inserting special characters in data like (,')etc., I am using mysql_real_escape_string() function & it's working fine.
Now I want to use same variable while inserting values in Oracle.
$str = 'N.G.Palace\'s Building',
'xyzcity', '12345678','India','100001',12
Here $str is result of mysql_real_escape_string(). so it escapes special character.
Now my code for oracle is like this-:
$qry ="INSERT INTO Ora_table(ship_to_street, ship_to_city,ship_to_country, ship_to_telephone, order_id, record_no) VALUES(".$str);
So my doubt is Oracle is not accepting values return by mysql_real_escape_string i.e. Palace\'s (like this as this mysql function attach \ before 'single quote)?
So can anybody tell me ho9w can I use that variable $str to insert data into Oracle?
Also I tried like this also-:
"q"."'"."c".$str."c"."'"
can we use this for multiple values like in my case...though still I am unable
to inser data in oracle?
HOW to insert special characters in Oracle db?
like 'SWEET/HOME', 'CROY-BOY' etc. /,-,\ etc.
please tell me..
I strongly urge you not to build queries by appending strings together. This is a ticket straight to hell - or to SQL Injection City, which is one stop earlier. :-) Seriously, though, if you use parameter markers and bind the values to the parameter markers you gain a couple of advantages:
You don't have to escape anything, and
No worries about SQL injection.
Share and enjoy.
From: http://www.php.net/manual/en/function.stripslashes.php#94758
function no_magic_quotes($query) {
$data = explode("\\",$query);
$cleaned = implode("",$data);
return $cleaned;
}
// I'm using mysql_escape_string as a simple example, but this function would work for any escaped string.
$query = "It's amazing! Who's to say this isn't a simple function?";
$badstring = mysql_escape_string($query);
echo '<b>Without function:</b> '.$badstring;
echo '<br><br>';
echo '<b>With function:</b> '.no_magic_quotes($badstring);

Inserting data using PHP into mysql when it contains a '

I am writing lots of info from an XML file into a database.
Everything works fine until I come across a field with the ' in the description, that insertion fails with an error
Error
1064: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 'd like you to feel that way too.
We'd love to have you visit us to view
over 100' at line 3
Is there a way to have this inserted without it failing? the import file could be large and change regularly so I cannot search and replace ' characters within it.
My actual PHP Statement is:
$query = mysql_query("REPLACE into list
(id, name, link, description, cost, date_added,type,myipaq,private,imgurl)
VALUES ('$id','$name','$link',"'$description'",'$cost','$date','$type','$myipaq','$private','$imgurl')");
thanks in advance,
Greg
This falls under the category of SQL injection.
In PHP a function: mysql_real_escape_string is used to encode a string so that none of it can affect the SQL statement it might be concatenated into.
so make sure all of your values go through the mysql_real_escape_string function and you will be fine.
API REF: http://php.net/manual/en/function.mysql-real-escape-string.php
Just pass your data through mysql_real_escape_string()
Use my handy dandy function:
function mysql_safe_string($value) {
if(is_numeric($value)) return $value;
elseif(empty($value)) return 'NULL';
elseif(is_string($value)) return '\''.mysql_real_escape_string($value).'\'';
elseif(is_array($value)) return implode(',',array_map('mysql_safe_string',$value));
}
function mysql_safe_query($format) {
$args = array_slice(func_get_args(),1);
$args = array_map('mysql_safe_string',$args);
$query = vsprintf($format,$args);
$result = mysql_query($query);
if($result === false) echo '<div class="mysql-error"><strong>Error: </strong>',mysql_error(),'<br/><strong>Query: </strong>',$query,'</div>';
return $result;
}
Like so:
mysql_safe_query('INSERT INTO table VALUES (%s, %s, %s)', $val1, $val2, $val3);
And forget about quoting or not quoting your strings, and writing out mysql_real_escape_string a dozen times.
The only really safe way of inserting or replacing or indeed interacting with anything on a database with PHP is to use prepared statements. There really is no excuse anymore for doing it any other way. Escaping strings using mysql_real_escape_string will give you some protection, but it is not bullet proof.
Prepared statements are not even hard. See the PHP manual page on them, and there are several wrappers to make life even easier, personally I like the codesense mysqli wrapper a lot and have been using it for a while with no problems - it's no harder than straight MySQL PHP code. EasyPDO looks promising too.
You should check out the related question "PHP: Is mysql_real_escape_string" sufficient for cleaning user input" for further details as to why you shouldn't be lazy.
Use: php.net/manual/en/function.addslashes.php
Addslashes prevent's just that!
And if you use that, just use
http://www.php.net/manual/en/function.stripslashes.php
to remove slashes from your string!

Why does my INSERT sometimes fail with "no such field"?

I've been using the following snippet in developements for years. Now all of a sudden I get a DB Error: no such field warning
$process = "process";
$create = $connection->query
(
"INSERT INTO summery (process) VALUES($process)"
);
if (DB::isError($create)) die($create->getMessage($create));
but it's fine if I use numerics
$process = "12345";
$create = $connection->query
(
"INSERT INTO summery (process) VALUES($process)"
);
if (DB::isError($create)) die($create->getMessage($create));
or write the value directly into the expression
$create = $connection->query
(
"INSERT INTO summery (process) VALUES('process')"
);
if (DB::isError($create)) die($create->getMessage($create));
I'm really confused ... any suggestions?
It's always better to use prepared queries and parameter placeholders. Like this in Perl DBI:
my $process=1234;
my $ins_process = $dbh->prepare("INSERT INTO summary (process) values(?)");
$ins_process->execute($process);
For best performance, prepare all your often-used queries right after opening the database connection. Many database engines will store them on the server during the session, much like small temporary stored procedures.
Its also very good for security. Writing the value into an insert string yourself means that you must write the correct escape code at each SQL statement. Using a prepare and execute style means that only one place (execute) needs to know about escaping, if escaping is even necessary.
Ditto what Zan Lynx said about placeholders. But you may still be wondering why your code failed.
It appears that you forgot a crucial detail from the previous code that worked for you for years: quotes.
This (tested) code works fine:
my $thing = 'abcde';
my $sth = $dbh->prepare("INSERT INTO table1 (id,field1)
VALUES (3,'$thing')");
$sth->execute;
But this next code (lacking the quotation marks in the VALUES field just as your first example does) produces the error you report because VALUES (3,$thing) resolves to VALUES (3,abcde) causing your SQL server to look for a field called abcde and there is no field by that name.
my $thing = 'abcde';
my $sth = $dbh->prepare("INSERT INTO table1 (id,field1)
VALUES (3,$thing)");
$sth->execute;
All of this assumes that your first example is not a direct quote of code that failed as you describe and therefore not what you intended. It resolves to:
"INSERT INTO summery (process) VALUES(process)"
which, as mentioned above causes your SQL server to read the item in the VALUES set as another field name. As given, this actually runs on MySQL without complaint and will fill the field called 'process' with NULL because that's what the field called 'process' contained when MySQL looked there for a value as it created the new record.
I do use this style for quick throw-away hacks involving known, secure data (e.g. a value supplied within the program itself). But for anything involving data that comes from outside the program or that might possibly contain other than [0-9a-zA-Z] it will save you grief to use placeholders.