CodeIgniter Forums
Preventing Logged in users from calling methods/functions of a controller directly. N00b here :oP - Printable Version

+- CodeIgniter Forums (https://forum.codeigniter.com)
+-- Forum: Archived Discussions (https://forum.codeigniter.com/forum-20.html)
+--- Forum: Archived Development & Programming (https://forum.codeigniter.com/forum-23.html)
+--- Thread: Preventing Logged in users from calling methods/functions of a controller directly. N00b here :oP (/thread-34802.html)



Preventing Logged in users from calling methods/functions of a controller directly. N00b here :oP - El Forum - 10-10-2010

[eluser]zrowcrypt[/eluser]
Hey guys,

This is my first post on CI forum. I started using CI seven days back and got acquainted to core MVC hands on experience about ten and trust me, learning was never so much fun so before I go ahead and start posting my n00b questions, a very big thanks to all you awesome guys who put so much of time in developing such great frameworks. Kudos to CI team and the whole of developer community Smile.

Ok, so here is something that I tried looking for an answer but was not able to get it.

Qs : How to we prevent users(legit logged in) to prevent from calling the methods/functions of my CI controller class. Yes (_function) can be used for private ones but what about public ones that expect to be called only by other controllers / or returned back from views or models after an expected processing of data/db/sessions/args etc.

If you find the question too dumb, I am sorry about it. As I mentioned I am just a week old as far as CI/MVC goes so feel free to just point me the right doc/video so that I can grab it. If you can explain it yourself, nothing better Smile

Thanks,
zrowcryt


Preventing Logged in users from calling methods/functions of a controller directly. N00b here :oP - El Forum - 10-10-2010

[eluser]Bas Vermeulen[/eluser]
Welcome Smile

Let me explain what I did to block access to full controllers or methods for people who aren't logged in w/o having to do that check in each secure controller/method. I hope this helps!

I extended the CI base Controller => MY_Controller (check the user guide if you don't know how to do that: http://ellislab.com/codeigniter/user-guide/general/core_classes.html). I used the term index for stuff that is allowed to be used by people who aren't logged in.

I added a the following to my config file:
Code:
/*
|--------------------------------------------------------------------------
| Index controllers
|--------------------------------------------------------------------------
|
| This determines which controllers are allowed to be used when a user is
| not logged in to prevent access to the secure controllers.
|
*/
$config['index_controllers'] = array('login', 'register');

/*
|--------------------------------------------------------------------------
| Index methods
|--------------------------------------------------------------------------
|
| This determines which methods are allowed to be used when a user is
| not logged in to prevent access to the secure methods.
|
*/
$config['index_methods'] = array('lost', 'request', 'activate');

The following goes into the construct method of MY_Controller (I removed some stuff to show the part that matters):

Code:
if($is_logged_in) {
    // Doing some stuff here
} else {
    // Not logged in, so I'm checking if the request is permitted.
    // First get the allowed controllers and methods
    $index_controllers = $this->config->item('index_controllers');
    $index_methods = $this->config->item('index_methods');
    // Then get the controller and method of the current request
    $current_controller = $this->router->fetch_class();
    $current_method = $this->router->fetch_method();
    // Now let's do the check
    if (in_array($current_controller, $index_controllers)) {
        // We can continue because the requested controller
        // is an index controller
        // Doing some stuff here
    } elseif (in_array($current_method, $index_methods)) {
        // We can continue because the requested method
        // is an index method
        // Doing some stuff here
    } else {
        // We have to abort this request because the requested
        // controller or method is a secure one, the user need
        // to be logged in.
        // Redirect to the login page.
        redirect('/login');
    }
}

I think with this info you should be able to fix what you want?


Preventing Logged in users from calling methods/functions of a controller directly. N00b here :oP - El Forum - 10-10-2010

[eluser]zrowcrypt[/eluser]
Cool, thanks for the prompt reply.

Well, you solved one of my other problems Smile so I'll definitely tweak my code for non logged in users code execution flow....but my concern is more towards user who are logged in, specially malicious users who have CI/MVC knowledge and who can take intelligent guesses as what my controllers and methods are. What if now they try to call a controller or a method of a controller directly typing it in the URL..it can crash my app or can be a security threat Sad.

Please let me know if you need more clarification on my problem.

Thanks once again.


Preventing Logged in users from calling methods/functions of a controller directly. N00b here :oP - El Forum - 10-10-2010

[eluser]Bas Vermeulen[/eluser]
Ghehe, I just came back from a 24 hour shift so I didn't read your post very well the first time. After replying I saw that you ment to prevent logged in users to have access to some controllers and methods. So I updated my post a bit (probably while you were replying) to explain that my example can be used to fix what you want. You can add arrays with secure controllers and or methods and do:

Code:
if($is_logged_in) {
    // Logged in, check if the request is permitted.
    // First get the allowed controllers and methods
    $secure_controllers = $this->config->item('secure_controllers');
    $secure_methods = $this->config->item('secure_methods');
    // Then get the controller and method of the current request
    $current_controller = $this->router->fetch_class();
    $current_method = $this->router->fetch_method();
    // Now let's do the check
    if (in_array($current_controller, $secure_controllers)) {
        // We can continue because the requested controller
        // is an allowed secure controller
        // Doing some stuff here
    } elseif (in_array($current_method, $secure_methods)) {
        // We can continue because the requested method
        // is an allowed secure method
        // Doing some stuff here
    } else {
        // We have to abort this request because the requested
        // controller or method is a private secure one.
        // Show error, redirect, remap, etc
    }
} else {
    // Doing some stuff here
}

Is this what you mean or should I just head to bed and try again later Tongue


Preventing Logged in users from calling methods/functions of a controller directly. N00b here :oP - El Forum - 10-10-2010

[eluser]zrowcrypt[/eluser]
Awesome. Thanks. This will solve the problem for me for now Smile. Probably, when you find time tomorrow or later can you let me know if there are other alternatives. This method seems just perfect but as my project keeps growing I'll have to continuously add on to the array list of controllers and methods...but as of now, I can work with this fix.

Thanks again. 24hr shift makes me feel I'm not working hard enough Tongue. Gd Nite!


Preventing Logged in users from calling methods/functions of a controller directly. N00b here :oP - El Forum - 10-11-2010

[eluser]Bas Vermeulen[/eluser]
Ghehe, I am working way to much ;p

Ok, I hope I properly get your question now:

Let's say you have a page that shows a user profile form, your controller is called Profile and you have a method called view($user_id). This method returns the user data, loads the view et voila you got yourself this nice form. The form is submitted to the edit($user_id) method. But you want to prevent people to directly load the edit($user_id) method by browsing to profile/edit/1 ?

You should not use what I showed you earlier for this. In the edit() method you can simply do some checks to make sure it's a valid POST request. I use the form validation class for that.

If I'm completely wrong please clarify Smile