Compartir a través de


Protección de un servicio asincrónica

Los servicios asincrónicas solo están disponibles para el usuario local y para los procesos implicados en la sesión de Visual Studio que lo activaron. En estos valores predeterminados, las consideraciones de seguridad para los servicios asincrónicas no son diferentes de otros código que se ejecutan en estos procesos, entre los que se incluyen:

  • Desde la perspectiva del modelo de amenazas, se supone que las extensiones que se ejecutan en el proceso de Visual Studio son de plena confianza. Las extensiones que se agotan el proceso deben tratar las llamadas de servicio de Visual Studio como cruzar un límite de confianza.
  • El código debe validar los argumentos en los puntos de entrada para confirmar que se encuentran en patrones o intervalos esperados.
  • Al leer datos del disco, tenga en cuenta que es posible que los datos se hayan alterado.
  • Al recibir datos de una red o de Internet, tenga cuidado al analizar o deserializar los datos para evitar vulnerabilidades comunes.

Se aplican varias consideraciones de seguridad adicionales críticas cuando el servicio se registra con el conjunto de ProvideBrokeredServiceAttribute.AllowTransitiveGuestClients marcas. El resto de este artículo se centra en esas consideraciones.

Comprobaciones de autorización para operaciones confidenciales

Adquisición del servicio de autorización

El servicio asincrónica debe tener un constructor que tome como AuthorizationServiceClient parámetro . El argumento debe almacenarse en un campo y desecharse en el método del Dispose() servicio.

class Calculator : ICalculator, IDisposable
{
    private readonly AuthorizationServiceClient authorizationService;

    internal Calculator(AuthorizationServiceClient authorizationService)
    {
        this.authorizationService = authorizationService;
    }

    public void Dispose()
    {
        this.authorizationService.Dispose();
    }
}

La factoría de servicios que proffer cambia ligeramente para admitir este nuevo parámetro. En lugar de proporcionar un BrokeredServiceFactory elemento al IBrokeredServiceContainer.Proffer método , proporcione un AuthorizingBrokeredServiceFactory delegado. Este delegado recibe el AuthorizationServiceClient que tendrá que pasar al servicio asincrónica.

Este cambio en el código de proffer podría tener este aspecto:

 container.Proffer(
     CalculatorService,
-    (moniker, options, serviceBroker, cancellationToken) => new ValueTask<object?>(new CalculatorService()));
+    (moniker, options, serviceBroker, authorizationService, cancellationToken) => new ValueTask<object?>(new CalculatorService(authorizationService)));

Uso del servicio de autorización

Cualquier operación que pueda revelar información confidencial o mutar el estado del usuario debe comprobarse con el servicio de autorización mediante AuthorizationServiceClient.AuthorizeOrThrowAsync.

Para afirmar que el autor de la llamada es el propietario del código (la misma identidad que el operador del host de Live Share), se puede usar este código:

private static readonly ProtectedOperation ClientIsOwner = WellKnownProtectedOperations.CreateClientIsOwner();

public ValueTask ResetOperationCounterAsync(CancellationToken cancellationToken)
{
    // Resetting the counter should only be allowed if the user is the owner.
    await this.authorizationService.AuthorizeOrThrowAsync(ClientIsOwner, cancellationToken);

    // Proceed with the operation.
    this.operationCounter = 0;
}

En la WellKnownProtectedOperations clase se definen otros niveles de autorización.

Todas las comprobaciones de autorización siempre se aprueban cuando el cliente de servicio se ejecuta en la misma máquina y cuenta de usuario. También están aprobados para un invitado de Live Share que funciona con la misma cuenta de Microsoft que el host.

Cuando la operación solicitada no esté autorizada, AuthorizeOrThrowAsync producirá una UnauthorizedAccessExceptionexcepción . El host de Live Share puede notificar al propietario del intento erróneo, lo que le da al host la oportunidad de conceder el permiso necesario para completar la operación si ProtectedOperation se reconoce para que un intento posterior en el cliente pueda realizarse correctamente.

Almacena AuthorizationServiceClient en caché todas las comprobaciones de autorización localmente para que las comprobaciones de autorización repetidas sean rápidas. En caso de que el conjunto de permisos de un usuario cambie (por ejemplo, los permisos de host de Live Share para el invitado), la caché local se vacía automáticamente.

Consumo de otros servicios asincrónicas

Cuando un servicio asincrónica requiere acceso a otro servicio asincrónica, debe usar el IServiceBroker que se proporciona a su generador de servicios. No debe usar el agente de servicio global, ya que no es consciente del contexto de esta instancia de servicio asincrónica determinada y la autorización que su cliente tiene para activar e invocar otro comportamiento.

Si nuestro servicio de calculadora tuviera necesidad de otros servicios asincrónicas para implementar su comportamiento, modificaríamos el constructor para aceptar un IServiceBroker:

internal class Calculator : ICalculator
{
    private readonly IServiceBroker serviceBroker;
    private readonly AuthorizationServiceClient authorizationService;

    internal class Calculator(IServiceBroker serviceBroker, AuthorizationServiceClient authorizationService)
    {
        this.serviceBroker = serviceBroker;
        this.authorizationService = authorizationService;
    }
}

Este parámetro adicional afectará al código de proffering de la factoría de servicios:

 container.Proffer(
     CalculatorService,
     (moniker, options, serviceBroker, authorizationService, cancellationToken)
-        => new ValueTask<object?>(new CalculatorService(authorizationService)));
+        => new ValueTask<object?>(new CalculatorService(serviceBroker, authorizationService)));

Disponibilidad limitada del servicio asincrónica

Cuando el cliente del servicio asincrónica es un invitado de Live Share (en una cuenta diferente del propietario del host), el agente de servicio contextual solo activará otros servicios asincrónicas que también hayan establecido la AllowTransitiveGuestClients marca como precaución de seguridad. Los intentos de activar un servicio asincrónica no calificado producirán una UnauthorizedAccessExceptionexcepción .

Si el servicio asincrónica requiere otro servicio asincrónica que no tenga la AllowTransitiveGuestClients marca , puede usar el agente de servicio global para obtenerlo, pero debe tener en cuenta que los servicios asincrónicas obtenidos de él no tienen idea de que un invitado que no es de confianza es el cliente final. Debe seguir todas las mismas precauciones dadas en la sección siguiente sobre cómo llamar a otros servicios de VS u otras API.

Obtenga más información sobre el consumo de servicios asincrónicas.

Consumo de otros servicios de VS u otras API

Se permite llamar a servicios estándar de Visual Studio, bibliotecas de terceros o API estándar de .NET en servicios asincronados que se exponen a invitados de Live Share, pero estas llamadas deben escribirse cuidadosamente y todas las entradas validadas en primer lugar.

Las rutas de acceso de archivo o las direcciones URL deben comprobarse cuidadosamente para asegurarse de que son válidas y se encuentran dentro de las subdirecciones esperadas a las que el invitado tiene autorización para acceder. Por ejemplo, si el servicio asincronado permite leer o escribir en archivos en función de una ruta de acceso, la ruta de acceso debe comprobarse para estar bajo la solución abierta y que el invitado realmente tenga permisos de escritura si procede. La validación de las rutas de acceso de archivo correctamente puede ser difícil teniendo en cuenta .. y otros medios para que parezca que una ruta de acceso comienza con el prefijo correcto, pero luego se escapa el directorio de soluciones permitido.

Use el AuthorizationServiceClient descrito en la sección anterior según corresponda para afirmar que el cliente tiene permiso antes de llamar a cualquier API que no tenga sus propias comprobaciones de permisos integradas. Solo se deben suponer que los servicios asincronados integrados en Visual Studio contienen sus propias comprobaciones de autorización y esto se basa en la adquisición de estos servicios asincronados mediante el agente de servicio contextual, tal como se describe en la sección anterior.

Todas las demás API, incluidos los servicios de Visual Studio no asincronados o los servicios asincronados obtenidos con el agente de servicio global, pueden ejecutarse a medida que los dirija sin tener en cuenta el nivel de permisos de su invitado de Live Share, lo que hace que su propia comprobación de autorización sea fundamental para proteger la seguridad del host de Live Share.

Evite exponer la funcionalidad del servicio asincrónica que otro servicio asincrónica de Visual Studio ya expone a medida que aumenta la superficie expuesta a ataques.

Uso compartido del estado entre instancias de servicio asincrónicas

Cuando el servicio asincrónica requiere el estado de uso compartido en varias instancias del servicio, estos datos se exponen potencialmente a varios usuarios con diversos conjuntos de permisos. Se convierte en fundamental para que el servicio asincrónica proteja estos datos entre estos usuarios. Use el modelo STRIDE para ayudar a identificar, clasificar y, en última instancia, mitigar las amenazas.

Puede decidir tratar el estado compartido como de confianza y, por tanto, concederle permiso para hacer lo que necesite internamente (por ejemplo, acceder a los servicios de VS o usar el agente de servicios global). En tal caso, se convierte en responsabilidad de una instancia de servicio asincrónica individual para proteger las llamadas realizadas en su estado compartido para asegurarse de que todas las entradas sean adecuadas teniendo en cuenta los permisos de su propio usuario mediante el servicio de autorización.

Microsoft Threat Modeling Tool puede ser una herramienta útil para proteger el estado compartido y los usuarios.