AppContainer pour les applications héritées

L’environnement AppContainer est un environnement d’exécution de processus restrictif qui peut être utilisé pour les applications héritées afin de garantir la sécurité des ressources. Le processus d’une application AppContainer et ses processus enfants s’exécutent à l’intérieur d’un conteneur d’application léger, où ils peuvent accéder uniquement aux ressources auxquelles l’accès leur est spécifiquement accordé. En outre, ils sont isolés par le biais de la virtualisation du système de fichiers et du Registre. Ainsi, les applications implémentées dans un environnement AppContainer ne peuvent pas être piratées pour autoriser des actions malveillantes au-delà des ressources affectées limitées.

Pour les applications empaquetées et non empaquetées, AppContainer représente une bonne pratique d’ingénierie sécurisée.

Conseil

AppContainer était initialement appelé LowBox (avant la publication de Windows 8). Ce nom hérité est visible dans certains noms d’API tels que NtCreateLowBoxToken.

Applications empaquetées

Vous pouvez prendre une application empaquetée à l’aide de MSIX, et la configurer facilement pour qu’elle s’exécute dans l’environnement AppContainer. Les applications UWP (plateforme Windows universelle) sont automatiquement des applications AppContainer. Toutefois, vous pouvez également configurer votre application de bureau empaquetée avec MSIX pour qu’elle soit une application AppContainer. Il est particulièrement facile d’utiliser AppContainer si vous créez un package à l’aide de MSIX. Pour obtenir plus d’informations et accéder à des scénarios et des exemples de configuration, consultez Applications MSIX AppContainer.

Applications non packagées

Une application non empaquetée peut également s’exécuter dans un conteneur d’application. Pour créer un processus dans un conteneur d’application, vous avez besoin d’une définition (ou profil) AppContainer. C’est pourquoi l’utilisation d’AppContainer avec une application empaquetée est plus simple. Lorsque vous inscrivez un package pour un utilisateur, la pile de déploiement appelle certaines API Win32 pour vous afin de créer le profil AppContainer nécessaire (par exemple, CreateAppContainerProfile). Et lorsque vous désinscrivez un package pour un utilisateur, la pile de déploiement effectue le travail de suppression du profil AppContainer (DeleteAppContainerProfile). Si vous n’empaquetez pas votre application, vous devez faire les mêmes choses en appelant vous-même ces API Win32, mais cela peut être compliqué.

La plupart des applications non empaquetées qui utilisaient le niveau de faible intégrité utilisent désormais AppContainer comme meilleur moyen de fournir un environnement d’exécution limité.

Lorsqu’un processus non empaqueté s’exécutant dans un conteneur d’application appelle CreateProcess, le processus enfant hérite généralement du jeton du parent. Ce jeton inclut les informations sur le niveau d’intégrité et le conteneur d’application. Il est préférable de ne pas penser à un axe unique avec les valeurs élevé/moyen/faible/AppContainer. Au lieu de cela, le fait d’être ou de ne pas être dans un conteneur d’application est une deuxième propriété orthogonale. Cela dit, si vous êtes dans un conteneur d’application, le niveau d’intégrité est toujours faible.

Avantages de l’utilisation d’un environnement AppContainer

L’un des principaux objectifs de l’environnement AppContainer est de séparer autant que possible l’état de l’application de l’état du système, tout en conservant la compatibilité avec les autres applications. Windows accomplit cela en détectant et en redirigeant certaines modifications qu’il apporte au système de fichiers et au Registre au moment de l’exécution (un processus appelé virtualisation). Une application AppContainer écrit dans son propre Registre virtuel et son propre dossier de données d’application, et ces données sont supprimées lors de la désinstallation ou de la réinitialisation de l’application. Les autres applications n’ont pas accès au Registre virtuel ou au système de fichiers virtuel d’une application AppContainer.

L’environnement AppContainer fournit donc un bac à sable sécurisé pour les applications. Il isole l’application et l’empêche d’accéder au matériel, aux fichiers, au Registre, à d’autres applications, à la connectivité réseau et aux ressources réseau sans autorisation spécifique. Des ressources individuelles peuvent être ciblées sans exposer d’autres ressources. En outre, l’identité de l’utilisateur est protégée au moyen d’une identité unique qui est une concaténation de l’utilisateur et de l’application, et l’accès aux ressources est accordé à l’aide d’un modèle respectant le principe des privilèges minimum. Cela assure une protection supplémentaire contre l’emprunt d’identité de l’utilisateur par l’application en vue d’accéder à d’autres ressources.

Exemple de code afin de tester si une application s’exécute dans un conteneur d’application

Dans un projet C# ou C++, vous pouvez utiliser l’un des exemples de code ci-dessous afin de déterminer si un processus s’exécute à l’intérieur d’un conteneur d’application. Pour chaque exemple, une fois le code exécuté, si la valeur de isAppContainer est différente de zéro (ou true), cela signifie que le processus s’exécute à l’intérieur d’un conteneur d’application.

C# (P/Invoke)

[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr GetCurrentProcess();

[DllImport("advapi32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool OpenProcessToken(
    IntPtr ProcessHandle,
    UInt32 DesiredAccess,
    out IntPtr TokenHandle);

[DllImport("advapi32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool GetTokenInformation(
    IntPtr TokenHandle,
    uint TokenInformationClass,
    out uint TokenInformation,
    uint TokenInformationLength,
    out uint ReturnLength);

UInt32 TOKEN_QUERY = 0x0008;
IntPtr tokenHandle;

if (!OpenProcessToken(
    GetCurrentProcess(),
    TOKEN_QUERY,
    out tokenHandle))
{
    // Handle the error.
}

uint isAppContainer;
uint TokenIsAppContainer = 29;
uint tokenInformationLength = sizeof(uint);

if (!GetTokenInformation(
    tokenHandle,
    TokenIsAppContainer,
    out isAppContainer,
    tokenInformationLength,
    out tokenInformationLength))
{
    // Handle the error.
}

C++ (WIL)

Cet exemple utilise les bibliothèques d’implémentation Windows (WIL). Le plus simple pour installer les bibliothèques WIL est de procéder comme suit : accédez à Visual Studio, cliquez sur Projet>Gérer les packages NuGet>Parcourir, tapez ou collez Microsoft.Windows.ImplementationLibrary dans la zone de recherche, sélectionnez l’élément dans les résultats de la recherche, puis cliquez sur Installer pour installer le package correspondant à ce projet.

#include <wil\token_helpers.h>
...
bool isAppContainer = wil::get_token_is_app_container();

Les fonctions wil::get_token_is_app_container_nothrow et wil::get_token_is_app_container_failfast offrent d’autres stratégies de gestion des erreurs. Pour plus d'informations, consultez wil\token_helpers.h.

C++ (canonique)

#include <windows.h>
...
HANDLE tokenHandle{};
DWORD isAppContainer{};
DWORD tokenInformationLength{ sizeof(DWORD) };

if (!::OpenProcessToken(
    GetCurrentProcess(),
    TOKEN_QUERY,
    &tokenHandle))
{
    // Handle the error.
}

if (!::GetTokenInformation(
    tokenHandle,
    TOKEN_INFORMATION_CLASS::TokenIsAppContainer,
    &isAppContainer,
    tokenInformationLength,
    &tokenInformationLength
))
{
    // Handle the error.
}

Contenu de cette section

Pour plus d’informations sur l’utilisation d’AppContainer pour les applications héritées, consultez les rubriques suivantes.

Rubrique Description
Isolation AppContainer L’isolation est l’objectif principal d’un environnement d’exécution AppContainer. En isolant une application des ressources inutiles et d’autres applications, vous réduisez les opportunités de manipulation malveillante. L’octroi de l’accès conformément au principe des privilèges minimum empêche les applications et les utilisateurs d’accéder à des ressources au-delà de leurs droits. Le contrôle de l’accès aux ressources protège le processus, l’appareil et le réseau.
Implémenter un AppContainer Pour implémenter un AppContainer, vous devez ajouter de nouvelles informations au jeton de processus, modifier SeAccessCheck() afin que tous les objets de liste de contrôle d’accès (ACL) hérités et non modifiés bloquent les demandes d’accès à partir de processus AppContainer par défaut, et replacer dans les listes ACL les objets qui doivent être accessibles aux environnements AppContainers.