Avoiding unauthorized access to a page by changing the URL query parameter in mvc3 - asp.net-mvc-3

I'm new in mvc and I have a question: If I have Index page (page with list of some object this is url http://localhost:6384/admin/) and I have actionlink button on which when user clicks he gets details of that object this is url http://localhost:6384/Admin/Apartman/details/1.
ID of obejct is 1, but if user change value 1 to some other value he will get some other object which maybe he shouldn't be able to see it.
What can I do to protect application?

The way i do it is simply checking whether the user has access to that object.
public ActionResult EditProfile(int id)
{
ApartmentViewModel objVM=MyService.GetApartment(id);
if(objVM.CreatedById==id)
{
return View(objVM);
}
else
{
return View("UnAuthorized");
}
}

Related

Redirecting to a page if session object expires or user did not login to the application

This is a mvc application
I have the links below on my master page
Link1 Link2 Link3 signout signIn
I have a userprofile object that is populated
when authentication is done.
When the session object for the user expires
and I click on the links, I get the yellow page(error page).
I will prefer a situation where when you click on the
links and the session object is expired, you get
redirected to the signin page.
Soln A: I could solve this problem by writing a method
which test for null value of the userprofile object then
make a call to this method on the click on every link.
I dont want this approach because in the future if there
are new controllers, i will need to care for them.
Do you have any idea how I can solve this problem?
I would have a Base Controller than all of your other controllers inherit from. Within this I would have a
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
if (SessionManager.Instance() == null)
{
filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary
{
{ "Controller", "BaseController" },
{ "Action", "LogOn" }
});
}
base.OnActionExecuting(filterContext);
}
The OnAction Executing will be hit before any method in any of your controllers - this way you can check your session is valid or your user is valid or whatever and handle the redirect to the view you want if that is not the case. If you do a Google search for Filters Actions MVC you will find out much more info.

asp.net mvc3 how to pass ID variable but without in browser

I was wondering how can I pass my primary-key int ID myid into a .tolist method that uses a for each loop
VIEW
#foreach (var item in Model)
{
#Html.ActionLink("View", "detail", new { id = item.myid})
#Html.ActionLink("Add Pictures", "pictures")
}
the .tolist controller
[Authorize]
public ActionResult mylist(list listings)
{
var showlist = (from s in db.list where getid == s.RegistrationID select s).ToList();
return View(showlist.ToList());
}
As you can see from above i do have the [authorize] notation on mylist which is were the foreach statement is on so people are logged on already. My question is were can I put the int myid in the #Html.ActionLink("Add Pictures", "pictures") ?? I do not want to have it in the Browser since then users can easily put in different numbers and view other peoples pictures .
You should be passing the id in the url
#Html.ActionLink("Add Pictures", "pictures",new { #id=item.ID})
And in your pictures action method, you should check whether the current User is a logged (Authentication) in user and he has proper permission to add picture (Authorization).
public ActionResult pictures(int id)
{
//TO DO : Check the user has sufficient permission to add pictures.
// The implementation of this checking is completely up to you.
// If not authorized redirect to a view to show the "Not authorized" message
}
Can't you just prevent people from looking at other people's pictures by checking if their user id matches the picture's owner's id?
You have to pass the id to the user, you can't avoid it.
That's not where you stop this kind of "hacking". In your controller or somewhere else, you do a check if the current authenticated user owns that photo and redirect him to a page that says "no picture found" - or something similar.

How to redirect to action from model

I have an app that uses a large model. It takes five view pages to collect all of the data. I am keeping the model in session between view pages. Sometimes the session dies after inactivity in the middle of the process. When this happens, I want to push the user back to the Home page.
Here is part of my model:
private MemberRegistration MemberRegistration {
get {
if (HttpContext.Current.Session["RegisterModel_MemberRegistration"] == null)
{
return null;
>>>> I want to go back the home page here <<<<
}
return (MemberRegistration)HttpContext.Current.Session["RegisterModel_MemberRegistration"];
}
set {
HttpContext.Current.Session["RegisterModel_MemberRegistration"] = value;
}
}
public string FirstName {
get {
return MemberRegistration.FirstName;
}
set {
MemberRegistration.FirstName = value;
}
}
My problem is this. The model binding begins when the user clicks the "Next" button. The model binding happens before the [HTTPPost] controller action. If the session has expired, we hit the "return null" line. I want to send the user back to the home page right then.
A secondary question - is there a better way to do this other than using the Session. (Please don't suggest that we keep the partial registration in the database. I'd rather have the problems with keeping it in the Session than the problems that arise from having a partial record in the database.)
Thank you very much!
Alternative: Use jQuery UI and create Tabs. Use 5 tabs on single view page instead of 5 view pages - you won't have to break your model to pieces.
http://jqueryui.com/demos/tabs/

MVC3 - RedirectToAction from Edit page back to Details page with parameter

I have a master detail scenario going from a list of categories to ingredients.
In the Edit ActionResult I have:
if (ModelState.IsValid){
dc.Entry(mainingredient).State = EntityState.Modified;
dc.SaveChanges();
int ID = ?????
return RedirectToAction("Details", new { id = ID});
}
...
I am basically trying to go back to the page I came from.
For example... from /Ingredient/Edit/2 back to Ingredient/Details/2
To make this question clearer:
how do I pass an id from the edit get to edit httppost controller so that I can redirect the user back to the details page again passing the id after they make an update?
You could pass a url query string parameter to the Edit action when invoking it. This way you will be able to redirect to:
public ActionResult Edit(string returnUrl)
{
...
return Redirect(url);
}
or if you already know the controller and action:
return RedirectToAction("Details", new { id = ID });
will be sufficient. The ID you want to redirect back could be passed as action argument.

How to prevent duplicate form submission in ASP.NET MVC 3?

I have a razor view that renders a html form and it posts to the server.
If the form values are right then it gets saved to database.
After insertion, I redirect to another view where user can make further changes.
Right now the user can hit browser back button and resubmit the form to create another record in db.
How do I prevent duplicate submission in my MVC app?
One solution is to put a hidden "token" field on the form that's generated randomly when the form loads. When you see that token come back on creation store it somewhere temporarily (in session if you're using sessions for example). If you see the same one again, you can assume the same form was submitted twice quickly together.
Create a cookie to represent that particular page when it succeeds. If it is replayed with the cookie (which the browser would now send over with every request) you know not to allow the new attempt.
Redirect the user to another HttpGet action after handling the post request.
So that when the user refreshes the browser the post action will not be called again.
return RedirectToAction("YourActionMethod");
Although client side validation is possible, it is not secure enough.
I am not sure if this method applies to MVC 3, but what i did is implement a ActionFilterAttribute
here is the implementation:
public class PreventFrequentCallsAttribute : ActionFilterAttribute
{
public int DelayRequest = 5;
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
var request = filterContext.HttpContext.Request;
var cache = filterContext.HttpContext.Cache;
var originationInfo = request.ServerVariables["HTTP_X_FORWARDED_FOR"] ?? request.UserHostAddress;
originationInfo += request.UserAgent;
var targetInfo = request.RawUrl + request.QueryString;
var hashValue = string.Join("", MD5.Create().ComputeHash(Encoding.ASCII.GetBytes(originationInfo + targetInfo)).Select(s => s.ToString("x2")));
if (cache[hashValue] != null)
{
filterContext.Controller.ViewData.ModelState.AddModelError("ExcessiveRequests", "Excessive Request Attempts Detected.");
}
else
{
cache.Add(hashValue, originationInfo, null, DateTime.Now.AddSeconds(DelayRequest), Cache.NoSlidingExpiration, CacheItemPriority.Default, null);
}
base.OnActionExecuting(filterContext);
}
}
later, in the target controller, just add this attribute:
[PreventFrequentCalls(3)]
public PartialViewResult LogOn(LogOnViewModel model)

Resources