Don't trust the URL... since POSTed data may hide what is really going on.
L'URL deve essere considerato come un valore lato client e non dovrebbe essere comunque considerato attendibile. Chiunque può facilmente modificare l'URL e potrebbe facilmente creare un POST a qualsiasi UserID
.
Anyone who can guess the route variable names in ASP.NET MVC, can put unexpected data into a controller
Questo può accadere comunque con la manomissione dei parametri. Ci sono alcuni suggerimenti utili in questa guida: link
In particolare
What Is It? Parameter tampering is an attack in which parameters are altered in order to change the application’s expected functionality. The parameters may be on a form, query string, cookies, database and so on. I’ll discuss attacks involving Web-based parameters.
How Is It Exploited? An attacker alters parameters to trick the application into performing an action it wasn’t intending. Suppose you save a user’s record by reading her user ID from the query string. Is this safe? No. An attacker can tamper with a URL in your application
In MVC ciò può avvenire tramite Model Binding:
Model binding is a great feature of Model-View-Controller (MVC) that helps with parameter checks as the properties on the Order object will automatically be populated and converted to their defined types based on the form information. ... Just be careful to limit what properties you allow to be populated and, again, don’t trust the page data for important items. ...
Note that I use the [Bind(Exclude)] attribute here to limit what MVC is binding into my Model in order to control what I do or don’t trust. This ensures the UserId won’t come from the form data and thus can’t be tampered with.
Quindi dovresti anche fare attenzione che i parametri del modulo che non esistono nella tua vista non possano essere manomessi e aggiunti da un utente malintenzionato. Lo faresti aggiungendo l'attributo Exclude
:
public ActionResult Edit([Bind(Exclude="UserId")] Order order)
Is this behavior consistent across other MVC frameworks (Rails etc)?
Non sono sicuro, ma non lo vedo come un difetto, dato che i controlli sui permessi dovrebbero essere fatti sia sui POST che sui tuoi GET. L'applicazione non deve presumere che un URL che è stato inserito in POST abbia il permesso di farlo solo perché quello della falsa affermazione che l'URL con il modulo su deve essere stato caricato per primo.
What are some ways to guard against this type of unexpected results? Should every POST be cross checked with URL parameters?
Il codice dovrebbe solo decidere di prendere la variabile route o la variabile POST (se è fornita da MVC come una variabile di metodo denominata UserID
, quindi perché non utilizzarla, non importa se era da POST dati o l'URL finché si è coerenti) e quindi prendere tutte le decisioni logiche basate su quello. Ciò include l'autorizzazione iniziale e anche la logica di elaborazione e di business: tutti dovrebbero utilizzare la stessa origine del valore per assicurarsi che le azioni vengano eseguite solo se autorizzate.