Reply to Re: strval $_REQUEST

Your name:

Reply:


Posted by Umberto Salsi on 05/17/07 14:56

SterLo <sterling.hamilton@gmail.com> wrote:

> I would guess they are just being redundant.
> You're right $_REQUEST is a string (most PHP variables are).
> So converting a string to a string is pointless.

As far as I know, $_GET $_POST and $_REQUEST are associative arrays
whose elements can be:

- unset (i.e. undefined)

- a string of arbitrary bytes, ranging from 0 up to max(memory_limit,
post_max_size, some_web_server_limit)

- an array of any combination of strings and arrays of strings with
arbitrary keys.

Consider these examples:

1) www.mysite.com/test.php?a=x%00%01x
$_GET['a'] becomes an unexpected "x%5C0%01x"
(here the string is urlencoded() for readability; note the "0" after "%5C")

2) www.mysite.com/test.php?a[]=xxx
$_GET['a'] becomes array(0=>"xxx")

3) www.mysite.com/test.php?a[one]=xxx&a[1]=yyy
$_GET['a'] becomes array("one"=>"xxx", 1=>"yyy"))
(note the keys "one" and 1)

4) www.mysite.com/test.php?a[3]=xxx&a[2][0]=yyy&a[-1]=zzz
$_GET['a'] becomes array(3=>"xxx", 2=>array(0=>"yyy"), -1=>"zzz")

5) www.mysite.com/test.php
$_GET['a'] is not set

The same holds for the $_POST and $_REQUEST arrays.

If all that involves some security issue or not, it depends on how all these
values are handled by your program. An array can be evaluated as "Array"
when a string is expected, and can be evaluated as 0 if a number is expected.
Some functions of the standard library behave differently depending on the
value they receive, be it a string or an array. Some test for validation
may fail. For example, for the case 3:

strlen($_GET['a']) gives always 5 for any array.

$_GET['a'] + 1 gives 1 for any array

preg_match("/^\\w\$/", $_GET['a']) raises an error and return false

$somearray[ $_GET['a'] ] always select the element of key "Array"

....and so on, with more and more unexpected behaviors and oddities.

The solution: build your own functions/classes that validate and sanitize
every type of input. As a base rule:

A) Most of the received parameters are (should be...) strings. Apply
a (string) type-cast:

$s = (string) $_GET['a'];

then remove control chars and check proper encoding (ISO-..., UTF-8, etc.).

B) <textarea>: as for A, but \t \r and \n should be preserved.

C) Numbers: if a little integer number is expected, apply the (int) type-cast
then check the range:

$i = (int) $_GET['a'];
$i = min( max($i, SOME_MIN), SOME_MAX );

Otherwise, if the number is a monetary value (example: "1,234.99") convert
to string and apply preg_match() with a proper REGEX, something like:

$a = trim( (string) $_POST['a'] );
if( preg_match("/^[0-9]+(,[0-9]{3})*(\\.[0-9]+)?\$/", $a ) === 1 ){
# ok, now remove commas then use BCMath or GMP for calculations
} else {
# BAD
}

D) <select multiple>: more difficult to validate. Check the received array
be actually an array, then copy every value in another array converting
every element to string or to int, depending on the expected type; ignore
duplicated values:

$a = $_POST['a'];
$a_sanitized = array();
if( is_array($a) ){
foreach($a as $v){
$i = (int) $v;
if( array_search($i, $a_sanitized) === FALSE )
$a_sanitized[] = $i;
}
}
# Here: check the values $a_sanitized[] be valid, for example they
# may be compared againts good values saved in the session, or in a
# hidden field protected with HMAC.

Regards,
___
/_|_\ Umberto Salsi
\/_\/ www.icosaedro.it

[Back to original message]


Удаленная работа для программистов  •  Как заработать на Google AdSense  •  England, UK  •  статьи на английском  •  PHP MySQL CMS Apache Oscommerce  •  Online Business Knowledge Base  •  DVD MP3 AVI MP4 players codecs conversion help
Home  •  Search  •  Site Map  •  Set as Homepage  •  Add to Favourites

Copyright © 2005-2006 Powered by Custom PHP Programming

Сайт изготовлен в Студии Валентина Петручека
изготовление и поддержка веб-сайтов, разработка программного обеспечения, поисковая оптимизация