Code igniter authentication code in controller security question - php

I have a main controller to handle the very front-end of my authentication system, it handles login, logout, update user info, etc. functions that I anticipate calling by POST'ing from views/forms. What about something like a "delete_user" function though? My thoughts are a button in someones admin panel would say "Delete Account" and it would post to "/auth/delete", and the function would delete the user based on their session username or id. This seems a bit open ended, you could send out a link to someone and when they opened it while in that application it would delete their account.. Whats the best way to handle this?

What you are concerned about is actually called Cross Site Request Forgery, or XSRF. You can read more about it on the OWASP Website.
A few things that you should do overcome this problem -
Use POST for the delete operation. This doesn't protect you from XSRF, but protects you from link followers/page accelerators. Its also a http best practice.
Post your session identifier in the body of the request. On the server side, compare the session identifier from cookie and from the request - if they are different, reject the request. This is the "double submit cookie" method to prevent XSRF.
Alternatively, you can ask the user to solve a captcha.
Additionally, a "soft-delete" on the lines of what Tom mentions is also a good idea.

It sounds like adding some other piece of information to the function is the answer. Here is the function in question:
function delete() {
$id = $this->session->userdata('user_id');
$this->auth->delete_user($id);
redirect('home');
}
In code igniter this can be accessed by just visiting site.com/class/delete which is my problem. I think a good plan will be to post an authentication token (saved in cookie) with the delete button, so it can't take action via the URL:
function delete() {
if($this->input->post("token") == $this->session->userdata('token')) {
$id = $this->session->userdata('user_id');
$this->auth->delete_user($id);
}
redirect('home');
}
I don't think i need a soft-delete right now, but thank you for that good tip! If you see any other issues please explain, thank you.

The way i handle this is as follows. On your account page you have a link to delete the account. They click that page and are greeted with another page asking if they are really sure and if so please enter their password to confirm they are sure.
After they do that i deactivate their account (not delete) and send an email saying that their account was deactivated and if this was intended no other action is needed on their part. If it was not intended they can login to their account and it will reactivate it. (within 48 hours) after 48 hours i delete their account and information.

Have a look at one of the better known authentication libraries for CodeIgniter:
https://github.com/benedmunds/CodeIgniter-Ion-Auth
If you don't decide to just use it, you can at least get some good ideas about how to go about creating your own

Related

How to prevent someone misusing routing systems?

I'm using a routing system. You can use the url to do some quick updates etc, without having to create a page for it. I believe this to be very effective. Though, how can I prevent a user misusing it?
This line updates a users account:
http://localhost:8080/Basic/Route/User/update/permissions>1/29
Class: User
Method: update
Set permissions => 1
Where id is 29
It works very nice, but any user could be able to type this in his URL if he knew in what way the system works.
Are there any ways to prevent misuses like this one?
Thanks!
You should implement User Authentication, then check if user is logged in and if he has required permissions. I don't see any other way to do it simpler.
Add a CSRF token and it might be fine. I would also make it a POST request instead of GET if it isn't already.
If you don't secure your URLs/forms this way users might be tricked into performing actions they didn't intend to (e.g. by visiting a link from another website or an email).

Direct URLs & delete confirmation forms

I am seeking a best practice advice for implementing delete confirmation forms.
The following page, among other options, contains delete button...
/website/features/f/123
...when clicked a simple form gets loaded under following url:
/website/features/f/delete/123
A user has to confirm deletion in a simple delete confirmation form. Delete button gets enabled after the 'check to confirm' checkbox is checked.
All good and clear, however I am concerned that providing direct URLs to delete options may lead to... say, situations that could be avoided.
Is there a better way of handling this scenario? Perhaps referer validation?
The most common "situations that could be avoided" are:
Bots following links (e.g. to precache results). Avoid this problem by ensuring that the URL requires a request to use an HTTP method that is not safe such as POST and not GET.
CSRF attacks as covered by this other question
Actually deleting something should required the user to be logged in to the site and you should check that this user has the necessary permission to actually delete something. If your use case permit that something can be delete publicly, then it doesn't really matters if the confirm is checked or not (think trolls). If your user has the permission to delete something, then there shouldn't be any problem except if mistype something in the URL.
To avoid this you can also implement the DELETE http request (think REST). A combination of permission and DELETE should be enough to avoid bypassing the confirm dialog.
Another solution could be to implement validation token. The confirm dialog generate a secret token that needs to be validated by the delete action.
I implemented my initial referer idea. But as always I am open for suggestions and constructive criticism.
if(empty($_SERVER['HTTP_REFERER'])) $this->_app->redirect('/website/features', 302);
Note that this is a slim based redirect.

Get request host in PHP

I'm developing a website by Zend.
Some people create a html file imitate my login view. Action in form point to my controller to submit.
I don't other login outsite from my websites. So how can I prevent other domains submit form to my controller?
I tried to get request host name of "requester pages" to compare theirs domain with mine, then return error if user login from other sites.
Check the ZF manual for CSRF protection, which is the standard, built-in way to solve this problem.
you could check the refferer if it is in your domain (or empty)
add a hidden input field an generate a token on every display. if the token is wrong, don't continue and redirect them to your login page.
Be sure that every token can only used once, by one user (same session/ip) and only for e.g. 1 hour
EDIT: see https://www.owasp.org/index.php/Cross-Site_Request_Forgery_%28CSRF%29_Prevention_Cheat_Sheet
there would be easiest way to prevent out side users to login into your site
user zend captcha to generate every time new code to login session
you can use below link as reference to use in login page
http://mnshankar.wordpress.com/2010/06/01/zend-form-element-captcha/

Ask for HTTP authentication only when user is trying to authenticate

What I think of is detecting authentication attempt and logging user in using PHP and standart HTTP credentials without bugging him with popup, when he does not try to login. That may sound easy, but we must keep in mind, that browsers check whether site is requesting authentication, and when it does not, they are bugging user with warning and they also send no data.
Is there any bypass? Any trick?
QUESTION SUMMARY:
I want url http://example.com/site to work wihout any promts and popups. User will see the site as anonymous.
I want url http://user:password#example.com/site to work without any popups too. User will see the site as user
To answer your question: no there is no way around it. The browser will not send the authentication information if it has not been requested by the website, and as you have discovered, it will also show an annoying security warning to the user. You should bite the bullet and use a GET param.

PHP form posting to prevent navigation/reposting problems

I have created a user registration form using PHP/smarty. The form posts back to itself since I don't know of any reason not to do it this way. The problem here is that if the user refreshes the welcome page, the code will attempt to recreate the account. What is the best way to do this from both a user and security perspective?
if (isset($_POST['submit'])) {
/* Create customer account */
$smarty->display($welcome_template);
} else {
$smarty->display($form_template);
}
after the account has successfully been created, do a HTTP redirect and send them to a separate "success" page: http://en.wikipedia.org/wiki/Post/Redirect/Get
I guess that is a reason to not do it this way. I think the standard solution is the Post/Redirect/Get pattern, which means: make the POST request and then redirect to a GET request to a confirmation page. That page can then be reloaded without any problem.
the user may of course try to recreate their account at any time, so care must be taken for that.
For your needs, as post-action page shows confirmation,
the easiest solution would be
//at end of post-action
echo '<script type="text/javascript">document.location = 'yoururl?cmd=confirm</script>';
die();
regards,
//t

Categories