Security of a simple numerical comparison - php

Ok I'm feeling like I'm going back not forward, can't even figure out by myself if a simple if statement is secure or not...
First of all let's say we get a variable from url GET method :
$my_number = $_GET['numb'];
Now we make this simple if statement:
if(($my_number >= 1) && ($my_number <= 12))
{
put $my_number in database without escaping it
}
So the question would be - Can user pass this if condition with something else besides 1-12, I mean using hex numbers, commenting, doing that kind of stuff?

To validate a number use intval()
$my_number = intval($_GET['numb']);
Nothing but a number will be allowed.
This will also insure the value will not create an error in the SQL.
I do not like >= or <=
if(($my_number >= 1) && ($my_number <= 12))
Change to:
if(($my_number > 0) && ($my_number < 13))

Your code is not fully secured. User can pass this if condition with something else besides 1-12.
You can test that with this simple code:
<?php
$my_number = $_GET['numb'];
if(is_numeric($my_number)){
if(($my_number >= 1) && ($my_number <= 12))
{
echo'User Can Pass';
}else{
echo'User Can Not Pass';
}
}else{
echo'User Can Not Pass';
}
?>
Now browse your site like http://example.com/?numb=8 or http://example.com/?numb=15 or http://example.com/?numb=7 Samurai
I think now you can find your answer. Thanks.

Related

Does using Comparison Operators works same as ctype_digit() or is_numeric() all the time?

For a variable like the following $p = $_GET['page']
In conditions like the following
if ($p > 0)
if ($p < 0)
if ($p >= 0)
if ($p <= 0)
if ($p == 0)
does it work same as
if (ctype_digit($p)){//Logic}
//or...
if (is_numeric($p)){//Logic}
My suggestion is pass in the right datatype for the job. So if you need number pass that to this code.
If you cannot control what is being passed in then check what it is first. This makes you take a second look when code starts to break. I would use is_numeric because it know negatives and floats unlike ctype_digit
is_numeric("-10"); //TRUE
ctype_digit("-10"); //FALSE
is_numeric("12.10"); //TRUE
ctype_digit("12.10"); //FALSE
So in the end you would want to do something like:
$p = $_GET['page'];
if(is_numeric($p)){
$p = (int)$p;
//Do stuff with an int
} else {
//Not sure what should happen here...
}
PHP is super flexible with casting for us but when it comes to trying to find a bug in your code it becomes hard to find when you act like everything is coming in good ie if($p>0){} seems like you know you have a number and I would keep looking elsewhere.

how to write single line if statement with multiple conditions?

I'm currently working on a foreach loop with nested if statements but I'm pretty sure there's a better way of writing these chunks of if statements.
I found this post: PHP if shorthand and echo in one line - possible?
Though this post is for single conditions, I would like to write mine in the same way(single lined).
I'm not that experienced in PHP myself so I'm sort of stuck on doing it the old fashioned way:
if(($colorLevel['name'] === 'ATTR_VPMCV13') && ($colorLevel['level'] >= 80))
{
$prominentSideNumberArray[] = 10;
}
elseif(($colorLevel['name'] == 'ATTR_VPMCV13') && ($colorLevel['level'] >= 60) && ($colorLevel['level'] <= 70)){
$prominentSideNumberArray[] = 8;
}
If someone could properly explain what code to use where and why, that could really help me, and/or others, out. I've looked at the manual but I just can't figure out what to use where.
There is no such thing like an "if shorthand".
?: is an operator, if is a control structure. They are different language concepts that have different purposes and do different things. An expression that contains the ternary conditional operator (?:) can always be rewritten as two expressions and an if/else statement. The vice-versa is usually not possible.
The code you posted can be written to be much easier to read if you extract the common checking of $colorLevel['name'] into a separate if that includes the rest of the tests, extract $colorLevel['level'] into a new variable with shorter name and make the conditions that use $colorLevel['level'] use the same rule:
$level = $colorLevel['level'];
if ($colorLevel['name'] == 'ATTR_VPMCV13') {
// Don't mix '<=' with '>=', always use '<='...
if (60 <= $level && $level <= 70) {
$prominentSideNumberArray[] = 8;
// ... and put the intervals in ascending order
} elseif (80 <= $level) {
$prominentSideNumberArray[] = 10;
}
}
If there are multiple if statements that verify different values of $colorLevel['name'] then the intention is more clear if you use a switch statement:
$level = $colorLevel['level'];
switch ($colorLevel['name'])
{
case 'ATTR_VPMCV13':
if (60 <= $level && $level <= 70) {
$prominentSideNumberArray[] = 8;
} elseif (80 <= $level) {
$prominentSideNumberArray[] = 10;
}
break;
case '...':
// ...
break;
default:
// ...
break;
}
You can achieve this by using a ternary operator. Look at the following code:
$prominentSideNumberArray[] = ((($colorLevel['name'] === 'ATTR_VPMCV13') &&
($colorLevel['level'] >= 80) )? 10 : (($colorLevel['name'] == 'ATTR_VPMCV13') &&
($colorLevel['level'] >= 60) && ($colorLevel['level'] <= 70)?8:"")) ;
EDIT As per comments and you have to compare same value its better to define name
$color_name = "ATTR_VPMCV13";
if($colorLevel['name'] == $color_name )
$prominentSideNumberArray[] = (($colorLevel['level'] >= 80)? 10 : (
($colorLevel['level'] >= 60) && ($colorLevel['level'] <= 70)?8:"")) ;
DEMO with different approach
EDIT
Keep in mind that this solution is less readable than if-else statement.

Where did i go wrong in if-statement php?

Need little help, always get the last value 188490?
if(isset($_POST['zapremina']) and is_numeric($_POST['zapremina']))
{
if ($_POST['zapremina']<=1050)
$_POST['zapremina']=1030;
if (($_POST['zapremina']>=1151) and ($_POST['zapremina']<=1300));
$_POST['zapremina']=2010;
if (($_POST['zapremina'] >= 1301) and ($_POST['zapremina'] <= 1600));
$_POST['zapremina']=4400;
if (($_POST['zapremina'] >= 1601) and ($_POST['zapremina'] <= 2000));
$_POST['zapremina']=9110;
if (($_POST['zapremina'] >= 2001) and ($_POST['zapremina'] <= 2500));
$_POST['zapremina']=45000;
if (($_POST['zapremina'] >= 2501) and ($_POST['zapremina'] <= 3000));
$_POST['zapremina']=91200;
if ($_POST['zapremina'] > 3001);
$_POST['zapremina']=188490;
}
else
$_POST['zapremina']=0;
I think is a little mistake, does anybody knows, txanks a log
Yeah, you need to do else if.
if ($_POST['zapremina']<=1050)
$_POST['zapremina']=1030;
else if (($_POST['zapremina']>=1151) and ($_POST['zapremina']<=1300))
$_POST['zapremina']=2010;
else if (($_POST['zapremina'] >= 1301) and ($_POST['zapremina'] <= 1600))
$_POST['zapremina']=4400;
etc.
As to why: You're checking against your variable and then you set it to another value, which tends to be higher than anything you're checking against AFTER you assign it.
So anything that's higher than would produce 188490 in the end.
The else means: Stop comparing at the first match.
Furthermore you need to remove the ; after the if statements, because the ; means: End of operation. In this context it would mean End of If...that in turn means, that the following line will ALWAYS be executed, the value of your variable doesn't even matter at that point any more.
remove ; [semicolon] at the end of every if statements and used else if ladder in current scenario
if(isset($_POST['zapremina']) and is_numeric($_POST['zapremina']))
{
if ($_POST['zapremina']<=1050)
$zapremina=1030;
if (($_POST['zapremina']>=1151) and ($_POST['zapremina']<=1300))
$zapremina=2010;
if (($_POST['zapremina'] >= 1301) and ($_POST['zapremina'] <= 1600))
$zapremina=4400;
if (($_POST['zapremina'] >= 1601) and ($_POST['zapremina'] <= 2000))
$zapremina=9110;
if (($_POST['zapremina'] >= 2001) and ($_POST['zapremina'] <= 2500))
$zapremina=45000;
if (($_POST['zapremina'] >= 2501) and ($_POST['zapremina'] <= 3000))
$zapremina=91200;
if ($_POST['zapremina'] > 3001)
$zapremina=188490;
}
else
$zapremina=0;
I see at least two errors:
1) You have semicolons (;) after almost every if-statement line of code. This way these statements don't even affect anything and your POST-variable is set six times.
2) You set your POST-variable to new (higher) values and check afterwards with this new and higher value which is not what you try to accomplish I guess.
Also - as datasage already said - avoid writing to the POST-variable.

php if-else failing

What is wrong with this if-else statement.
if((strlen($objectData['pss'] >= 8))AND(strlen($objectData['pss'] <= 20)))
{
//do my bidding
}
else
{
echo "String to short or to long";
}
Ultimately I am trying to find if the variable is greater than or equal to 8 chars while being under or equal to 20 chars. My test string is 11 char, and I am seeing string to short/to long. I've done similar to this in the past, so I dunno what I mucked up at the moment (maybe Im just to tired to realize it)
if (strlen($objectData['pss']) >= 8 && strlen($objectData['pss']) <= 20)
if ((strlen($objectData['pss']) >= 8) and (strlen($objectData['pss']) <= 20))
{
//do my bidding
}
else
{
echo "String to short or to long";
}
I have corrected you brackets
Yes you are indeed "to tired".. You are basically counting the length of an expression instead of the string itself:
if((strlen($objectData['pss']) >= 8)AND(strlen($objectData['pss']) <= 20))

PHP ELSE IF statement

unable to get my else if statement to work, does anyone have any ideas? it works without the else if....
$waveFeet = round("$ar2");
if ($waveFeet >= 2) {
echo $waveFeet - 1;
}
else if ($waveFeet > 5) {
echo $waveFeet - 2;
}
else
{
echo "$wavefeet";
}
also as a side question, can anyone tell me how to change my round() to make it always round (down) instead of rounding up or down...?
Using the third argument of round you can round it down
echo $waveFeet = round($ar2, 2, PHP_ROUND_HALF_DOWN);
and for your if your else if condition will never got true as if the $waveFeet is greater than or equal to 2, the first condition will be true hence your elseif condition will never be true.
You should be changing it to
if ($waveFeet > 5) {
echo $waveFeet - 1;
}
else if ($waveFeet >= 2) {
echo $waveFeet - 2;
}
else
{
echo $wavefeet;
}
Try the statement with a particular value, say $waveFeet = 10;, then step through the code. The first condition succeeds, so the later branches are never checked. In fact, the only time the first branch isn't entered is when $waveFeet < 2, in which case the last branch body will be executed. Thus the middle branch is never executed. The more exclusive case should come first:
if (5 < $waveFeet) {
...
} elseif (2 <= $waveFeet) {
...
} else {
# $waveFeet < 2
...
}
To be completely safe, you can specify both boundary conditions:
...
} elseif (2 <= $waveFeet && $waveFeet <= 5) {
...
The inefficiency due to redundancy is minimal and the code is clearer. As you get more experienced, you can leave off this sort of thing.
If you wish to round even negative numbers down, use floor. If you wish to round towards zero (i.e. truncate), cast to an int:
$waveFeet = (int) $ar2;
you can use floor for down round
$waveFeet = floor($ar2);
if ($waveFeet > 5)
echo $waveFeet - 2;
else if ($waveFeet >= 2)
echo $waveFeet - 1;
else
echo $wavefeet;
you have to first check for 5 bcz 5 is big no than 2 and your first condition >= 2 also satisfied if no >5 so control go to first condition rather than second....
Theres nothing wrong in your code ( except that you can pass argument to function without quotes ). The way you are checking it is wrong.
it wont go to else if condition because the condition will be satisfied in the first check itself .
PHP buil-in floor() and ceil() functions round a number down and up respectively. I recommend posting the error you get so we can help you faster =)
Try this:
$waveFeet = floor($ar2);
if ($waveFeet >= 2 && $waveFeet <= 5 ) {
echo $waveFeet - 1;
} else if ($waveFeet > 5) {
echo $waveFeet - 2;
} else {
echo $wavefeet;
}
Note the change in the first condition (added && $waveFeet <= 5)
I think the problem might be that the ranges you use in your first and second conditions are overlapped, and it is very likely that in the case, let's say, $waveFeet == 6 PHP evaluates your first condition (originally $waveFeet >= 2), and it happened to be true, so PHP does not test the else if statement... Whenever it's possible to use disjunct conditions, I recommend you to do it...

Categories