Linee guida per la sicurezza di ACS

Aggiornamento: 19 giugno 2015

Si applica a: Azure

Si applica a

  • Microsoft Azure Active Directory Access Control (anche noto come Servizio di controllo di accesso o ACS)

  • Windows Identity Foundation (WIF)

Riepilogo

Questo argomento consolida le linee guida per la sicurezza per ACS. Attenersi a tali linee guida per aumentare il livello di sicurezza dell'implementazione. Sono infatti utili per verificare l'architettura dell'applicazione, esaminare i bug di sicurezza del codice e della registrazione e controllare la distribuzione di produzione. Queste linee guida ti fanno riferimento per altre informazioni su Come usare i passaggi prescrittivi per eseguire un'attività specifica e per altre informazioni su una determinata funzionalità o funzione di ACS.

Obiettivi

  • Risolvere i problemi di sicurezza correlati al codice e alla configurazione di un'applicazione nel contesto di ACS.

  • Risolvere i problemi di sicurezza correlati alle configurazioni di ACS.

  • Risolvere i problemi di sicurezza correlati alle distribuzioni di Azure nel contesto di ACS.

Di seguito sono riportate le linee guida di sicurezza relative al codice e alla configurazione dell'applicazione.

  • Considerare la possibilità di impostare la funzionalità di rilevamento della riproduzione (DetectReplayedTokens) su true.

  • Impostare l'attributo requireHttps di wsFederation su true.

  • Impostare l'attributo requireSsl di cookieHandler su true.

  • Impostare un intervallo di tempo molto breve per l'attributo lifetime di sessionTokenRequirement.

  • Elencare i servizi token di sicurezza (autorità emittenti dei token) attendibili in issuerNameRegistry.

  • Definire l'ambito dei token che devono essere accettati dall'applicazione usando audienceUri.

Considerare la possibilità di impostare la funzionalità di rilevamento della riproduzione (DetectReplayedTokens) su true

In WIF è disponibile una cache di rilevamento della riproduzione specifica per i token "bearer" del servizio token di sicurezza (STS), che è semplicemente una cache dei token STS usati in precedenza. Quando il client si autentica nella relying party usando il token STS, riceve un token di sicurezza della sessione che usa per autenticarsi nella relying party per qualsiasi richiesta aggiuntiva. Ciò avviene su SSL (Secure Sockets Layer), in modo che il token di sicurezza della sessione non possa essere rubato. Se un client o un malintenzionato tenta di autenticarsi nella relying party con un token STS già usato dal client, la relying party può ricercare il token STS nella cache di rilevamento della riproduzione e rifiutare la richiesta.

Tale cache tuttavia non garantisce che un token non possa mai essere riprodotto. Esegue il miglior rilevamento possibile in base alla propria dimensione, alla scadenza del token STS e al numero di richieste di autenticazione univoche ricevute dalla relying party. È consigliabile impostare la dimensione della cache e la scadenza del token STS per la relying party in modo da bilanciare prestazioni e sicurezza.

Esempio:

<securityTokenHandlers>
  <securityTokenHandlerConfiguration>
    <tokenReplayDetection enabled="true" capacity="1000" expirationPeriod="500"/>
  </securityTokenHandlerConfiguration>
</securityTokenHandlers>

Nota

Con questa funzionalità viene usato il meccanismo di affinità del server che può causare problemi di scalabilità negli ambienti con bilanciamento del carico, incluso Azure. Per ovviare al problema, considerare la possibilità di implementare un proprio meccanismo di rilevamento della riproduzione dei token usando una classe astratta di base Microsoft.IdentityModel.Tokens.TokenReplayCache e facendovi riferimento nel file di configurazione con codice simile al seguente.

<system.identityModel>
  <identityConfiguration>
    <tokenReplayDetection>
      <replayCache type='FQTN of your type' />
    </tokenReplayDetection>
  </identityConfiguration>
</system.identityModel>

Impostare l'attributo requireHttps di wsFederation su true

L'attributo requireHttps determina se il modulo reindirizzerà soltanto un URL sicuro per il servizio token di sicurezza. Il valore predefinito è "true". Ciò garantisce comunicazioni sicure con il servizio token di sicurezza con traffico HTTPS/SSL non crittografato, limitando la sottrazione di credenziali e token durante la trasmissione.

Esempio:

<federatedAuthentication>
  <wsFederation
        passiveRedirectEnabled="true"
        issuer="http://STS URL GOES HERE/"
        realm="http://RP REALM GOES HERE/"
        requireHttps="ture" />
  <cookieHandler requireSsl="true" />
</federatedAuthentication>

Impostare l'attributo requireSsl di cookieHandler su true

Questo valore è booleano e l'impostazione predefinita è false. L'attributo requireSsl determina se viene emesso il flag "Secure" per i cookie scritti. Se si imposta questo valore, i cookie della sessione di accesso saranno disponibili soltanto su HTTPS. Ciò impedisce l'invio di cookie di sessione nel traffico non crittografato, limitando il rischio di sottrazione del token durante la trasmissione.

Esempio:

<federatedAuthentication>
  <wsFederation
        passiveRedirectEnabled="true"
        issuer="http://STS URL GOES HERE/"
        realm="http://RP REALM GOES HERE/"
        requireHttps="ture" />
  <cookieHandler requireSsl="true" />
</federatedAuthentication>

Impostare un intervallo di tempo molto breve per l'attributo lifetime di sessionTokenRequirement

Considerare la possibilità di richiedere che i token vengano rilasciati con limiti di durata molto brevi. In questo modo, si limita il tempo a disposizione di un malintenzionato per riprodurre un eventuale token rubato.

Esempio:

<add type="Microsoft.IdentityModel.Tokens.SessionSecurityTokenHandler, Microsoft.IdentityModel">
  <sessionTokenRequirement securityTokenCacheType="Microsoft.IdentityModel.MruSecurityTokenCache, Microsoft.IdentityModel"
                           saveBootstrapTokens="true"
                           securityTokenCacheSize="500"
                           useWindowsTokenService="false"
                           lifetime="10:00" />
</add>

Elencare i servizi token di sicurezza (autorità emittenti dei token) attendibili in issuerNameRegistry

Tutti i token delle autorità emittenti vengono convalidati mediante IssuerNameRegistry, il cui scopo è quello di mappare il token di tali autorità a un nome di stringa. Se la convalida ha esito negativo, il token non verrà accettato. Ciò limita il rischio che vengano accettati token non attendibili. Qualsiasi tipo personalizzato può essere registrato usando l'attributo type dell'elemento <issuerNameRegistry> . L'emittenteNameRegistry <> può avere un elemento figlio che fungerà da configurazione personalizzata per IssuerNameRegistry. Viene fornito un tipo di IssuerNameRegistry predefinito, ConfigurationBasedIssuerNameRegistry, che può essere usato per configurare un insieme di certificati di autorità emittenti attendibili in configurazione. Questo tipo richiede un elemento <di configurazione figlio trustedIssuers in cui sono configurati> i certificati di autorità di certificazione attendibili. <La configurazione trustedIssuers> aggiunge certificati attendibili usando la forma codificata ASN.1 dell'identificazione personale del certificato.

Esempio:

<issuerNameRegistry type="Microsoft.IdentityModel.Tokens.ConfigurationBasedIssuerNameRegistry, Microsoft.IdentityModel">
  <trustedIssuers>
    <add thumbprint="97249e1a5fa6bee5e515b82111ef524a4c9158de" name="contoso.com" />
    <remove thumbprint="97249e1a5fa6bee5e515b82111ef524a4c9158de" />
    <clear/>
  </trustedIssuers>
</issuerNameRegistry>

Definire l'applicazione come ambito per i token usando solo audienceUri

<audienceUris> specifica il set di URI che sono accettabili come identificazione di questa relying party. I token non verranno accettati se non hanno come ambito uno degli URI dei gruppi di destinatari consentiti. Ciò limita il rischio di riprodurre token validi rilasciati per altre relying party. Per impostazione predefinita, alla raccolta non verranno aggiunti URI. L'elemento SecurityTokenHandler per i tipi di token SAML 1.1 e SAML 2.0 usa i valori di questa raccolta per configurare qualsiasi restrizione relativa agli URI dei gruppi di destinatari consentiti negli oggetti SamlSecurityTokenRequirement.

Esempio:

<audienceUris>
  <clear/>
  <add value="http://www.example.com/myapp/" />
  <remove value="http://www.example.com/myapp/" />
</audienceUris>

Di seguito sono riportate le linee guida per la sicurezza correlate alla configurazione del portale di gestione di ACS.

  • Impostare una scadenza molto breve per i token STS

  • Fornire una convalida dei dati adeguata quando si usa la funzionalità URL errori

  • Considerare la possibilità di crittografare i token per gli scenari particolarmente sensibili

Impostare una scadenza molto breve per i token STS

L'attributo lifetime del token determina la durata, Viene specificato quando si crea o si configura la relying party usando il portale di ACS o il servizio di gestione. È possibile usare la proprietà Durata token per specificare la quantità di tempo per un token di sicurezza rilasciato da ACS all'applicazione relying party per rimanere validi. Per impostazione predefinita, in ACS questo valore è impostato su 10 minuti (600 secondi). In ACS questo valore deve essere maggiore di zero, ma minore o uguale a 24 ore (86400 secondi).

Fornire una convalida dei dati adeguata quando si usa la funzionalità URL errori

È possibile usare l'URL di errore per specificare un URL a cui ACS reindirizza gli utenti se si verifica un errore durante il processo di accesso. Può essere una pagina personalizzata ospitata nell'applicazione relying party, ad esempio http://www.fabrikam.com/billing/error.aspx. Nell'ambito del reindirizzamento, ACS fornisce informazioni dettagliate sull'errore dell'applicazione relying party come parametro URL HTTP con codifica JSON. La pagina di errore personalizzata può essere impostata in modo da usare le informazioni sull'errore con codifica JSON per eseguire il rendering dell'effettivo messaggio di errore ricevuto o per visualizzare un testo statico della Guida. Se la pagina richiede l'autorizzazione, il risultato sarà un ciclo di reindirizzamento infinito in un caso in cui ACS tenterà di accedervi e invierà l'errore con codifica JSON. Deve pertanto essere configurata per l'accesso anonimo. Poiché la pagina è accessibile in modo anonimo e può includere codice che esegue l'eco dell'HTML o scrive dati nel database, è consigliabile impedire gli attacchi tramite script da altri siti e gli attacchi SQL injection.

Considerare la possibilità di crittografare i token per gli scenari particolarmente sensibili

Per gli scenari particolarmente sensibili, considerare la possibilità di crittografare i token per la federazione passiva. Altre informazioni sulla crittografia e la decrittografia del token nell'argomento Certificati e chiavi .

Di seguito sono riportate le considerazioni sulla sicurezza correlate alle applicazioni che usano ACS e che vengono distribuite in Azure.

  • Crittografare i cookie mediante RSA

Crittografare i cookie mediante RSA

In Azure il meccanismo di crittografia dei cookie predefinito, basato su interfacce DPAPI (Data Protection Application Programming Interface), non è adatto perché ciascuna istanza dispone di una chiave diversa. Questo significa che un cookie creato da un'istanza del ruolo Web non è leggibile da un'altra istanza del ruolo Web. Ciò può causare malfunzionamenti del servizio, portando anche a una situazione di Denial of Service. Di seguito viene riportato un messaggio di errore simile a quello che viene visualizzato se si usa il meccanismo di crittografia dei cookie predefinito:

[CryptographicException: Key not valid for use in specified state.
]
System.Security.Cryptography.ProtectedData.Unprotect(Byte[] encryptedData, Byte[] optionalEntropy, DataProtectionScope scope) +577
Microsoft.IdentityModel.Web.ProtectedDataCookieTransform.Decode(Byte[] encoded) +80
[InvalidOperationException: ID1073: A CryptographicException occurred when attempting to decrypt the cookie using the ProtectedData API (see inner exception for details). If you are using IIS 7.5, this could be due to the loadUserProfile setting on the Application Pool being set to false. ]
Microsoft.IdentityModel.Web.ProtectedDataCookieTransform.Decode(Byte[] encoded) +433
Microsoft.IdentityModel.Tokens.SessionSecurityTokenHandler.ApplyTransforms(Byte[] cookie, Boolean outbound) +189
Microsoft.IdentityModel.Tokens.SessionSecurityTokenHandler.ReadToken(XmlReader reader, SecurityTokenResolver tokenResolver) +862
Microsoft.IdentityModel.Tokens.SessionSecurityTokenHandler.ReadToken(Byte[] token, SecurityTokenResolver tokenResolver) +109
Microsoft.IdentityModel.Web.SessionAuthenticationModule.ReadSessionTokenFromCookie(Byte[] sessionCookie) +356
Microsoft.IdentityModel.Web.SessionAuthenticationModule.TryReadSessionTokenFromCookie(SessionSecurityToken& sessionToken) +123
Microsoft.IdentityModel.Web.SessionAuthenticationModule.OnAuthenticateRequest(Object sender, EventArgs eventArgs) +61
System.Web.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +80
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +270

Per ovviare al problema, usare un meccanismo di crittografia dei cookie che si avvalga di una chiave condivisa da tutte le istanze del ruolo Web. Il seguente codice mostra come sostituire l'oggetto SessionSecurityHandler predefinito e configurarlo per l'uso della classe RsaEncryptionCookieTransform.

private void OnServiceConfigurationCreated(object sender, 
    ServiceConfigurationCreatedEventArgs e)
{
    List<CookieTransform> sessionTransforms =
        new List<CookieTransform>(
            new CookieTransform[] 
            {
                new DeflateCookieTransform(), 
                new RsaEncryptionCookieTransform(
                    e.ServiceConfiguration.ServiceCertificate),
                new RsaSignatureCookieTransform(
                    e.ServiceConfiguration.ServiceCertificate)  
            });
   SessionSecurityTokenHandler sessionHandler = 
    new
     SessionSecurityTokenHandler(sessionTransforms.AsReadOnly());

    e.ServiceConfiguration.SecurityTokenHandlers.AddOrReplace(
        sessionHandler);
}

void Application_Start(object sender, EventArgs e)
{
    FederatedAuthentication.ServiceConfigurationCreated += OnServiceConfigurationCreated;
}

Risorse aggiuntive