CryptographicException: il riempimento non è valido e non può essere rimosso e la convalida del viewstate MAC non è riuscita

StackOverflow https://stackoverflow.com/questions/1821243

Domanda

Monitorando i miei registri delle eccezioni globali questo errore sembra impossibile da rimuovere, qualunque cosa io faccia, pensavo di essermi finalmente liberato, ma è tornato di nuovo. Puoi vedere una traccia strack dell'errore su un post simile qui .

Note sull'ambiente:

IIS 6.0, .NET 3.5 SP1 server singolo applicazione ASP.NET

Passaggi già effettuati:

  <system.web>
    <machineKey validationKey="big encryption key"
      decryptionKey="big decryption key"
      validation="SHA1" decryption="AES" />

Nella mia pagina base per tutte le mie pagine

  protected override void OnInit(EventArgs e)
  {
    const string viewStateKey = "big key value";

    Page.ViewStateUserKey = viewStateKey;
  }

Anche nella fonte della pagina posso vedere che tutti i campi nascosti generati da ASP.NET sono correttamente nella parte superiore della pagina.

È stato utile?

Soluzione

Innanzitutto partiamo dal fatto che questo errore di stato di visualizzazione si verifica in PostBack .

Inoltre devo dire che ho fatto tutte le cose che ognuno suggerisce per evitare questo problema. E ho una sola macchina, ma 2 pool che eseguono le stesse pagine.

Quindi qualcuno fa un'azione , etera un uomo, etera qualche altra macchina di ricerca 'facendo clic' sulle tue pagine, o qualche hacker prova a controllare il tuo sistema per problemi ...

Ho problemi simili (rari ma esistenti) e ho finalmente scoperto che le persone cercano di hackerare le mie pagine. (dallo stesso IP che ho e dosano gli attacchi)

Modifico la funzione LoadPageStateFromPersistenceMedium () che traduce il viewstate e vede registrando quale esattamente era l'input e da quali IP ... quindi ho iniziato a monitorare questi risultati e vedere che lo stato di visualizzazione è stato modificato manualmente o completamente vuoto.

In caso di errore l'ho semplicemente reindirizzato alla stessa pagina ...

Ecco cosa ho fatto ...

public abstract class BasePage : System.Web.UI.Page
{
    protected override object LoadPageStateFromPersistenceMedium()
    {
        try
        {
            .. return the base, or make here your decompress, or what ever...
            return base.LoadPageStateFromPersistenceMedium();            
        }
        catch (Exception x)
        {
            string vsString = Request.Form[__VIEWSTATE];
            string cThePage = Request.RawUrl;

            ...log the x.ToString() error...
            ...log the vsString...
            ...log the ip coming from...
            ...log the cThePage...

        // check by your self for local errors
            Debug.Fail("Fail to load view state ! Reason:" + x.ToString());
        }

        // if reach here, then have fail, so I reload the page - maybe here you
        // can place somthing like ?rnd=RandomNumber&ErrorId=1 and show a message
        Responce.Redirect(Request.RawUrl, true);        

        // the return is not used after the redirect
        return string.Empty;
    }    
}

Secondo motivo

Ora c'è un altro motivo per cui questo può accadere, e il motivo è perché qualcuno fa clic sulla tua pagina prima che __EVENTVALIDATION sia caricato.

Questa eventValidation viene posizionata sull'ultimo pulsante, anche quello trovato da asp.net, e se ne hai alcuni in molti punti della pagina o vicino al pulsante, questo va alla fine della pagina.

Quindi, anche se vedi il viewstate nella parte superiore della pagina, dov'è la convalida ??? forse questa pagina non è mai stata caricata - corrotto?, clic dell'utente troppo veloce sulla pagina?

<input type="hidden" name="__EVENTVALIDATION" id="__EVENTVALIDATION" ... >

Per evitare questo tipo di problema, ho creato un semplice javascript per non lasciarlo premere il pulsante a meno che questo input non sia stato caricato !!!.

Un altro commento, __EVENTVALIDATION non è sempre presente! quindi è forse più sicuro non cercare questo campo se si crea una soluzione generale, ma fare un trucco javascript per controllare solo se la pagina intera è caricata o qualcos'altro che si pensa.

Ecco la mia soluzione finale con jQuery: (nota che controllo PageLoad se esiste una validazione dell'evento!). Ho inserito questo nei miei MasterPages.

<script language="javascript" type="text/javascript">
    function AllowFormToRun()
    {
        var MyEventValidation = $("#__EVENTVALIDATION");

        if(MyEventValidation.length == 0 || MyEventValidation.val() == ""){
            alert("Please wait for the page to fully loaded.");
            return false;
        }

        return true; 
    }       
</script>

protected void Page_Load(object sender, EventArgs e)
{
    // I do not know if Page can be null - just in case I place it.
    if (Page != null && Page.EnableEventValidation)
    {
        Form.Attributes["onsubmit"] = "return AllowFormToRun();";
    }
}

Puoi provare mettendo un attimo vicino al pulsante della tua pagina.

<% System.Threading.Thread.Sleep(5000); %>

Aggiornamento

Oggi vedo di nuovo nel registro questo messaggio per WebResource e quello che scopro è che un bot ottiene le pagine e crea tutti i caratteri sui collegamenti in minuscolo , inclusi i parametri, quindi questo era un motivo in più per non ottenere la stringa codificata corretta e inviare un messaggio come Il riempimento non è valido e non può essere rimosso.

Spero che questo ti aiuti di più.

Altri suggerimenti

Un sondaggio delle pagine Web trovate con diverse parole chiave del messaggio di errore indica che questo tipo di errore è relativamente comune, di solito casuale (almeno nell'aspetto) e purtroppo raramente inclusivo di un soluzione esplicita o spiegazione ...

L'esistenza di molte situazioni simili ma diverse è probabilmente legata alle moltissime architetture e configurazioni sottostanti che possono in qualche modo portare all'incapacità del livello crittografico di affermare l'autenticità del MAC (Message Authentication Codes) nel pagine di richiesta:

  • Installazione della server farm
  • Pagine incrociate / sindacate
  • librerie di widget di terze parti e simili
  • Logica effettiva del programma ASP (ovviamente)

Un marcatore "frequente" relativamente frequente attorno a queste segnalazioni di bug c'è la menzione di richieste di risorse (ad es. WebResource.axd ).
Si noti che tali richieste sono spesso non registrate (per evitare che gonfiano le dimensioni dei file di registro con un evento di scarso interesse). Questa assenza dal file di registro e il fatto che siano spesso memorizzati nella cache (e quindi la relativa occorrenza casuale e rara del bug) può spiegare come questa possibile origine del bug vada "sotto il radar". Ciò suggerisce anche che nel tentativo di ricreare il bug (durante il tracciamento nei registri, in tempo reale, ecc.) Può essere utile impedire la memorizzazione nella cache del browser Web (o almeno svuotare inizialmente la cache).

In breve, ecco alcune idee e cose da cercare:

  • inizia a registrare le richieste * .axd
  • prova a correlare tali richieste axd con gli eventi di errore nel registro delle eccezioni
  • cerca pagine con riferimenti a risorse
  • se in un ambiente Farm, assicurati che tutte le istanze utilizzino la stessa chiave (apparentemente lo snippet fornito nel suggerimento della domanda su più server IIS)
  • Diffidare delle pagine con legami di terze parti (servizi di ricerca, programmi di affiliazione ...)

Spero che questo aiuti ;-)

Sei sicuro che il tuo problema sia legato alla crittografia e non sia causato da ViewState di grandi dimensioni? Se ViewState è il problema, puoi smontarlo - modifica il valore di pages / MaxPageStateFieldLength in web.config

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top