ASP.NET protección de falsificación de solicitudes (XSRF/CSRF) en este núcleo

Actualización de la página :
Fecha de creación de la página :

Ambiente

Visual Studio
  • Visual Studio 2019
Núcleo ASP.NET
  • 3.0
  • 3.1

¿Qué es el forgeri de solicitud entre sitios?

La falsificación de solicitudes entre sitios (CSRF/XSRF) es para aquellos que se procesan solo dentro del sitio de interés. Un ataque a una vulnerabilidad que realiza un proceso de actualización de este tipo desde un sitio externo.

Por ejemplo, supongamos que tiene la capacidad de publicar comentarios en un sitio web. Normalmente, creo que publicarás ingresando un comentario del sitio, Este proceso de envío se utiliza con mayor frecuencia para lanzar datos en la dirección URL de destino.

Por lo tanto, si envía datos similares a la dirección URL de alguien que no sea el sitio de destino, Es el mismo trato que publicaste.

Si sólo un atacante hiciera esto, no sería una amenaza. Lo aterrador de CSRF es que los atacantes pueden construir sitios falsos o incrustar URL ocultas en el sitio. Es donde alguien más accede involuntariamente a ella y se convierte en un atacante.

No voy a entrar en profundidad aquí, así que por favor, obtenga más información sobre el forgeri de solicitud entre sitios.

ASP.NET Core incorpora esta contramedida en el marco de trabajo.

Compruebe la falsificación de solicitudes entre sitios para trabajar

Intente ver si el proceso de actualización se realiza realmente desde sitios o herramientas externos.

Index.cshtml crea un formulario de entrada que envía el texto especificado al servidor. A continuación, coloque viewdata para que el servidor muestre los mensajes que ha creado para que coincidan con el texto de entrada.

Index.cshtml

@{
  ViewData["Title"] = "Home Page";
}

<div class="text-center">
  <h1 class="display-4">Welcome</h1>
  <p>Learn about <a href="https://docs.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>.</p>
</div>

<form method="post">
  <input type="text" name="text" />
  <button type="submit">送信</button>
</form>

<p>@ViewData["Message"]</p>

HomeController.cs del lado del servidor procesa el texto enviado y lo genera en un seguimiento de Visual Studio. Establezca el mismo texto en ViewData para que se pueda mostrar al cliente.

HomeController.cs

public class HomeController : Controller
{
  // 省略

  [HttpPost]
  public IActionResult Index(string text)
  {
    System.Diagnostics.Trace.WriteLine($"「{text}」が入力されました。");
    ViewData["Message"] = $"「{text}」が入力されました。";
    return View();
  }

  // 省略
}

Intente realizar la funcionalidad que acaba de crear en los pasos normales. Cuando ejecute la depuración y aparezca la pantalla, escriba el texto y haga clic en el botón Enviar.

El texto procesado aparece en la pantalla como se esperaba.

Dado que también se genera en el seguimiento, la ventana de salida del estudio visual también muestra texto. De hecho, hacemos cosas como registrar datos de entrada en una base de datos, pero no vamos a simplificar el código aquí.

Ahora, intente acceder al programa desde fuera del sitio de destino durante la depuración y ejecución. Para simplificar, publicaré una publicación con una herramienta denominada Visual Studio Code. Si puede enviar POST, puede usar otras herramientas o crear otro programa de sitio para el ataque.

Al instalar una extensión denominada Cliente REST en Visual Studio Code, Puede utilizar una característica que le permita comprobar fácilmente el funcionamiento de la API REST con solo abrir el archivo .http.

Al crear un archivo .http similar al siguiente en un archivo de texto y, a continuación, abrir el archivo en Visual Studio Code, Puede enviar GET o POST haciendo clic en Enviar solicitud.

Si crea los siguientes datos POST, se le enviará casi la misma cantidad de datos que escriba texto en la pantalla y pulse el botón Enviar. (El número de puerto localhost debe ser el mismo que el entorno de ejecución.)

RestTest.http://www.restTest.http

### Form で POST 送信
POST https://localhost:44372/home/index HTTP/1.1
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW

------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="text"

なんらかのテキスト
------WebKitFormBoundary7MA4YWxkTrZu0gW--

Cuando lo envía, puede ver que el servidor está recibiendo texto y procesándolo.

Visual Studio Code puede obtener los resultados. Si echa un vistazo más de cerca al código de resultado, puede ver que se muestra el valor establecido para ViewData. (Se muestra en Unicode, pero el texto se muestra correctamente si se ve en un explorador Web.)

Abordar la vulnerabilidad de falsificación de solicitudes entre sitios

Como mencioné al principio, ASP.NET Core incorpora medidas contra la falsificación de solicitudes entre sitios en el marco. Una medida común es emitir un token único al cliente de antemano en una pantalla que requiere post, etc. No tiene que aceptar el procesamiento a menos que lance el token al servidor.

Por supuesto, si accede a la dirección URL directamente desde un sitio externo, el token es desconocido y no aceptará el procesamiento.

En primer lugar, me gustaría hablar sobre la emisión de tokens al cliente (HTML), pero el hecho es que el marco de trabajo no es capaz de hacer esto. Me iré. Si especifica un método POST en la etiqueta de formulario, puede incorporar parámetros de token en HTML sin permiso.

En el código HTML de abajo, se encuentra el nombre de entrada "__RequestVerificationToken" tipo "oculto". Esto se envía al servidor juntos cuando se presiona el botón de envío. Por cierto, no se anexa por el GET método.

En el lado del servidor, Startup.cs servicios. AddControllersWithViews opciones del método. Filtros para AutoValidateAntiforgeryTokenAttribute, todas las acciones Esta comprobación de token se agrega automáticamente a (para ser exactamente solo los métodos HTTP de POST, PUT, PATCH y DELETE).

Si desea agregar esta restricción solo a acciones específicas, no todas las acciones, por controlador, por acción También es posible establecer.

Por el contrario, si desea imponer restricciones a la mayoría de las acciones, pero desea excluir acciones específicas, Si establece el atributo IgnoreAntiforgeryToken en el controlador y la acción, está bien.

Startup.cs

public void ConfigureServices(IServiceCollection services)
{
  services.AddControllersWithViews(options =>
  {
    // 全ての「POST, PUT, PATCH, DELETE」アクションに自動で ValidateAntiForgeryToken を付与。
    // 個別に除外したい場合は「IgnoreAntiforgeryToken」属性を指定すること
    // API では HTML 側にトークンを発行できないのでコントローラーに「IgnoreAntiforgeryToken」を指定する必要がある。
    options.Filters.Add(new Microsoft.AspNetCore.Mvc.AutoValidateAntiforgeryTokenAttribute());
  });
}

Veamos cómo funciona. En primer lugar, el proceso de transmisión se realiza normalmente desde la pantalla.

Los resultados se reflejaron en la pantalla como se esperaba.

También se envía al seguimiento.

Ahora, vamos a tratar de acceder a ella desde el exterior.

Access ed, pero Bad Request fue devuelto. Es un resultado diferente al de cuando no estás tomando medidas. Se entiende que está protegido porque no es salida a la traza.

Resumen

Esta vez traté de implementar medidas contra el forgeri de solicitudes entre sitios. Era muy fácil de implementar porque ya estaba integrado en el marco de trabajo.

La creación de un sitio Web requiere mucha más vulnerabilidad que CSRF. Puede comprobar lo que hay por ahí, o puede utilizar herramientas como OWASP para comprobar si hay vulnerabilidades en su sitio.