Condividi tramite


Stringhe di scopo in ASP.NET Core

I componenti che utilizzano IDataProtectionProvider devono passare un parametro univoco per scopi al CreateProtector metodo . Il parametro di scopo è intrinseco alla sicurezza del sistema di protezione dei dati, in quanto fornisce l'isolamento tra i consumatori di crittografia, anche se le chiavi crittografiche radice sono le stesse.

Quando un consumer specifica uno scopo, la stringa di scopo viene usata insieme alle chiavi di crittografia radice per derivare sottochiavi crittografiche univoche per tale consumer. In questo modo il consumer viene isolato da tutti gli altri consumer crittografici nell'applicazione: nessun altro componente può leggere i payload e non può leggere i payload di altri componenti. Questo isolamento rende anche impraticabili intere categorie di attacchi contro il componente.

Esempio di diagramma scopo

Nel diagramma precedente, IDataProtector le istanze A e B non possono leggere i payload dell'altro, solo i propri.

La stringa di scopo non deve essere segreta. Dovrebbe essere semplicemente univoco nel senso che nessun altro componente che si comporta correttamente fornirà mai la stessa stringa finalizzata.

Suggerimento

L'uso dello spazio dei nomi e del nome del tipo del componente che utilizza le API di protezione dei dati è una buona regola generale, perché in pratica queste informazioni non saranno mai in conflitto.

Un componente creato da Contoso responsabile della generazione di token al portatore potrebbe usare Contoso.Security.BearerToken come identificatore di scopo. Oppure, ancora meglio, potrebbe usare Contoso.Security.BearerToken.v1 come stringa di scopo. L'aggiunta del numero di versione consente a una versione futura di usare Contoso.Security.BearerToken.v2 come scopo e le diverse versioni saranno completamente isolate l'una dall'altra per quanto riguarda i payload.

Poiché il parametro a scopo di CreateProtector è una matrice di stringhe, è possibile che il parametro precedente sia stato specificato come [ "Contoso.Security.BearerToken", "v1" ]. Ciò consente di stabilire una gerarchia di scopi e apre la possibilità di scenari multi-tenancy con il sistema di protezione dei dati.

Avvertimento

I componenti non devono consentire che l'input utente non attendibile sia l'unica origine di input per la catena dei processi.

Si consideri ad esempio un componente Contoso.Messaging.SecureMessage responsabile dell'archiviazione di messaggi sicuri. Se il componente di messaggistica sicura dovesse chiamare CreateProtector([ username ]), allora un utente malintenzionato potrebbe creare un account con nome utente "Contoso.Security.BearerToken" nel tentativo di far sì che il componente chiami CreateProtector([ "Contoso.Security.BearerToken" ]), causando inavvertitamente al sistema di messaggistica sicura di creare payload che potrebbero essere percepiti come token di autenticazione.

Una catena di scopi migliore per il componente di messaggistica è CreateProtector([ "Contoso.Messaging.SecureMessage", $"User: {username}" ]), che fornisce un isolamento appropriato.

L'isolamento fornito da e i comportamenti di IDataProtectionProvider, IDataProtector, e le finalità sono i seguenti:

  • Per un determinato IDataProtectionProvider oggetto, il CreateProtector metodo creerà un IDataProtector oggetto associato in modo univoco all'oggetto IDataProtectionProvider che lo ha creato e al parametro di scopo passato al metodo .

  • Il parametro purpose non deve essere Null. Se gli scopi vengono specificati come array, significa che l'array non deve avere lunghezza zero e tutti gli elementi dell'array devono essere non nulli. Un scopo di stringa vuota è tecnicamente consentito, ma è sconsigliato.

  • Due argomenti di scopo sono equivalenti se e solo se contengono le stesse stringhe (usando un operatore di confronto ordinale) nello stesso ordine. Un argomento a scopo singolo equivale alla matrice a scopo singolo elemento corrispondente.

  • Due IDataProtector oggetti sono equivalenti se e solo se vengono creati da oggetti equivalenti con parametri di scopo equivalenti IDataProtectionProvider .

  • Per un determinato IDataProtector oggetto, una chiamata a Unprotect(protectedData) restituirà l'originale unprotectedData se e solo se protectedData := Protect(unprotectedData) per un oggetto equivalente IDataProtector .

Annotazioni

Non viene considerato il caso in cui alcuni componenti scelgono intenzionalmente una stringa di scopo che è nota per essere in conflitto con un altro componente. Tale componente sarebbe essenzialmente considerato dannoso e questo sistema non è progettato per fornire garanzie di sicurezza nel caso in cui il codice dannoso sia già in esecuzione all'interno del processo di lavoro.