I want some real life scenario in programming where we can use this solr util method i.e. SolrUtils::escapeQueryChars().
Now I am using it for escaping query chars from query in solr.
q:+popularity:[10 TO *] +section:0
And I am using
escapeQueryChars(+popularity:[10 TO *] +section:0)
But I am unable to get the result after escaping.
SolrUtils::escapeQueryChars is usually used to escape characters in the Query which have special meaning in Solr.
The current list of characters are + - && || ! ( ) { } [ ] ^ " ~ * ? : \ which have special meaning in Solr and the behaviour would be different if not escaped.
for example if you are searching for 5* unless escaped it would behave as a wildcard search and return results with tokens starting from 5.
It shall be used in query values only.
Most of the time you will be accepting queries from a user. So its essential to escape these characters to avoid exceptions
a user search query can be: "Thomas' Calculus (12th Edition)"
The user query above would certainly lead to unwanted results
$query = new SolrQuery('product_name:'.SolrUtils::escapeQueryChars($userQuery));
Related
I'm trying to update a table called RAC_PV at my oracle database but the query is returning that error when i run my application. I thing everyting is right because i run the same query on sqldeveloper (but with manual values) and when i change the variable $preco_medio to a number like 1, it works on the application. Here's my code:
$preco_medio = number_format(($v_interna_real / $encargo + $vipe_real) / $v_interna_t + $vipe_t , 2, ",", ".") ;
sc_exec_sql("update RAC_PV set PRECO_MEDIO = $preco_medio where rac_anopv = {ano} and rac_mespv = {mes} and codempresa = $id_empresa and codpainel = 6 and cod_prod1 = '$id_produto'");
My table name and the column names are right and checked, my variables like {ano}, {mes}, $id_produto and $preco_medio are all corretly seted. This sc_exec_sql("query here") works fine. Maybe the problem is in the $preco_medio ? I've never used that number_format but when a echo this the number shows right for me like 3,123.03 .
Can anyone help me?
3,123.03
That's not a number literal, that's two numbers, 3 and 123.03, one of which is apparently interpreted as column name. Remove the grouping , in the number literal expression or use TO_NUMBER() and a string literal with the formatted number representation.
The best way however would be not to build queries by string concatenation but parametrized queries. String concatenation is prone to SQL Injection. Also parametrized queries find the right representation for the DBMS (usually and mostly) automatically, avoiding such problems you have here.
With this issue, I would really like to avoid modifying the core files if possible, so a workaround would be extremely helpful.
REGEX works with the 'where' query builder class easy enough, but using the word boundaries breaks it by adding an extra space.
function search($searchQuery){
$sq = '[[:<:]]'.strtolower($searchQuery).'[[:>:]]';
$this->db->select('column');
$this->db->from('table');
$this->db->where('LOWER(otherColumn) REGEXP', $sq);
echo $this->db->get_compiled_select();
}
search('billy');
Expected result:
SELECT column FROM table WHERE LOWER(otherColumn) REGEXP
'[[:<:]]billy[[:>:]]';
Actual result:
SELECT column FROM table WHERE LOWER(otherColumn) REGEXP
[[: < :]]billy[[:>:]]';
This is such a specific issue with a specific stack and I haven't found anybody running into the same issue. I've tried escaping the colons, the <'s, the square brackets, nothing seems to work. Or it adds additional backslashes.
Really any help or direction would be helpful at this point.
Thanks in advance.
function search($searchQuery){
$sq = $this->db->escape('[[:<:]]'.strtolower($searchQuery).'[[:>:]]');
$this->db->select('column');
$this->db->from('table');
$this->db->where('LOWER(otherColumn) REGEXP ', $sq, false);
echo $this->db->get_compiled_select();
}
search('billy');
For Codeigniter v 3.1.6 and MySQL v5.6
Just because Codeigniter adds space before and after < when compiling the query, I do not know why but it does. And I have escaped the value for variable $sq to mitigate injection Attack or identical. Hence, added third parameter to where function as false to prevent it from re-escaping and adding spaces.
I have not gone through other versions of codeigniter. I hope this will work.
For more information on MySQL REGEXP visit this link: MySQL 5.6 Reference Manual - Regular Expressions
i am using mysqlclient,
in one of my query, as shown below
sprintf (query, "select user from pcloud_session where id = '%s'", sid);
here some time this sid is with % sign in it like the example
2Cq%yo4i-ZrizGGQGQ71eJQ0
but when there is this % this query always fail, i think i have to escape this %, but how ?
i tried with \ and %% , but both of this not working, please help me here
UPDATE:
When using session.hash_bits_per_character = 6, in php session ,the default charset contains a character (comma) that will always be urlencoded(here it is %2C). This results in cookie values having this %2C in it, but session db having a comma instead of it. any idea about fixing this problem ?.. sorry for the confusion
Thanks
There's no need to escape a literal '%' in MySQL query text.
When you say the query "always fail", is it the call to the mysql_query function that is returning an error? Does it return a SQL Exception code, or is it just not returning the resultset (row) you expect?
For debugging, I suggest you echo out the contents of the query string, after the call to sprintf. We'd expect the contents of the string to be:
select user from pcloud_session where id = '2Cq%yo4i-ZrizGGQGQ71eJQ0'
And I don't see anything wrong with that SQL construct (assuming the id column exists in pcloud_session and is of character datatype. Even if id was defined as an integer type, that statement wouldn't normally throw an exception, the string literal would just be interpreted as integer value of 2.)
There should be no problem including a '%' literal into the target format of an sprintf. And there should be no problem including a '%' literal within MySQL query text.
(I'm assuming, of course, that sid is populated by a call to mysql_real_escape_string function.)
Again, I suggest you echo out the contents of query, following the call to sprintf. I also suggest you ensure that no other code is mucking with the contents of that string, and that is the actual string being passed as an argument to mysql_query function. (If you are using the mysql_real_query function, then make sure you are passing the correct length.)
UPDATE
Oxi said: "It does not return a SQL Exception code, it just does not return the result[set] I expect. I did print the query, it prints with % in it."
#Oxi
Here's a whole bunch of questions that might help you track down the problem.
Have you run a test of that query text from the mysql command line client, and does that return the row(s) you expect?
Is that id column defined as VARCHAR (or CHAR) with a length of (at least) 24 characters? Is the collation on the column set as case insensitive, or is it case sensitive?
show create table pcloud_session ;
(I don't see any characters in there that would cause a problem with characterset translation, although that could be a source of a problem, if your application is not matching the database charactarset encoding.)
Have you tested queries using a LIKE predicate against that id column?
SELECT id, user FROM pcloud_session WHERE id LIKE '2Cq\%yo4i-%' ESCAPE '\\'
ORDER BY id LIMIT 10 ;
SELECT id, user FROM pcloud_session WHERE id LIKE '2Cq%'
ORDER BY id LIMIT 10 ;
Are you getting no rows returned when you expect one row? Are you getting too many rows returned, or are you getting a different row than the one you expect?
That is an oddball value for an id column. At first, it looks almost as if the value is represented in a base-64 encoding, but it's not any standard encoding, since it includes the '%' and the '-' characters.
If you're going to do this in C without an interface library, you must use mysql_real_escape_string to do proper SQL escaping.
There shouldn't be anything intrinsically wrong with using '%inside of a string, though, as the only context in which it has meaning is either directly inprintftype functions or as an argument toLIKE` inside of MySQL.
This proves to be really annoying, but it's absolutely necessary. It's going to make your code a lot more complicated which is why using low-level MySQL in C is usually a bad idea. The C++ wrapper will give you a lot more support.
You really shouldn't escape the string yourself. The safest option is to let the MySQL API handle it for you.
For a string of maximum length n, start by allocating a string of length 2*n+1:
int sidLength = strlen(sid);
// worst-case, we need to escape every character, plus a byte for the ASCIIZ
int maxSafeSidLength = sidLength * 2 + 1;
char *safeSid = malloc(maxSafeSidLength);
// copy "sid" to "safeSid", escaping as appropriate
mysql_real_escape_string(mysql, safeSid, sid, sidLength);
// build the query
// ...
free(safeSid);
There's a longer example at the mysql_real_escape_string page on dev.mysql.com, in which they build the entire query string, but the above approach should work for supplying safeSid to sprintf.
For a search feature I wrote a MySQL query to be executed by a PHP script. I'm not doing a fulltext search. Instead, I'm doing a search using the following method:
... WHERE field LIKE '%etc%' AND field REGEXP '[[:<:]]etc[[:>:]]'
Now, my idea is to prepare these dynamic values in PHP, like:
$word = '2*3%5_1^0'; // just an example
$wordLike = strtr($word,array('\\'=>'\\\\','%'=>'\\%','_'=>'\\_'));
// instead of my old solution:
// $wordLike = preg_replace('~([%_])~', '\\\\$1', $word);
$wordLike = $db_con->escape('%' . $wordLike . '%');
$spaces = '[[:blank:]]|[[:punct:]]|[[:space:]]';
// I'm not sure about the difference between blank & space, though
$wordRX = preg_quote($word);
$wordRX = $db_con->escape('(^|'.$spaces.')'.$wordRX.'($|'.$spaces.')');
// instead of my old solution:
// $wordRX = $db_con->escape('[[:<:]]' . $wordRX . '[[:>:]]');
and then use these values like in…
... WHERE field LIKE '$wordLike' AND field REGEXP '$wordRX'
which, with this example input, results in
...
WHERE field LIKE '%2*3\\%5\\_1^0%' AND
field REGEXP '[[:<:]]2\\*3%5_1\\^0[[:>:]]`
A couple of notes…
In my actual code I'm making it handle multiple words, this is just the pseudo code.
The method I'm using to search the word(s) -with LIKE & REGEXP together- was the fastest one among the approaches I tried.
I know I should use PDO instead, please don't input anything about that unless it's relevant to my issue
Q1: Is this the right way to go?
Q2: Is this secure enough against SQL injections?
Some additional info
About MySQL REGEXP…
Following characters are escaped by preg_quote()
. \ + * ? [ ^ ] $ ( ) { } = ! < > | : -
Following is the list of [occasionally] special characters in REGEXP
. \ + * ? [ ^ ] $ ( ) { } | -
There are also additional constructs in REGEXP but they're all surrounded by single/double brackets, and because I know all the brackets will be escaped by preg_quote() I feel like I shouldn't be concerned about them.
About MySQL LIKE…
The only 2 special characters in LIKE are
_ %
So escaping them seems enough a workaround.
Please correct me if I'm missing anything.
Appart from what you mention mysql_real_escape_string() function should do fine for sanitization against SQL injection.
You just have to properly escape whatever user input using the appropiate escaping function(s), if you picture it as chained processing blocks processing this user input you will know in which order (from last to first) and what to escape/unescape and when, and you should be okay as far as securing a clean input goes (validation is a different issue).
And, as you already seem to know, quote() on PDO or Mysqli prepare() are a better approach.
try this use mysql_real_escape_string()
$word = '2*3%5_1^0';
$query = 'SELECT * FROM TABLE_NAME WHERE field REGEXP "(.*)[[:<:]]'.mysql_real_escape_string($word).'[[:>:]](.*)" ';
function clean($str) {
$str = #trim($str);
if(get_magic_quotes_gpc()) {
$str = stripslashes($str);
}
return mysql_real_escape_string($str);
}
then:
$word = clean($_POST['whatever post']);
then trim word and your good to go. what this php function does is take all literals and turns them into strings so no one can lets say delete your db etc
The user has a search box.
I need to give him flexibility so he ca do a search like client and the sql for this will be
name like '%client%'
The problem is I don't want to give the user the possibility to search with % or _ wildcards.
I know I can escape them .. but is there a function to do this for any wildcard/ or other solution ?
create or replace function escape_like(text)
returns text language sql immutable strict as
$q$
select regexp_replace($1, $$([\\%_])$$, $$\\\1$$, 'g')
$q$;
Try it:
=> select escape_like($$foo%bar\foo__bar$$);
quote_like
----------------------
foo\%bar\\foo\_\_bar
(1 row)
So your query should look similar to:
select * from tablename where columnname like '%' || escape_like(?) || '%';
In MySQL you can do it with PHP:
$text_escaped = addcslashes($text, '%\\_');
I guess the same applies to PostgreSQL, but I remeber reading something on their mailing list that you need to double escape the backward slashes in order for it to work properly, I'm not sure though...
Why don't you use full text search?