How do we protect our post data processing method in CodeIgniter controller from the external form? - codeigniter

I'm working on a small project with CodeIgniter which handling some post data submitted from the admin form page.
I do transfer the post data to a method in my controller and send it to the database.
Its working all the time.
Im thinking, what if someone make an external form with the exact same inputs name and action attribute with mine in the admin page (I dont know how to figure the inputs name out but this is just my wonder), and try to post some data to the controller?
I try to use session but I wonder if there are any way to protect that kind of inject method?

you can try before your form_validator with
if( $_SERVER['HTTP_REFERER'] == base_url()){
//form validator
}
else{
$this->session->set_flashdata('warning', 'You try to enter from an external web without permission');
redirect(base_url(), 'refresh');
}

There are a couple of things you can do.
First, since this is an admin only page I assume you have some kind of login and user verification in place.
You can use session data to store the successful admin login.
//admin log in OK
$this->session->set_userdata('admin_logged_in', TRUE);
In the method that processes the form post, confirm the user is logged in
if($this->session->userdata('admin_logged_in') !== TRUE)
{
redirect('somewhere_else');
return; //here in case the redirect call doesn't work
}
Second, since you are 'posting' to this page confirm that is the method the server has received - it MUST be post. If you are using CI version => 3.0 the do this
if($this->input->method() !== 'post')
{
//somebody is trying to fool you
redirect('somewhere_else');
return; //here in case the redirect call doesn't work
}
If you are using an earlier version of CI (before 3.0.x) do this
if(strtolower($this->server('REQUEST_METHOD') !== 'post')
{
//somebody is trying to fool you
redirect('somewhere_else');
return; //here in case the redirect call doesn't work
}
You also might want to consider the case where the session info checks out but it was not a POST request. That is very suspicious to me and it might be wise to destroy the session before redirecting.

Related

Symfony 2 - Secure Ajax Controller

I have ajax controler to store actions that are called through the AJAX from JS.
Here in every action I validate if request is made by AJAX and no other:
if (!$request->isXmlHttpRequest()) {
return new JsonResponse(array('message' => 'You can access this only using Ajax!'), 400);
}
Now the problem is that not every ajax controller action should be called by everyone, but rather depending on a role of the logged in user.
The request to action is made by AJAX from JS, but since actions are in controller I am still able to get logged in user object by $this->getUser() and to check if user has acceptable ROLE to execute the controller action by isGranted().
Example:
if (!$authorizationChecker->isGranted('ROLE_ADMIN')) {
return new JsonResponse(array('message' => 'This can be performed only by admin!'), 400);
}
Should I check ROLES from inside controller in every action or try to configure access_control for ajax routes in security.yml?
I have no idea what is the big difference between these two approaches, but would like to know which one would be more practical and could keep my ajax actions more secure.
Depends on the number of AJAX Controllers you have. If you have so many controllers those are to be allowed only for a certain role, access_control in security.yml is a good choice. Else you can have the condition in each controller.
For dynamic permission layer, where permission to be decided based on subject attribute(the viewing content), You might want to use voter.

Registering routes with Laravel but make them unaccessible

I am trying to make a single page CRUD application with Laravel. I will use ajax to create, edit and delete my entity, and also to render partial views. The corresponding controller methods will process the information and return the views.
I want to register the routes so I can call the different methods when necessary. I don't see any other way:
However, registering them so I can do something like this {{ Form::open(['route' => ['cities.store', $city->id]]) }} will allow access via the URL, and I only want to make those routes accessible through the tools I am going to create in that one page CRUD.
I can only think of applying a before filter, but what would be the filter? Also, any other ideas on how I should approach this situtation?
I've had to do something similar with a web service I created. Basically, I wanted only my app to be able to access the routes I created.
What I ended up doing was adding a hashed key to each request being sent, then checking for this key value in the controller. So, only if the key is present and matches the one sent would you then process the request.
Or, if you're using forms, you could do something like the following:
//check if request was sent from our form
if ( Session::token() !== Input::get( '_token' ) ) {
return Response::json( array(
'msg' => 'Unauthorized access attempt'
) );
}
Hope this helps.
another way that doesnt need tokens but is less secure, you got to know what you need,
is using laravels request information
if (Request::ajax())
{
//your action
}else{
//error
}
note this only works when your application always uses ajax you could even type this in your before filter and add it to all needed routes

How do you change the CakePHP model validation redirect?

CakePHP seems to redirect an invalid form back to the controller/action the form was sent from. But in my case, the form comes from controller/action/value and I need to validation redirect to go there.
I've tried adding redirects in my controller in the appropriate place to no avail. Any ideas?
You totally can do this. Just manually check the validation from the controller like this:
if ($this->ModelName->validates(array('fieldList' => array('field1', 'field2')))) {
// valid - do save here and continue
} else {
// invalid - do redirect here
}
You can read more here:
http://book.cakephp.org/1.3/view/1182/Validating-Data-from-the-Controller

Use CodeIgniter form validation in a view

I have footer view that's included on all my pages which contains a form. I would like to be able to make use of CI's form validation library to validate the form. Is that possible?
Currently the form posts back to the current page using the PHP_SELF environment variable. I don't want to get it to post to a controller because when validation fails it loads the controller name in the address bar, which is not the desired behaviour.
Any suggestions gratefully received.
Thanks,
Gaz
One way, whilst far from ideal, would be to create a "contact" function in every controller. This could be in the form of a library/helper.
CI doesn't natively let you call one controller from another, although I believe there are extensions that enable this.
Another option would be an AJAX call instead, which would allow you to post to a generic controller, validate etc whilst remaining on the current page.
In this use case, I would definitely go for an AJAX call to a generic controller. This allows you to show errors even before submitting in the origin page.
Another way (slightly more complex), involves posting your form data to a generic controller method, passing it a hidden input containing the current URL.
The generic controller method handling your form can then redirect to the page on which the user submitted the form, passing it the validation errors or a success message using flash session variables: $this->session->set_flashdata('errors',validation_errors()) might do the trick (untested)
The good thing about this is that you can use the generic form-handling method for both the ajax case (suppressing the redirect) and the non-ajax case
AJAX would be best, just like everyone else says.
I would redirect the form to one function in one controller, you could make a controller just for the form itself. Then have a hidden value with the return URL. As far as errors go you could send them back with flashdata.
Just remember to never copy paste code, it a bad practice and guarantees bugs.
//make sure you load the proper model
if ($this->form_validation->run() == FALSE){
// invalid
$redirect = $this->input->post('url');
$this->session->set_flashdata('errors',validation_errors());
redirect($redirect);
} else {
/*
success, do what you want here
*/
redirect('send them where ever');
}

How do I prevent tampering with AJAX process page?

I am using Ajax for processing with JQUERY. The Data_string is sent to my process.php page, where it is saved.
Issue: right now anyone can directly type example.com/process.php to access my process page, or type example.com/process.php/var1=foo1&var2=foo2 to emulate a form submission. How do I prevent this from happening?
Also, in the Ajax code I specified POST. What is the difference here between POST and GET?
First of all submit your AJAX form via POST and on a server side make sure that request come within same domain and is called via AJAX.
I have couple of functions in my library for this task
function valid_referer()
{
if(isset($_SERVER['HTTP_REFERER']))
return parse_url($_SERVER['HTTP_REFERER'], PHP_URL_HOST) == $_SERVER['SERVER_NAME'];
else
return false;
}
function is_ajax()
{
$key = 'HTTP_X_REQUESTED_WITH';
return isset($_SERVER[$key]) && strtolower($_SERVER[$key]) == 'xmlhttprequest';
}
You might read this post regarding difference between post and get
While as Jason LeBrun says it is pretty much impossible to prevent people simulating a form submission, you can at least stop the casual attempts to. Along with implementing Nazariy's suggestions (which are both easy to get round if you really want to), you could also generate some unique value on the server side (i'll call it a token), which gets inserted into the same page as your Ajax. The Ajax would would then pass this token in with your other arguments to the process.php page whereupon you can check this token is valid.
UPDATE
see this question with regards to the token
anti-CSRF token and Javascript
You can not prevent people from manually emulating the submission of form data on your website. You can make it arbitrarily more difficult, but you won't be able to prevent it completely.

Resources