Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Validate class/method names with regex

I'm currently working on an MVC Style framework for a company and for security reasons I need to make sure that the controller / method that's passed via the Query String is valid chars to the RFC (which I can't find).

I need to be able to validate / sanitize class names according to what's allowed by the PHP interpreter

For Example:

class SomEFunk__YClAssName extends Controller
{

}

I need some kind of regex that will validate SomEFunk__YClAssName and sanitize it if need be! This is also the same principles as methods.

There is a few things to take into consideration such as

  • Numerics at the start
  • Only underscores allowed
  • Certain PHP Special Chars to be allowed.

Any information on this or possible expressions would be really helpful.

Here is some of my Router Code so you can see where I need to implement it:

private function prepareQueryString()
    {
        if(strlen($this->query_string) == 0)
        {
            return;
        }
        //Remove [ending|starting|multiple] slashes
        $this->query_string = preg_replace('/^\/+|\/+$|\/(?=\/)/', '', $this->query_string);
        foreach(explode('/',$this->query_string) as $Key => $Value)
        {
            if($Key == 0)
            {
                $Controller = $this->AssignController($Value);
            }
            if($Key == 1)
            {
                $this->AssignMethod($Value);
            }else
            {
                $this->AssignParam($Value);
            }
        }

        //Build RouterVar stdClass
    }

    public function AssignController(String $Controller)
    {
        if(!empty($Controller))
        {
            //Sanitize
        }
    }

    public function AssignMethod(String $Method)
    {
        if(!empty($Method))
        {
            //Sanitize
        }
    }

    public function AssignParam(String $Param)
    {
        $this->params[] = $Param;
    }

You will see the comment "Sanitize" where the check is needed.

like image 541
RobertPitt Avatar asked Jul 07 '10 14:07

RobertPitt


2 Answers

I believe the regex you're looking for short class name, e.g. SomeClass is:

<?php

preg_match(
    '/^[a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*$/', 
    $input
);

According to: http://php.net/manual/en/language.oop5.basic.php


For namespaced class, e.g. App\SomeClass it is:

<?php

preg_match(
    '/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*(\\[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)*$/', 
    $input
);
like image 133
nate Avatar answered Nov 06 '22 11:11

nate


You're better off using a very general regular expression, and then testing that the class exists with a simple call to class_exists().

This will match any valid PHP class name, including really weird ones like ___ or _3, both of which are valid class names:

/^[a-z_]\w+$/i

I personally am more restrictive than PHP's naming conventions for classes. I demand my controllers be capitalized, and post-fixed with _controller so that strange non-controller classes aren't invoked via weird URLs. I'd use something like this:

class Products_controller extends Controller { }

// elsewhere, after parsing the controller name from the URI:

if (preg_match('/^[A-Z]\w+_controller$/', $controller_name)
&&  class_exists($controller_name)) {
  $controller = new $controller_name();
}

As an aside, passing the controller name via the query string yields really ugly and search-engine unfriendly URLs. Consider building the controller name and method into the URL:

/products/index # controller=products, action=index
/users/show/3   # controller=users, action=show, user id=3
like image 28
meagar Avatar answered Nov 06 '22 12:11

meagar