Simple GET validation - php

I have GET[] input and would like to carry out their validation. The input data is always a number by. Schema. I want to make sure that the pass number and the appropriate amount - not to throw the sql query.
at this moment I am using the procedures
$cc = $_GET['cc'];
if ($cc=='') $cc='9012';$find=array("..", "/", "\\");
$replace=array("", "", "");
$cc=str_replace($find, $replace, $cc);
$eic = $_GET['eic'];
.... ect.
// where f.ex. 9012 is an real existing data (in dbase) to generate sucure sql question
GET[] variable data schema
$_GET[$cc] - always 4 digits
$_GET[$eic] - always 4 digits
$_GET[$iy] - always 4 digits
$_GET[$ir] - always 1 digit
Can you show me a better way to secure my GET?

If the query you're getting is always a digit you can use the intval() function in PHP to make sure its an int.
$eic = intval($_GET['eic']);
http://php.net/manual/en/function.intval.php

You can force numeric values by using intval().
You can't, however, represent values with a leading 0 like 0123 using this method.
If you don't have values with leading zeros use this:
<?php
$_GET['cc'] = intval($_GET['cc']);
strlen($_GET['cc']) == 4 ? $_GET['cc'] : $_GET['cc'] = 0; // Replace 0 with default/error value
// Repeat the steps above for all parameters...
?>

change in the number of digits in a variable crashes Query
Well, the whole point of validation is that you "validate" data and don't even bother disturbing your SQL database in case the data has not been validated. Why would you bother executing a query which you know to be invalid?
I don't really agree with using intval() for validation. With intval(), you're forcefully changing the value inputted by the user, which is not really validation. A better method would be to use is_int() instead.
For security? Nothing beats "Prepared Statements"
http://php.net/manual/en/pdo.prepared-statements.php

Related

How to compare (min & max) Float values with MySQL?

I've a database with lon and lat geo location data.
Both are saved as float / decimal attribute in the mysql table.
Now I want to compare this stuff like:
(u.user_location_lat <= ".$lat_max." AND u.user_location_lat >= ".$lat_min.") AND
(u.user_location_long <= ".$long_max." AND u.user_location_long >=".$long_min.")
But it does not show any result (and it should!) - but also no error.
How to EASILY solve this (I actually don't want to work with spatial indexes - at least I do not understand how to do)?
Thanks.
I recommend you verify what that statement looks like, after you do the variable substitution.
That is, echo or vardump the contents of the variable containing the SQL text, before you prepare/execute the SQL statement.
There doesn't appear to be anything wrong with the form of the predicates. (These could be written using equivalent BETWEEN comparators, but it's not a problem what you have written.)
It's possible you have the min and max values swapped, or have the longitude and latitude swapped. If that's not the issue, then I suspect that the variables being substituted may be represented in scientific notation, rather than as decimal values.
e.g. the SQL text gets generated
... u.lat <= 1.241E+2 ...
rather than
... u.lat <= 124.1 ...
In the former case, MySQL is going to evaluate that literal as decimal value of 1.241.
(There's a corner case issue when the bounding box crosses the +180/-180 boundary, but I don't see that's likely a problem for most of your values, that's going to be an exceptional case, which you would probably need to setup special test case to actually have happen.)
In order to debug this, you need the actual SQL text that's being sent to the database to be prepared/executed.
(There's not enough information in your question to identify the actual problem.)
Q: How do I get the actual SQL text?
A: Construct your SQL statement as a string into a variable; and then var_dump that variable for debugging:
$sqltext = "SELECT ... WHERE u.lat <= ". $lat_max . " AND u.lat ... ";
var_dump($sqltext);
$stmt = mysqli_prepare($db, $sqltext);

Problems inserting negative numbers in MySQL with PHP

I am trying to build a simple web app to keep up with my debt and I want to use the same database table for adding and also subtracting data.
I am converting the input from the input field using a simple php operation to convert it to a negative number:
$sum2 = $sum*-1;
$sum being the input field:
$sum = $_POST['shuma'];
The Idea is, when I input a positive number, my debt grows larger, when I input a negative number, my debt gets smaller, it's a simple idea.
In MySQL database, I am inserting the input into:
decimal(7,2) Default:Null
The problem is, the positive input, even though it's being converted into a negative number, it's not being inserted as negative in MySQL, it inserts it again with a positive number. The problem it's not within PHP because I tested it and even after the form it's submitted and data it's pushed into MySQL, I still can get the negative number shown using the echo in PHP.
Does anyone have any idea how to solve this?
P.S. Maybe I should mention, when I try to insert negative directly from phpmyadmin it works, it accepts the negative number in the same field.
Thank you.
change you field type to DECIMAL (10,2) . Field length defination is on you. Define length according to your requirement.
In this case negative value will be inserted. If not, then please die(); your query and execute it directly in mysql. Because for another field's problem also negative value not insert in table though the field type is DECIMAL.
Well, I am trying to use the same input field for both, only use a
checkbox, when the box it's checked, it's a negative number, otherwise
it's positive
About that comment.
i.e. you have
<input type="checkbox" name="negative"/>
<input type="text" name="sum" />
<?php
$sum = (int)$_POST['sum'];
...
so you can have, let's say two methods:
function increase($value) {
return query("UPDATE table SET value = value + $value");
}
and
function decrease($value) {
return query("UPDATE table SET value = value - $value");
}
so you are checking:
if(isset($_POST['negative']) {
decrease($sum);
}
else {
increase($sum);
}
However, the queries are just a sample, I just wanted to explain the logic, where you don't need to add the number with negative sign, but you can change the query depends on the checked inputs

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.

How to change decimal separator cleanly in outputs in mysql - php combo

I was trying to export database query to CSV and the need arised to use different decimal comma. It seems impossible to change the decimal comma in MySQL, so I tried in PHP:
setlocale(LC_NUMERIC, "cs_CZ");
But it seems that all the database functions like mysql_fetch_row and mysql_fetch_assoc are retrieving data of type string instead of double:
$res = mysql_query("select 50/3");
$row = mysql_fetch_row($res);
var_dump($row); // $row[0] is of type "string"
So in general PHP already doesn't have data of type double, but only strings!
So is there some general, clean way to specify output of the decimal point?
I ended up converting the strings using str_replace('.', ',', $row[0]) but this is ugly for two reasons:
you have to know which field is of type double
it's a dirty string job.
I don't know which database client/driver you're using but there is something like mysql_field_type­Docs which gives you the type based on it's offset, like 0.
This should do the job to find out if a certain column needs re-formatting or not.
To reformat, there is number_format­Docs.
With these you can do the conversion automatically.
Edit: Regarding your comments:
If you want to get PHP datatypes mapped, consider using the MySQL Native Driver­Docs. Use it together with PDO:
Advantages of using mysqlnd for PDO
mysqlnd returns native data types when using Server-side Prepared Statements, for example an INT column is returned as an integer variable not as a string. That means fewer data conversions internally. Source
So depending of what you try to achieve, use the right tool.
See as well the multiple options you have when fetching data from a PDO Statement­Docs.
// French notation
$nombre_format_francais = number_format($number, 2, ',', ' ');
Try
number_format($row[0], 2, ",", ".");
That should change the format of the number. (german format)

Why MySQL fetches record even if it doesn't match the ID?

I just discovered this, I use MySQL as my database.
When i do something like:
$query = $this->db->where('id', '6rubbish')->get('posts', 1);
it generates and executes this SQL:
SELECT *
FROM (`posts`)
WHERE `id` = '6rubbish'
LIMIT 1
The surprising thing is that it actually fetches the post with the ID 6.
I find this very vulnerable in same cases because i'm trying to exactly match the ID, not to do a LIKE query.
Any ideas?
Yes.
Read Type Conversion in Expression Evaluation
Use intval() PHP function to extract the integer part of the variable
Or use is_int to exclude any variable that is not a pure integer
But the origin of the problem is that your query generator library doesn't understand the variable types, PHP being a dynamic typed language doesn't help too.
I don't know what library you're using, maybe there is an option to tell that you're passing an int? It should protect you from SQL injection, I hope, try with:
$query = $this->db->where('id', "don't")->get('posts', 1);
and see if the generated SQL has the single quoted escaped (doubled or preceded by backslash).
That is because SELECT 6 = '6rubbish' will give you true, and your id is number type.
Your id field is, no doubt, a numeric data type.
When MySQL evaluates expressions, it converts operands to compatible types (see docs).
'6rubbish' (a string) gets converted to 6 (a number) and, hence, you get a match.

Categories