Question

I am trying to read get parameters in such a way that will not open up potential security issues.

What I was thinking was matching the request parameter explicitly to what I expect and then setting a default for anything that doesn't match.

For example:

if ($_REQUEST['media'] == "video")
    $sort = "video";
elseif ($_REQUEST['media'] == "audio")
    $sort = "audio";
else
    $sort = "both";

Is this enough or are further steps necessary?

Was it helpful?

Solution

What you mention is safe, but is overly verbose. Using an PHP's array operations would let PHP handle the dirty work for you:

$sort_valid = array('video', 'audio', 'both');
$sort = 'both'
if (isset($_REQUEST['media']) && in_array($_REQUEST['media'], $sort_valid)) {
    $sort = $_REQUEST['media'];
}

If this sort of superglobal parsing is common throughout your code, you could abstract this into a function that handles it for you (as many large PHP projects do).


As Gavin noted, it's also a good idea to use the specific superglobal that you're interested in (i.e. $_GET, $_POST, or $_COOKIE) if at all possible. It might not seem important now, but some ugly bugs can manefest from naming conflicts will occur between the three superglobals (e.g. sort in $_COOKIE may refer to the default sorting of search results, but sort in $_GET refers to ascending or descending order).

OTHER TIPS

It's probably also worth noting (if you're that concerned about security) that it is fairly bad practice to not know where your data is coming from. You should probably either use $_GET, $_POST or $_SESSION depending on the method of delivery.

I would add one more condition:

    $sort = "both";
    if (array_key_exists('media', $_REQUEST))
    {
        if ($_REQUEST['media'] == "video")
            $sort = "video";
        elseif ($_REQUEST['media'] == "audio")
            $sort = "audio";
    }

And yes, the $_REQUEST superglobal is the recommended way to read the request.

Simplest way would be:

$sort='both';
$sort_valid = array('video', 'audio');
if(isset($_REQUEST['media']) && in_array($_REQUEST['media'], $sort_valid)) $sort=$_REQUEST['media'];
$valid = array("media" => array("both", "media", "video"), ... );
$default = array("media" => "both", ...);

...

// 1. drop invalid keys
$filtered_on_keys = array_key_intersect($_REQUEST, $valid);

// 2. drop invalid values
$filtered_on_values = array();

foreach($filtered_on_keys as $key => $value) {
  if (array_search($value, $_REQUEST($key) !== FALSE) {
    $filtered_on_values[$key] = $value;
  }
}

// 3. add missing defaults
$result = array_merge($defaults, $filtered_on_values);

Make sure you know where the data is coming from is the best way.
// we don´t accept GET method, so, we set $media null
// if method equals post, we parse into int, so whateever comes in $_post,
// it will not parse in string mode and we wont need to check for sql injcetion.

(isset($_GET['media']))? $media='': $media=(int)(isset($_POST['media'])) ? $_POST['media'] : '';

switch ($media) {
    case 1: $sort = "video"; break;
    case 2: $sort = "audio"; break;
    default: $sort = "both"; break;
}



by the way, you can read about $_SERVER['REQUEST_METHOD']

// we use POST method in form, so...

if ($_SERVER['REQUEST_METHOD']=="GET") header('Location: http://www.disney.com/');

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top