CodeIgniter Forums

Full Version: How do I prevent direct controller function access?
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Pages: 1 2

El Forum

[eluser]Kraig[/eluser]
I have looked around and a lot of people say to use the underscore before the function or just make it private instead of public. However, if I do this then I cannot access it from my script either. Is there another way to prevent someone from entering this directly into their address bar?

http://www.somesite.com/folder/controller/some_function

This is just an example....So far I have come up with an idea, but it seems like a lot of work to do every time:

Code:
public function some_function()
{
  $val = $this->input->post('val'); // Folder Name
  $val = strip_tags( trim($val) );
  $val = mysql_real_escape_string($val);
  $userID = $this->session->userdata('id');
  $duplicate = $this->account_model->validateFolderName($val);
  
  if ( !$duplicate && $this->input->post('val') ) {
   $this->db->query("INSERT INTO user_folder (user_id, name) VALUES ('".$userID."', '".$val."') ");
   $output_string['duplicate'][ ] = 'false';
   $output_string['folderID'][ ] = $this->account_model->getFolderID($val);
   echo json_encode($output_string);
  } elseif ( $duplicate && $this->input->post('val') ) {
   $output_string['duplicate'][ ] = 'true';
   echo json_encode($output_string);
  } else {
   redirect('errors/error_404', 'refresh'); // Tried to access directly
  }
}


Also how come when I enter "www.somesite.com/folder/controller/" into the address bar I don't get the "No direct script access allowed" error? I have the code below at the top of everyone of my files...minus the views (should I add it to the views?)

Code:
<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

El Forum

[eluser]Kraig[/eluser]
In case anyone else needs this I decided to use the routes class. For instance, account is a folder inside the controllers and the second segment "account" would be the controller that has all of the functions.

Code:
$route['account/account/(:any)'] = 'error_mess';

Basically if someone tries to enter "www.somesite.com/account/account/add_user", the add_user being the function, they would be redirected to my set error page!

El Forum

[eluser]PhilTem[/eluser]
That's all kinda unnecessary, you can just add an underscore in front of the function name and it will become inaccessible from the URI. That's one thing. Furthermore, what I guess is also what you want to have, you may want to check for permissions, i.e. implement an authentication and authorization library/module/whatever, that will be taking care of checking permissions.

@Kraig What do you do when you have hundreds of such methods? Do you add one line per method to the routes file? Isn't that kinda over-bloating everything? #justaskin Wink

El Forum

[eluser]Kraig[/eluser]
If I use the underscore then I cannot access the function through my scripts...like my forms or even ajax. So I'm either writing if else statements for post/ajax checking or routes.

El Forum

[eluser]PhilTem[/eluser]
I'm not sure I understand "cannot access the function through my scripts…like my forms or even ajax" correctly, but only external access to your functions is prohibited, not internal access (as long as you don't use the public-declaration in the method header Wink )

But sure, for AJAXing it's not possible to access these methods since these requests will be routed through index.php as well and that checks for underscores. However, if you restrict access with routes.php, even AJAX requests won't be able to access it since it's prohibited.
Thus, the only plausible way would be to use some filtering in MY_Controller::__construct() to check for allowed/disallowed requests Wink

El Forum

[eluser]Kraig[/eluser]
Ok...so if I have a form and some ajax then I use the underscore and take off the public so it's function _someFunc() it should work? I'm not even sure how you would check in MY_Controller. If routes and the underscore don't work then what I did above would have to do the trick huh...

El Forum

[eluser]Kraig[/eluser]
[quote author="PhilTem" date="1356101671"]
Thus, the only plausible way would be to use some filtering in MY_Controller::__construct() to check for allowed/disallowed requests Wink[/quote]

Do you happen to have an example? I'm surprised this issue hasn't been looked at and fixed before. I use controller functions externally when submitting forms and when using ajax. Making them secure is a must.

El Forum

[eluser]Aken[/eluser]
Any URL you want to use for form submissions and ajax requests has to be publicly available, because they are meant to accept standard HTTP requests, even though they are not (typically) directly from a user's browser.

You can use built-in methods such as $this->input->is_ajax_request() to test for an ajax request, and output the proper response.

Personally, I do something like StackOverflow solution/answer, where I use the same controller method to process standard browser requests as well as ajax requests.

El Forum

[eluser]Kraig[/eluser]
Do you put is_ajax_requested in MY_Controller that way you can access it from all of your controllers?
Code:
public function is_ajax_request()
{
    return ($this->server('HTTP_X_REQUESTED_WITH') === 'XMLHttpRequest');
}

So this is for ajax, how would you do a normal post form submission so you can do this...I put question marks because not all posts will have the same parameter
Code:
if ($this->input->is_ajax_request() || $this->input->post(???) )
{
    // AJAX request stops here
    exit(json_encode($data));
}

Also do you put all of your ajax requests and form submission functions into the same controller, or do you keep them in their perspective controller?

El Forum

[eluser]Aken[/eluser]
is_ajax_request() is built into the Input class already.

An ajax request and a POST request are two different things. You can have a POST request without an ajax request (standard form submission), or you can have both, or you can have an ajax request without POST data. How you check depends completely on what you're trying to accomplish.

And like that StackOverflow answer mentions, I don't separate ajax requests - I check for an ajax request on an existing method, and act accordingly.
Pages: 1 2