Is This a Bug in MySQL? - php

I am using mysql and php (Laravel) and facing a very strange situation .
I am trying get an encrypted user type and user id and decrypt it . and then find the records for that user id .
my code is like this . i am using Laravel framework .
$key = Config::get('app.key');
$decodedUserIDwithType = base64_decode($encryptedUserIDwithType);
$decryptedUserIDwithType = mcrypt_decrypt(XXXXX , $key, $decodedUserIDwithType, XXXXXX);
$userIDwithType = $decryptedUserIDwithType;
I am expecting the decoded value to be something like this
id#100
so i will explode it by # and find the user id , here it is 100 .
for testing i have changed the encrypted value by manually adding one or two characters . when i decrypt i got something like
id#100������������������������]u甀�+&�fj�W�ZЪS��d��]3�]"
and after i explode this i will get the id as 100���]u甀�+&�fj�W�ZЪS��d��]3�]"
now i select all raws with same id using .
SELECT * FROM table WHERE id=$id
it will select the recordes with id = 100 even the actual id is 100���]u甀�+&�fj�W�ZЪS��d��]3�]"
so weird . the type of the id column is INT may be that is why it is matched .
but from my point of view it is very bad , because my whole logic got incorrect because of this .
I checked this query both in Laravel and raw MySQL Query , the results are the same .
Any Ideas , Thanks in advance .
UPDATE
I understand the point mentioned by Shadow, but how to handle a
scenario like this , from decryption i expect id like 100 , but if i
got something like 1ASASAS, if you cast it to int it will be 1 (this
is just for example) . now the problem is my database has a user id 1
also , so now you can see how much trouble i am in because i will get an
incorrect user , sadly this is related to payment :P . some incorrect
users wallet will be topped up . ha ha .how to handle this

This is not a bug, this is a feature in MySQL described in Type Conversion in Expression Evaluation section of the MySQL manual:
When an operator is used with operands of different types, type conversion occurs to make the operands compatible. Some conversions occur implicitly. For example, MySQL automatically converts numbers to strings as necessary, and vice versa.
When MySQL converts a string to a number, it evaluates the characters starting from the left as long as the characters can be interpreted as part of a number and stops, if it encounters a character that cannot be considered as part of a number. In case of 100���]u甀�+&�fj�W�ZЪS��d��], the first � cannot be interpreted as a part of the number, so MySQL stops after 100. The characters after 100 seem to be some kind of garbage anyway and you should check your php code why it produces that garbage.

Related

PHP - ORA-01747: invalid user.table.column, table.column, or column specification

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.

Inserting symbols in mysql using php

I'm using php and mysql and I have a problem with inserting latitude and longitude values along with the degree, min and sec symbols. that is (°,',") symbols.
I have referred several sites and tried different ways but i just can't solve it.
First i tried copying symbols and concatenating with the 3 user input values.
$latitude=$degree.'°'.$min.'''.$sec.'?'.'N';
Then after executing the insert query,the $latitude variable value is inserted in database, but the symbols are replaced by random characters as shown here.
2˚3ʼ4ˮN (data stored in database)
Then i tried using html character code instead of symbols.
$latitude=$degree.'&deg'.$min.'&#8217'.$sec.'#8221'.'N';
But it doesn't work.It displays the same html characters in databse.
I don't know whether it is a problem with html entities or something.
In my opinion such values should be stored without including its ( DMS : Deg Min Sec ) formatting .
In other words , I might store latitude/longitude ( for example ) as a float value and would apply required formatting when displaying .
Just for example :
You would store a date as 2015-04-23 but might display it as 4th April, 2015 .
You might store an amount as 10.50 but might display it as $10.50 USD .
Coming to latitude/longitude considering 36°19'11.46" N as example , one of these ways might apply to your situation :
Store it as 36.31985 but use required conversion to display it as 36°19'11.46" N .
Store it as 36D19M11.46S N but use required string manipulation to display it as 36°19'11.46" N .
Store it as four parts lat_deg , lat_min , lat_sec , lat_dir but use concatenation to display it as 36°19'11.46" N .
Links that might help :
mysql-convert-degree-minutes-seconds-to-degree-decimal
latitude-and-longitude-datatype-and-storage-format
convert-dd-to-dms-in-mysql
converting-latitude-and-longitude-coordinates-between-decimal-and-degrees-minutes-seconds
whats-the-best-way-to-store-co-ordinates-longitude-latitude-from-google-maps
Try this function:
$result = mysqli_real_escape_string();
refer following link
http://php.net/manual/en/mysqli.real-escape-string.php

How to Handle (Escape) a % sign in mysqlclient (C Library)

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.

AES en-and decrypt PHP MySQL

Well, I definitively rightly chose my nick, as I am baffled over this:
First I encrypt it, and I get an encrypted row in my table. But when I try to decrypt it, I get zero rows as the result set.
Encrypting:
INSERT INTO accesobases (company, username,email) VALUES
('hola',
AES_ENCRYPT('pedro','capullo'),
AES_ENCRYPT('myemail',' capullo')
);
and when I run the decryption query, 0 rows show up.
SELECT company,
AES_DECRYPT('username', 'capullo'),
AES_DECRYPT('email', 'capullo')
from acceso
where company = 'hola';
Note that I did not encrypt company, but I will definitively need to, but I wanted to see where the error it could be. That is, not even departing from a non encrypted word (company = hola) I get any results. So, it will be even worse when I try to do as:
where AES_DECRYPT ('company', 'capullo') = ' " . $company . " '
which is how it would look like on my php pages. The above block was being run on the MySQL database itself.
So, the questions are two:
What is wrong with not showing any data
Whether the version of ..."$company.." will work.
However, if I say:
SELECT * from acceso
WHERE company = 'hola';
then, it does show the row with encrypted words
So, it is as if it did not have the time to decrypt the row before showing it and then shows nothing
SELECT company,
AES_DECRYPT('username', 'capullo'),
AES_DECRYPT('email', 'capullo')
from acceso
where company = 'hola';
This won't work because you're telling MySQL to decrypt the constant string "username", not the value of the username column. Remove the quotes on 'username' and 'email'.
where AES_DECRYPT ('company', 'capullo') = ' " . $company . " '
Same issue here. However, it'd be more efficient to do this the other way around in order to leverage indices:
where company = AES_ENCRYPT(?, 'capullo')
That being said, using AES_ENCRYPT on the MySQL server side is NOT SECURE. The encryption key is passed to the server with each query, and, as such, will appear in the MySQL processlist, as well as potentially in server query, slow, and/or error logs; if you are not using SSL for your MySQL connection, they will be passed over the network in cleartext, as will the decrypted data.
These are column names, so don't put them in quotes:
AES_DECRYPT('username', 'capullo'),
AES_DECRYPT('email', 'capullo')
Do this instead:
AES_DECRYPT(username, 'capullo') AS username,
AES_DECRYPT(email, 'capullo') AS email
Also, since the output of AES_ENCRYPT is binary, ensure your columns are binary.
It also looks like you might have two different tables, 'accesobases' and 'acceso', so ensure you're using the correct table.
Your statement:
where AES_DECRYPT (company, 'capullo') = ' " . $company . " '
Seems fine, as long as you remove the quotes from the column name here too. It will be slow since it won't be able to use an index. Instead, you should do this:
where company = AES_ENCRYPT('$company', 'capullo')

LIKE Condition in PHP Not Work correctly

i have a row in my database with name "active_sizes" and i want filter my website items by size, for this, i use LIKE Condition in php :
AND active_sizes LIKE '%" . $_GET['size'] . "%'
but by using this code i have problem
for example when $_GET['size']=7.0 this code shows items that active_sizes=17.0
my active_sizes value looks like 17.0,5.0,6.5,7.5,,
thanks
Using comma-separated values in a single field in a database is indicative of bad design. You should normalize things, and have a seperate "item_sizes" table. As it stands now, you need a VERY ugly where clause to handle such sub-string mismatches:
$s = (intval)$_GET['size'];
... WHERE (active_sizes = $s) // the only value in the field
OR (active_sizes LIKE '$s%,') // at the beginning of the field
OR (active_sizes LIKE '%,$s,%') // in the middle of the field
OR (active_sizes LIKE '%,$s') // at the end of the field
Or, if you normalized things properly and had these individual values in their own child table:
WHERE (active_sizes_child.size = $s)
I know which one I'd choose to go with...
You don't state which DB you're using, but if you're in MySQL, you can temporarily accomplish the same thing with
WHERE find_in_set($s, active_sizes)
at the cost of losing portability. Relevant docs here: http://dev.mysql.com/doc/refman/5.0/en/string-functions.html#function_find-in-set
You Have % signs around your $_GET value. Combined with LIKE, this means that any string that simply contains your get value will be retuned. If you want an exact match, use the = operator instead, without the percentage signs.
This will solve your immediate issue:
AND active_sizes LIKE '" . mysql_real_escape_string($_GET['size']) . "%'
If you are using the database other than MySQL, use corresponding escape function. Never trust input data.
Besides, I'd suggest using numeric field (DECIMAL or NUMERIC) for active_sizes field. This will accelerate your queries, will let you consume less memory, create queries like active_sizes BETWEEN 16.5 AND 17.5, and generally this is more correct data type for a shoe size.

Categories