views:

199

answers:

2

Hi

I am writing a "catch all" method for my controller for ajax. It is called 'ajax' :P

This is what it currently looks like

public function ajax($method = null) {

    if ( ! $method OR ! request::is_ajax()) {

        return false;

    }


    if (method_exists(array($this, 'searchModel'), $method)) {
        echo $this->searchModel->$method();

    }

    exit;



}

In case that isn't obvious, I want the ajax to first bail out if it thinks it's not an Ajax request, and then, check my $this->searchModel to see if it has the method that was passed in as the ajax method's arguement.

If it does find the method, it should echo it's return value and then exit.

My problem is I can't get the method_exists() to find the method! I know it does exist... I've even hard coded (for testing purposes) methods I know for certain exist.

It's been driving me a little crazy, is anyone able to tell me what I'm doing wrong?

Thanks!

P.S. I'm using the Kohana framework, but I don't think it should matter.

UPDATE

Do you think exposing my internal method names to the JavaScript (i.e. public) could be of security concern?

+3  A: 

You're using the first argument to method_exists() as if it supports a callback argument, but it doesn't accept a callback. It accepts only an object instance or a class name (a string) for testing static methods.

Try this:

if (method_exists($this->searchModel, $method)) {
    echo $this->searchModel->$method();
}


Re your second question, yes I think it's a security concern. You have done no validation that the request is well-formed. I would not use the "catch-all" solution you are designing.

Bill Karwin
Thanks Bill! If I did something like this, do you think it would make it secure `$method = 'ajax_' . $method` .i.e. The 'ajax_' prefix will ensure they can't access any of the other methods of my model?
alex
I was actually more concerned about malicious requests that *do* invoke ajax methods, rather than requests that invoke non-ajax methods.
Bill Karwin
Well this model only deals with user searches - It should be safe.
alex
+2  A: 

I think your code is supposed to say:

if(method_exists($this->searchModel, $method))
    echo $this->searchModel->$method();

However, it is a bad idea to expose all the methods of your searchModel object to the world, so you should prefix the ajax methods with 'ajax_' or something similar so that it is only possible to call methods with that prefix:

// given that $method is 'user_login' ...
$realMethod = 'ajax_' . $method;    
if(method_exists($this->searchModel, $realMethod))
    // calls $this->searchModel->ajax_user_login();
    echo $this->searchModel->$realMethod();
too much php
You read my mind with the prefix thing! Thanks for your answer.
alex