In che modo gli sviluppatori devono gestire le variabili del modulo POST in conflitto con le variabili di percorso?

1

In ASP.NET MVC, quando eseguo un post HTTP su /controller/action/UserID ...

e avere una route corrispondente /controller/action/{UserID} ...

e se faccio un Form POST, il dato POSTed UserID sovrascrive tutto ciò che la rotta era originariamente dice. (almeno lo fa in ASP.NET MVC4)

Per me questo dice alcune cose:

  • Non fidarti dell'URL ... dato che i dati POST possono nascondere ciò che sta realmente accadendo.
  • Chiunque possa indovinare i nomi delle variabili di percorso in ASP.NET MVC, può inserire dati inattesi in un controller

  • ....?

Domande

  • Questo comportamento è coerente con altri framework MVC (Rails, ecc.)?
  • Quali sono alcuni modi per evitare questo tipo di risultati imprevisti? Ogni cross deve essere verificato con i parametri URL?
posta random65537 26.11.2013 - 01:26
fonte

2 risposte

1

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)] attrib­ute 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.

    
risposta data 27.11.2013 - 11:41
fonte
0

Se si desidera separare o distinguere le azioni GET / POST, è necessario utilizzare l'attributo AcceptVerbs . Ad esempio, per forzare un'azione a rispondere solo alle richieste POST, aggiungere ad essa il seguente attributo:

[AcceptVerbs(HttpVerbs.Post)]

E aggiungi anche quanto segue a GET uno

[AcceptVerbs(HttpVerbs.Get)]

In questo modo, puoi garantire che solo i tipi di richiesta desiderabili (GET, POST, ...) possano toccare il metodo di azione.

E sull'altro lato della tua domanda, c'è un attacco web relativo a tutti i framework MVC chiamato Over Posting e può essere verificato se ti basti completamente sul modello di raccoglitore. Per prevenire questo attacco, hai due modi:

  • Utilizzo di Visualizza modelli
  • Uso dell'attributo Bind

Penso che il primo sia chiaro. E circa il secondo, puoi rafforzare un metodo di azione POST come il seguente:

[AcceptVerbs(HttpVerbs.Get)]     
public ActionResult AddComment([Bind(Include = "Name, Email, CommentText")] Comment model)

Inoltre, l'attributo Bind può anche essere aggiunto alla definizione del modello stesso.

    
risposta data 17.03.2015 - 07:53
fonte