I somewhat understand how [ValidateAntiForgeryToken]
prevents CSRF and I have read through this question, but I'm unsure whether this would prevent someone from falsifying the parameters for a form post.
ItemList
has an Items
property that is a collection of items and a User
property that is a reference to the ApplicationUser
that it belongs to. Item
has an ItemList
property that is a reference to the list it belongs to. Here are the Add methods in the ItemController:
// GET: Item/Add/4 (Adds new Item to the ItemList with ID=4)
public ActionResult Add(int? itemListId)
{
// Gets the current user and the ItemList that the Item will be added to
UserManager<ApplicationUser> userManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(db));
ApplicationUser currentUser = userManager.FindById(User.Identity.GetUserId());
ItemList itemList = db.ItemLists.Find(itemListId);
// Makes sure that ItemList exists and belongs to the user
if (itemList == null || itemList.User != currentUser)
{
return View("InsufficientPerm");
}
ViewBag.ItemListId = itemListId;
return View();
}
// POST: Item/Add/4 (Adds new Item to the ItemList with ID=4)
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Add([Bind(Include = "ID,Name")] Item item, int? itemListId)
{
if (ModelState.IsValid)
{
ItemList itemList = db.ItemLists.Find(itemListId);
item.ItemList = itemList;
db.Items.Add(item);
itemList.Items.Add(item);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(item);
}
My question is whether [ValidateAntiForgeryToken]
would prevent a user from falsifying the itemListId
parameter during the post, or if I would need to put another if (itemList == null...
check in the post method.
Edit: Here is the logic that I am looking at right now:
- The use of
ValidateAntiForgeryToken
forces a user to access the first method (therefore loading the view) in order for a post to be accepted. If they don't load that view, then there will be no anti-forgery token. - The user will go to the form webpage (let's say
http://foo.bar/Item/Add/3
) - The user will fill out and submit the form, which would call the post method (in this case
itemListId=3
because that's the webpage that was accessed) - There is no way for a user to pass a different itemListId to the above step, because it is passed by the webpage when they submit the form
Now, please let me know if there is something wrong with what I have stated above, or if that logic is correct (meaning that I don't need to check the validity of itemListId during the post). PLEASE give an example or a link to clarify where my logic is incorrect