Partager via


Recommandations en matière de sécurité ACS

Mise à jour : 19 juin 2015

S’applique à : Azure

S’applique à

  • Contrôle d’accès Microsoft Azure Active Directory (également appelé Service de contrôle d’accès ou ACS)

  • Windows Identity Foundation (WIF)

Résumé

Cette rubrique consolide les instructions de sécurité pour ACS. Utilisez ces instructions pour améliorer la qualité de votre implémentation du point de vue de la sécurité. Vous pouvez utiliser ces instructions lors de l’examen de l’architecture de votre application, de la révision du code et de la journalisation des bogues de sécurité et de la révision du déploiement de production. Ces instructions vous souhaitent obtenir plus d’informations sur la procédure à suivre avec des étapes prescriptives pour accomplir une tâche spécifique et des rubriques conceptuelles pour en savoir plus sur une fonctionnalité ou une fonction particulière d’ACS.

Objectifs

  • Résolvez les problèmes de sécurité liés au code et à la configuration d’une application dans le contexte d’ACS.

  • Résolvez les problèmes de sécurité liés aux configurations ACS.

  • Résolvez les problèmes de sécurité liés aux déploiements Azure dans le contexte d’ACS.

Voici les instructions de sécurité relatives au code et à la configuration de votre application.

  • Envisagez de définir la fonctionnalité de détection de relecture (DetectReplayedTokens) sur true.

  • Définissez l’attribut requireHttps de wsFederation sur true.

  • Définissez l'l’attribut de cookieHandler sur true.

  • Définissez la valeur agressive pour l’attribut de durée de vie de sessionTokenRequirement.

  • Répertoriez le STS approuvé (émetteurs de jetons) dans issuerNameRegistry.

  • Jetons d’étendue qui doivent être acceptés par votre application à l’aide de audienceUri.

Envisagez de définir la fonctionnalité de détection de relecture (DetectReplayedTokens) sur true

WIF a un cache de détection de relecture spécifiquement pour les jetons de porteur de service de jeton de sécurité (STS), qui est simplement un cache de jetons STS précédemment utilisés. Lorsque le client s’authentifie pour la première fois auprès de la partie de confiance à l’aide du jeton STS, il reçoit un jeton de sécurité de session qu’il utilise pour s’authentifier auprès de la partie de confiance pour toutes les demandes supplémentaires. Il effectue cette opération sur SSL (Secure Sockets Layer) afin que le jeton de sécurité de session ne puisse pas être volé. Si un client ou un attaquant tente de s’authentifier auprès de la partie de confiance avec un jeton STS que le client a déjà utilisé, la partie de confiance peut rechercher le jeton STS dans le cache de relecture et refuser la demande.

Ce cache ne garantit pas qu’un jeton ne peut jamais être relecté. Il effectue une détection optimale en fonction de la taille du cache, de l’heure d’expiration du jeton STS et du taux de demandes d’authentification uniques reçues par la partie de confiance. Nous vous recommandons vivement de définir la taille du cache et le délai d’expiration du jeton STS pour votre partie de confiance afin d’obtenir le bon équilibre entre les performances et la sécurité.

Exemple:

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

Note

L’utilisation de cette fonctionnalité introduit l’affinité serveur qui peut entraîner des problèmes d’extensibilité dans des environnements à charge équilibrée, notamment Azure. Pour résoudre ce problème, vous pouvez envisager d’implémenter votre propre détection de relecture de jeton à l’aide d’une classe abstraite de base Microsoft.IdentityModel.Tokens.TokenReplayCache, puis de le référencer dans le fichier de configuration, avec du code similaire à ce qui suit.

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

Définir l’attribut requireHttps de wsFederation sur true

L'exigerHttps attribut contrôle si le module redirige uniquement une URL sécurisée pour le STS. La valeur par défaut est « true ». Cela garantit des communications sécurisées avec STS sur le trafic HTTPS/SSL clair, en atténuant les informations d’identification et leiffage de jeton sur le câble.

Exemple:

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

Définir l’attribut requireSsl de cookieHandler sur true

Cette valeur est booléenne ; la valeur par défaut est false. L'exige que L’attribut SSsl contrôle si l’indicateur « Secure » est émis pour tous les cookies écrits. Si cette valeur est définie, les cookies de session de connexion sont disponibles uniquement via HTTPS. Cela empêche l’envoi de cookies de session sur le trafic clair, ce qui atténue la menace du jeton sniffé sur le réseau.

Exemple:

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

Définir la valeur agressive pour l’attribut de durée de vie de sessionTokenRequirement

Envisagez d’émettre des jetons avec des limites de durée de vie agressives. Cela limiterait le délai d’exécution d’un attaquant pour relire le jeton en cas de vol.

Exemple:

<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>

Répertorier les STS approuvés (émetteurs de jetons) dans issuerNameRegistry

Tous les jetons d’émetteur sont validés à l’aide de IssuerNameRegistry. L’objectif de IssuerNameRegistry est de mapper le jeton émetteur à un nom de chaîne. Si la validation échoue, le jeton ne sera pas accepté. Cela atténue la menace d’accepter des jetons qui ne sont pas approuvés. Tout type personnalisé peut être inscrit à l’aide du type attribut de l’élément <issuerNameRegistry>. La <issuerNameRegistry> peut avoir un élément enfant qui servira de configuration personnalisée à IssuerNameRegistry. Un type IssuerNameRegistry est fourni en dehors de la zone ( ConfigurationBasedIssuerNameRegistry) qui peut être utilisé pour configurer un ensemble de certificats d’émetteur approuvés dans la configuration. Ce type nécessite un élément de configuration enfant <trustedIssuers> où les certificats d’émetteur approuvés sont configurés. <trustedIssuers> configuration ajoute des certificats approuvés à l’aide du formulaire codé ASN.1 de l’empreinte numérique du certificat.

Exemple:

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

Jetons d’étendue à votre application à l’aide uniquement d’audienceUri

<audienceUris> spécifie l’ensemble d’URI acceptables pour identifier cette partie de confiance. Les jetons ne seront pas acceptés, sauf s’ils sont limités à l’une des URI d’audience autorisés. Cela atténue la menace de relecture de jetons valides émis pour d’autres parties de confiance. Par défaut, aucune URI n’est ajoutée à la collection. Les types de jetons SAML 1.1 et SAML 2.0 utilisent les valeurs de cette collection pour configurer les restrictions d’URI d’audience autorisées dans les objets SamlSecurityTokenRequirement.

Exemple:

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

Voici les instructions de sécurité relatives à la configuration du portail de gestion ACS.

  • Définir une expiration agressive pour les jetons STS

  • Fournir une validation des données adéquate lors de l’utilisation de la fonctionnalité URL d’erreur

  • Envisagez de chiffrer des jetons pour des scénarios hautement sensibles

Définir une expiration agressive pour les jetons STS

L’attribut de durée de vie du jeton contrôle la durée de vie du jeton. Elle est spécifiée lorsque vous créez ou configurez la partie de confiance à l’aide du portail ACS ou du service de gestion. Vous pouvez utiliser la propriété Durée de vie du jeton pour spécifier la durée pendant laquelle un jeton de sécurité émis par ACS à l’application de partie de confiance reste valide. Par défaut, dans ACS, cette valeur est définie sur 10 minutes (600 secondes). Dans ACS, cette valeur doit être supérieure à zéro, mais inférieure ou égale à 24 heures (86400 secondes).

Fournir une validation des données adéquate lors de l’utilisation de la fonctionnalité URL d’erreur

Vous pouvez utiliser l’URL d’erreur pour spécifier une URL vers laquelle ACS redirige les utilisateurs si une erreur se produit pendant le processus de connexion. Il peut s’agir d’une page personnalisée hébergée sur l’application de partie de confiance, par exemple, http://www.fabrikam.com/billing/error.aspx. Dans le cadre de la redirection, ACS fournit des détails sur l’erreur à l’application de partie de confiance en tant que paramètre d’URL HTTP encodé JSON. La page d’erreur personnalisée peut être conçue pour consommer les informations d’erreur encodées JSON pour afficher le message d’erreur réel reçu ou afficher le texte d’aide statique. Si la page nécessite une autorisation, le résultat est une boucle de redirection infinie dans un cas où ACS tente d’y accéder et envoie l’erreur encodée JSON. Par conséquent, elle doit être configurée pour l’accès anonyme. Étant donné que la page est accessible anonymement et qu’elle peut inclure du code qui renvoie du code HTML ou écrit des données dans la base de données, vous devez prendre des mesures pour empêcher les attaques par script intersites et d’injection SQL.

Envisagez de chiffrer des jetons pour des scénarios hautement sensibles

Pour les scénarios hautement sensibles pour la fédération passive, envisagez de chiffrer des jetons. En savoir plus sur le chiffrement et le déchiffrement du jeton dans rubrique Certificats et clés.

Voici les considérations de sécurité relatives aux applications qui utilisent ACS et qui sont déployées sur Azure.

  • Chiffrer les cookies à l’aide de RSA

Chiffrer les cookies à l’aide de RSA

Dans Azure, le mécanisme de chiffrement des cookies par défaut (qui utilise des interfaces de programmation d’applications de protection des données (DPAPI) n’est pas approprié, car chaque instance a une clé différente. Cela signifie qu’un cookie créé par une instance de rôle web n’est pas lisible par une autre instance de rôle web. Cela peut entraîner des défaillances de service, provoquant efficacement un déni de service. Voici le message d’erreur que vous rencontrerez si vous utilisez le mécanisme de chiffrement de cookie par défaut :

[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

Pour résoudre ce problème, utilisez un mécanisme de chiffrement de cookie qui utilise une clé partagée par toutes les instances de rôle web. Le code suivant montre comment remplacer l’objet SessionSecurityHandler par défaut et le configurer pour utiliser la 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;
}

Ressources additionnelles