Leggere in inglese

Condividi tramite


Cookie SameSite e Open Web Interface per .NET (OWIN)

Di Rick Anderson

SameSite è una bozza IETF progettata per fornire una certa protezione contro attacchi di richiesta intersito falsa (CSRF). La bozza SameSite 2019:

  • Considera i cookie come SameSite=Lax per impostazione predefinita.
  • I cookie stati che asserisce SameSite=None in modo esplicito per abilitare il recapito tra siti devono essere contrassegnati come Secure.

Lax funziona per la maggior parte dei cookie dell'app. Per impostazione predefinita, alcune forme di autenticazione come OpenID Connect (OIDC) e WS-Federation vengono reindirizzati basati su POST. I reindirizzamenti basati su POST attivano le protezioni del SameSite browser, quindi SameSite è disabilitato per questi componenti. La maggior parte degli account di accesso OAuth non è interessata a causa delle differenze nel flusso della richiesta. Tutti gli altri componenti non sono impostati SameSite per impostazione predefinita e usano il comportamento predefinito dei client (vecchio o nuovo).

Il None parametro causa problemi di compatibilità con i client che hanno implementato lo standard bozza 2016 precedente (ad esempio, iOS 12). Vedere Supporto di browser meno recenti in questo documento.

Ogni componente OWIN che emette cookie deve decidere se SameSite è appropriato.

Per la versione ASP.NET 4.x di questo articolo, vedere Usare i cookie SameSite in ASP.NET.

Utilizzo dell'API con SameSite

Microsoft.Owin ha una propria SameSite implementazione:

  • Ciò non dipende direttamente da quello in System.Web.
  • SameSite funziona su tutte le versioni destinate ai Microsoft.Owin pacchetti, .NET 4.5 e versioni successive.
  • Solo il componente SystemWebCookieManager interagisce direttamente con la System.Web HttpCookie classe .

SystemWebCookieManager dipende dalle API .NET 4.7.2 System.Web per abilitare SameSite il supporto e dalle patch per modificare il comportamento.

I motivi per l'uso SystemWebCookieManager sono descritti in Problemi di integrazione dei cookie di risposta OWIN e System.Web. SystemWebCookieManager è consigliato quando si esegue in System.Web.

Il codice seguente imposta SameSite su Lax:

owinContext.Response.Cookies.Append("My Key", "My Value", new CookieOptions()
{
    SameSite = SameSiteMode.Lax
});

Le API seguenti usano SameSite:

Cronologia e modifiche

Microsoft.Owin non ha mai supportato lo SameSite standard draft 2016.

Il supporto per la bozza SameSite 2019 è disponibile solo nella Microsoft.Owin versione 4.1.0 e versioni successive. Non esistono patch per le versioni precedenti.

La bozza 2019 della SameSite specifica:

  • Non è compatibile con le versioni precedenti della bozza del 2016. Per altre informazioni, vedere Supporto di browser meno recenti in questo documento.
  • Specifica che i cookie vengono considerati come SameSite=Lax per impostazione predefinita.
  • Specifica i cookie che asserisce SameSite=None in modo esplicito per abilitare il recapito tra siti deve essere contrassegnato come Secure. None è una nuova voce da rifiutare esplicitamente.
  • È pianificata l'abilitazione di Chrome per impostazione predefinita nel febbraio 2020. I browser hanno iniziato a passare a questo standard nel 2019.
  • È supportato dalle patch rilasciate come descritto negli articoli della Knowledge Base. Per altre informazioni, vedere articoli della Knowledge Base che supportano SameSite in .NET Framework.

Supporto di browser meno recenti

Lo standard 2016 SameSite impone che i valori sconosciuti debbano essere considerati come SameSite=Strict valori. Le app a cui si accede da browser meno recenti che supportano lo standard 2016 SameSite possono interrompersi quando ottengono una SameSite proprietà con un valore .None Le app Web devono implementare il rilevamento del browser se intendono supportare browser meno recenti. ASP.NET non implementa il rilevamento del browser perché i valori degli agenti utente sono altamente volatili e cambiano frequentemente. Un punto di estensione in ICookieManager consente il plug-in logica specifica dell'agente utente.

In Startup.Configurationaggiungere codice simile al seguente:

public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        app.UseOpenIdConnectAuthentication(
             new OpenIdConnectAuthenticationOptions
             {
                 // … Your preexisting options … 
                 CookieManager = new SameSiteCookieManager(
                                     new SystemWebCookieManager())
             });

        // Remaining code removed for brevity.

Il codice precedente richiede la patch .NET 4.7.2 o successiva SameSite .

Il codice seguente illustra un'implementazione di esempio di SameSiteCookieManager:

public class SameSiteCookieManager : ICookieManager
{
    private readonly ICookieManager _innerManager;

    public SameSiteCookieManager() : this(new CookieManager())
    {
    }

    public SameSiteCookieManager(ICookieManager innerManager)
    {
        _innerManager = innerManager;
    }

    public void AppendResponseCookie(IOwinContext context, string key, string value,
                                     CookieOptions options)
    {
        CheckSameSite(context, options);
        _innerManager.AppendResponseCookie(context, key, value, options);
    }

    public void DeleteCookie(IOwinContext context, string key, CookieOptions options)
    {
        CheckSameSite(context, options);
        _innerManager.DeleteCookie(context, key, options);
    }

    public string GetRequestCookie(IOwinContext context, string key)
    {
        return _innerManager.GetRequestCookie(context, key);
    }

    private void CheckSameSite(IOwinContext context, CookieOptions options)
    {
        if (options.SameSite == Microsoft.Owin.SameSiteMode.None 
                             && DisallowsSameSiteNone(context))
        {
            options.SameSite = null;
        }
    }

Nell'esempio precedente viene DisallowsSameSiteNone chiamato nel CheckSameSite metodo . DisallowsSameSiteNone è un metodo utente che rileva se l'agente utente non supporta SameSite None:

private void CheckSameSite(IOwinContext context, CookieOptions options)
{
    if (options.SameSite == Microsoft.Owin.SameSiteMode.None 
                         && DisallowsSameSiteNone(context))
    {
        options.SameSite = null;
    }
}

Il codice seguente illustra un metodo di esempio DisallowsSameSiteNone :

Avviso

Il codice seguente è solo per dimostrazione:

  • Non deve essere considerato completo.
  • Non viene gestito o supportato.
public static bool DisallowsSameSiteNone(IOwinContext context)
{
    var userAgent = context.Request.Headers["User-Agent"];
    
    if (string.IsNullOrEmpty(userAgent))
    {
        return false;
    }
    
    // Cover all iOS based browsers here. This includes:
    // - Safari on iOS 12 for iPhone, iPod Touch, iPad
    // - WkWebview on iOS 12 for iPhone, iPod Touch, iPad
    // - Chrome on iOS 12 for iPhone, iPod Touch, iPad
    // All of which are broken by SameSite=None, because they use the iOS 
    // networking stack.
    if (userAgent.Contains("CPU iPhone OS 12") ||
        userAgent.Contains("iPad; CPU OS 12"))
    {
        return true;
    }

    // Cover Mac OS X based browsers that use the Mac OS networking stack. 
    // This includes:
    // - Safari on Mac OS X.
    // This does not include:
    // - Chrome on Mac OS X
    // Because they do not use the Mac OS networking stack.
    if (userAgent.Contains("Macintosh; Intel Mac OS X 10_14") &&
        userAgent.Contains("Version/") && userAgent.Contains("Safari"))
    {
        return true;
    }

    // Cover Chrome 50-69, because some versions are broken by SameSite=None, 
    // and none in this range require it.
    // Note: this covers some pre-Chromium Edge versions, 
    // but pre-Chromium Edge does not require SameSite=None.
    if (userAgent.Contains("Chrome/5") || userAgent.Contains("Chrome/6"))
    {
        return true;
    }

    return false;
}

Testare le app per problemi SameSite

Le app che interagiscono con siti remoti, ad esempio tramite l'accesso di terze parti, devono:

  • Testare l'interazione su più browser.
  • Applicare il rilevamento e la mitigazione del browser descritti in questo documento.

Testare le app Web usando una versione client che può acconsentire esplicitamente al nuovo SameSite comportamento. Chrome, Firefox e Chromium Edge hanno tutti nuovi flag di funzionalità di consenso esplicito che possono essere usati per i test. Dopo che l'app applica le SameSite patch, testarla con le versioni client precedenti, in particolare Safari. Per altre informazioni, vedere Supporto di browser meno recenti in questo documento.

Testare con Chrome

Chrome 78+ offre risultati fuorvianti perché ha una mitigazione temporanea sul posto. La mitigazione temporanea di Chrome 78+ consente i cookie meno di due minuti prima. Chrome 76 o 77 con i flag di test appropriati abilitati fornisce risultati più accurati. Per testare il nuovo SameSite comportamento, chrome://flags/#same-site-by-default-cookies passare a Abilitato. Le versioni precedenti di Chrome (75 e versioni successive) vengono segnalate come non riuscita con la nuova None impostazione. Vedere Supporto di browser meno recenti in questo documento.

Google non rende disponibili versioni chrome meno recenti. Seguire le istruzioni in Scaricare Chromium per testare le versioni precedenti di Chrome. Non scaricare Chrome dai collegamenti forniti cercando versioni precedenti di Chrome.

Eseguire test con Safari

Safari 12 ha implementato rigorosamente la bozza precedente e ha esito negativo quando il nuovo None valore è in un cookie. None viene evitato tramite il codice di rilevamento del browser Supporto dei browser meno recenti in questo documento. Testare gli account di accesso basati sul sistema operativo basati su Safari 12, Safari 13 e WebKit usando MSAL o qualsiasi libreria in uso. Il problema dipende dalla versione del sistema operativo sottostante. OSX Mojave (10.14) e iOS 12 sono noti per avere problemi di compatibilità con il nuovo SameSite comportamento. L'aggiornamento del sistema operativo a OSX Catalina (10.15) o iOS 13 risolve il problema. Safari non dispone attualmente di un flag di consenso esplicito per testare il nuovo comportamento della specifica.

Testare con Firefox

Il supporto di Firefox per il nuovo standard può essere testato sulla versione 68+ optando per la about:config pagina con il flag network.cookie.sameSite.laxByDefaultdi funzionalità . Non sono stati segnalati problemi di compatibilità con le versioni precedenti di Firefox.

Testare con il browser Edge

Edge supporta il vecchio SameSite standard. Edge versione 44 non presenta problemi di compatibilità noti con il nuovo standard.

Test con edge (Chromium)

SameSite nella pagina vengono impostati edge://flags/#same-site-by-default-cookies flag. Non sono stati rilevati problemi di compatibilità con Edge Chromium.

Test con Elettrone

Le versioni di Electron includono versioni precedenti di Chromium. Ad esempio, la versione di Electron usata da Teams è Chromium 66, che mostra il comportamento precedente. È necessario eseguire test di compatibilità personalizzati con la versione di Electron usato dal prodotto. Vedere Supporto di browser meno recenti nella sezione seguente.

Risorse aggiuntive