problem in where clause of mysql query - mysql

Hi
I am generating messahedigest with SHA1 of a file(having extension .eml, as it contains email info)and then storing it to the table named web_de in column messagedigest. Why can't I execute following query in mysql ?? and also not in java...
SELECT slno FROM `webcrawler`.`web_de`
where messagedigest='?Ê'?`®o1F±[øT¤?¿!€' ;
while I could execute query like
SELECT slno FROM `webcrawler`.`web_de`
where messagedigest= ')#Ä€ó…ªã³§°óÚdv~θ`';
Pl note that I am trying to execute that query in mysql workbench 5.2.32 and using mysql 5.1
Can anybody help me out here please ???
Thanks in advance

You have to escape that single quote in the first query:
where messagedigest = '?Ê''?`®o1F±[øT¤?¿!€' ;
Escaping is done by duplicating quotes:
''
(btw: as you see, even the stackoverflow syntax highlighter wasn't able to properly format your string...)
On the other hand, you shouldn't inline values in SQL for various reasons (security, performance). Since you're using Java, use a PreparedStatement instead:
// Prepare a statement with a bind variable : ?
PreparedStatement ps = connection.prepareStatement(
"SELECT slno FROM webcrawler.web_de WHERE messagedigest = ?");
// Bind your string to the first bind variable
ps.setString(1, "?Ê'?`®o1F±[øT¤?¿!€");
// ...
ResultSet rs = ps.executeQuery();

The ' is not being escaped. Replace it with double quotes '' so it reads as:
SELECT slno FROM `webcrawler`.`web_de`
where messagedigest='?Ê''?`®o1F±[øT¤?¿!€';
EDIT: Too slow! :P
You can also escape it by using \' also

the messagedigest value has a quote in it. If you escape the quote it should work, but...
you might be better off encoding the message digest before trying to write it to the database.

Related

Is mysql.format in nodejs MYSQL safe from unescaped input?

I've hear that preparing MySQL queries prevents injection. I'm working with nodejs, so I've found MySql Preparing Queries. According to the documentation,
You can use mysql.format to prepare a query with multiple insertion
points, utilizing the proper escaping for ids and values.
Does that mean that I can put unescaped things in userId and get an escaped mysql request called sql?
The code is:
var sql = "SELECT * FROM ?? WHERE ?? = ?";
var inserts = ['users', 'id', userId];
sql = mysql.format(sql, inserts);
It's safe.
Escaping is performed by the sqlstring module, you can take a look at its source code for additional info, it's rather small.
You should always escape your values, either by using the ? placeholders or calling escape directly. However using the placeholders is more recommended because it protects you from scenarios where you might forget to do the manual escaping.

Escaping single quote inside a variable before database update

This might be a very basic question.
I have a variable $name which is input through a form from html page.
Now i have to update value of this $name into the database table using a sql query.
When $name has single quotes in it, the database update fails. Eg. James O'Hara
when it does not have single quotes, the update works fine.
Is there a way to escape this single quote inside a variable before updating the database.?
I dont want to strip the single quote. just want to escape it so the update goes through fine and actual name is updated in the database.
Please let me know. Thanks.
Generally, the best approach to this is to prepare a query and use a placeholder. Then pass the data to the database to populate the prepared query.
An ORM such as DBIx::Class will do this for you automatically.
If you are using DBI directly then you would do something like this:
$sth = $dbh->prepare("SELECT * FROM users WHERE email = ?");
foreach my $email (#emails) {
$sth->execute($email);
$row = $sth->fetchrow_hashref;
[...]
}
Use the provided quoting functions
$dbh->do("
UPDATE `MyTable`
SET `MyField` = ".$dbh->quote($my_value)."
WHERE `id` = ".$dbh->quote($id)."
");
or use placeholders
my $sth = $dbh->prepare("
UPDATE `MyTable`
SET `MyField` = ?
WHERE `id` = ?
");
$sth->execute($my_value, $id);
The latter is prettier, but under some circumstances, the former can be faster (since the DB can optimized the query better knowing the type of the expressions in advance).

placeholder use in perl DBI

I have perl script as following my $tb = 'rajeev';
$query = 'select * from table where name = ?'
$sth = $dbh->prepare($query);
$sth->execute($tb);
Does $tb replaced by rajeev or 'rajeev' when query executes ? means does query executs as select * from table where name = rajeevorselect * from table where name = 'rajeev'
DBI handles all the escaping for you. In the case of a string, it will be 'rajeev'. Calling select * from table where name = rajeev will give you an error.
If you provide a number, it will not add quotation marks because they are not needed.
See the DBI Doc. It also says:
The quote() method should not be used with "Placeholders and Bind Values".
Using placeholders sometimes takes care of the quoting for you, depending on which DBD you are using. In your case the DBD::mysql calls $dbh->quote() as mentioned in the doc:
An alternative approach is
$dbh->do("INSERT INTO foo VALUES (?, ?)", undef, $number, $name);
in which case the quote method is executed automatically.
If you have access to the query log you can check what the queries look like. If you have queries that take a long time you can also open a mysql console and say SHOW FULL PROCESSLIST; to see a list of the running queries. That will also hold the complete SQL statements for you to look at. On Windows you could use HeidiSQL to do it.

I want to Auto add single quotes to my mysql queries

I have couple of mysql queries in perl but some of the values of the where clause contain space between words e.g. the gambia. When my scripts runs with the where clause arguments containing a space it ignore the second word.
I want to know how can I solve this problem i.e. if I type the gambia it should be treated the gambia not the.
If you are using DBI, you can use placeholders to send arbitrary data to database without need to care about escaping. The placeholder is question mark in prepare statement, actual value is given to execute:
use DBI;
$dbh = DBI->connect("DBI:mysql:....",$user,$pass)
or die("Connect error: $DBI::errstr");
my $sth = $dbh->prepare(qq{ SELECT something FROM table WHERE name = ? });
$sth->execute('the gambia');
# fetch data from $sth
$dbh->disconnect();
Edit: If you are composing the query (as you suggested in comments), you can utilize quote method:
my $country = "AND country = " . $dbh->quote('the gambia');
my $sth = $dbh->prepare(qq{ SELECT something FROM table WHERE name = ? $country});
Well, firstly, you should look at using something like DBIx::Class instead of raw SQL in your application.
But if you're stuck with raw SQL, then (assuming that you're, at least, using DBI) you should use bind points in your SQL statements. This will handle all of your quoting problems for you.
$sth = $dbh->prepare('select something from somewhere where country = ?');
$sth->execute('The Gambia');
See the DBI docs for more information about binding.

How to use a variable name in a SQL statement?

I'm using R to call a mySQL statement, where I define the variable outside the statement e.g.
foo = 23;
dbGetQuery(con, "select surname from names WHERE age = '.foo.' ;")
But this returns an empty set, I've googled around and tried'.&foo.' ".foo." '".&&foo."'
and many different combinations, but none of them work, I think this should be a mysql question rather than an R specific problem I'm having, but not sure. Normally variables have $values but not in R.
This should work:
foo = 23;
sqlStatement <- paste("select surname from names WHERE age =",foo,'"',sep="")
dbGetQuery(con, sqlStatement;)
You may want to look at the answers to this question: Can I gracefully include formatted SQL strings in an R script?.
The simplest solution is to use the paste command as Robert suggested.
The accepted answer gives bad advice which leaves your application vulnerable to SQL injection. You should always use bind variables instead of concatenating values directly into your query. Use the dbGetPreparedQUery method as described in this answer: Bind variables in R DBI
Adding the semi-colon at the end of query sometimes creates problem. Try changing your query from:
dbGetQuery(con, "select surname from names WHERE age = '.foo.' ;")
to:
dbGetQuery(con, "select surname from names WHERE age = '.foo.'")
AFAIK the command has to be a string, so you should append the single components. Not being familiar with R I cant help you out HOW to do that. In MS-VBA the string concatenation operator is '&'.