Savride’s Weblog

Web development, coding , graphics

Posts Tagged ‘check

Secure PHP variables $_GET, $_POST – wrapper function

with 2 comments

If You’re tired of maintaining endless $_POST, $_GET or other multiple variables passed to Your PHP scripts,  want to gain more control over them or just try to secure things from abusive users, bots etc. it’s conveniently to use some shortcut.

How to group them at one place? It’s easy, and it’s a time saver to simplify complicated.

Try this wrapper function. It’s especially not optimized fe. to switch or shortened in any way, both for tutorial purposes and that it comes straight out of my PHP project. The project is always ‘work in progress’ so some code has to stay unoptimized for further evaluation.

Some people use such code for so called front controller and other:

page = $_GET['page'];
swith($page) {
case 'home':
include_once('index.php');
break;
case: {...}

Try to avoid it.
You can have multiple places in your script where some variable has to be used and checked. Why do always the same and worst – insecure.  

Do it better way:

/**
 * Savride's environment variables filtering ($_GET, $_POST, etc.) (c) 2008
 * wrapper function
 *
 * @return > a filtered value or redirect if filtered out as abuse  
 * @param $_option Object > get variable by index, example: 'pagename' (useful when var does'nt exist)
 * @param $_old_option Object > use this as default if no value is set
 * @param $_filter Object[optional] regexp for advanced filtering or simple /string/ to deny
 */
function _sopt( $_option, $_old_option = false, $_filter = false)
  {
  $_value = false;
  if( isset( $_GET[$_option] )) {
    $_get_t = $_GET[$_option];
  
    if( $_get_t !== false)
      $_value = $_get_t;
    }

  if( isset( $_POST[$_option] )) {
    $_post_t = $_POST[$_option];
   
    if( $_post_t !== false)
      $_value = $_post_t;
    }

  if( $_filter) {
    if ((( strpos($_filter, "#") !== false) && ( strpos($_filter, "#") == 0))
      ||
      (( strpos($_filter, "/") !== false) && ( strpos($_filter, "/") == 0))) {
        if ( !preg_match( $_filter, $_value)) {
          $_value = false;
              //echo "Error _sopt - unwanted chars";
          }
      }
      else
       if( strpos( $_value, $_filter) !== false) {
             //echo "$_value  | $_filter";
         Header( "HTTP/1.1 403 Forbidden" );
         exit;
         }
    }

  if( !$_value ) 
    {
    if ( isset( $_old_option) && ( $_old_option != "") )
      $_value = $_old_option;
      else
      $_value = false;   
      }

      //echo $_value;
  return( $_value );
  }

Example usage:

// simplest (no multiple conditionals at this place in code)
$_var = _sopt('page');

// check for abusive http URLs injections

if(( _sopt( 'page', "", "http://" ) == false ) || ( _sopt(  'page', "", "http%3A%2F%2F" ) == false ))
(...)

if( _sopt( 'PHPSESSID', "", "http://" )
  ||
  _sopt( 'PHPSESSID', "", "http%3A%2F%2F" ))
  {...};

// check some sent FORM / LINK variable 

if( _sopt( 'fbt_message_send', "") )
(...)

// variable check filtered with regexp

if( _sopt( 'subpage', "", "/^[a-zA-Z0-9]+$/" ))
(...)

And so on. Use this idea freely. I hope it’ll work for You.

This piece of code can be extended with a wider variable scope, not just $_GET… etc. also can be used with any variable check operation/validation. 
Depends of functionality/speed overhead You can afford in Your project.
Caching for current script page variables can be added (eliminates $_GLOBALS access), also an additional parameter escaping functions.

The thing is: use single wrapper function, do not let variables spread all over your scripts.

Don’t let it be Yours one and only security line, as i said, it’s just a part of an environment validation but very useful and important.
Don’t put it in heavy for/while etc. loops.

Written by savride

June 22, 2008 at 12:58