Evitar ataques de falsificación de solicitud entre sitios (XSRF/CSRF) en ASP.NET Core
Por Fiyaz Hasan, Rick Andersony Steve Smith
La falsificación de solicitudes entre sitios (también conocida como XSRF o CSRF) es un ataque contra las aplicaciones hospedadas en web, por lo que una aplicación web malintencionada puede influir en la interacción entre un explorador cliente y una aplicación web que confía en ese explorador. Estos ataques son posibles porque los exploradores web envían algunos tipos de tokens de autenticación automáticamente con cada solicitud a un sitio web. Esta forma de vulnerabilidad de seguridad también se conoce como ataque de un solo clic o de sesión porque el ataque aprovecha la sesión autenticada previamente del usuario.
Un ejemplo de ataque CSRF:
Un usuario inicia sesión mediante
www.good-banking-site.comla autenticación de formularios. El servidor autentica al usuario y emite una respuesta que incluye una autenticación cookie . El sitio es vulnerable a ataques porque confía en cualquier solicitud que reciba con una autenticación cookie válida.El usuario visita un sitio malintencionado,
www.bad-crook-site.com.El sitio malintencionado,
www.bad-crook-site.com, contiene un formulario HTML similar al siguiente:<h1>Congratulations! You're a Winner!</h1> <form action="http://good-banking-site.com/api/account" method="post"> <input type="hidden" name="Transaction" value="withdraw"> <input type="hidden" name="Amount" value="1000000"> <input type="submit" value="Click to collect your prize!"> </form>Observe que las publicaciones del
actionformulario en el sitio vulnerable, no en el sitio malintencionado. Esta es la parte "entre sitios" de CSRF.El usuario selecciona el botón Enviar. El explorador realiza la solicitud e incluye automáticamente la autenticación cookie para el dominio solicitado,
www.good-banking-site.com.La solicitud se ejecuta en el servidor con el contexto de autenticación del usuario y puede realizar cualquier acción que un usuario autenticado
www.good-banking-site.compueda realizar.
Además del escenario en el que el usuario selecciona el botón para enviar el formulario, el sitio malintencionado podría:
- Ejecute un script que envíe automáticamente el formulario.
- Envíe el envío del formulario como una solicitud AJAX.
- Oculte el formulario mediante CSS.
Estos escenarios alternativos no requieren ninguna acción ni entrada del usuario que no sea visitar inicialmente el sitio malintencionado.
El uso de HTTPS no evita un ataque CSRF. El sitio malintencionado puede enviar una https://www.good-banking-site.com/ solicitud tan fácilmente como puede enviar una solicitud no segura.
Algunos ataques tienen como destino puntos de conexión que responden a solicitudes GET, en cuyo caso se puede usar una etiqueta de imagen para realizar la acción. Esta forma de ataque es común en los sitios de foro que permiten imágenes pero bloquean JavaScript. Las aplicaciones que cambian el estado en las solicitudes GET, donde se modifican variables o recursos, son vulnerables a ataques malintencionados. Las solicitudes GET que cambian el estado no son seguras. Un procedimiento recomendado es no cambiar nunca el estado de una solicitud GET.
Los ataques CSRF son posibles contra aplicaciones web que usan cookie s para la autenticación porque:
- Los cookie exploradores almacenan los emitidos por una aplicación web.
- Las cookie sesiones almacenadas incluyen cookie sesiones para usuarios autenticados.
- Los exploradores envían todas las asociadas a un dominio a la aplicación web cada solicitud, independientemente de cómo se generó la solicitud a cookie la aplicación en el explorador.
Sin embargo, los ataques CSRF no se limitan a las cookie vulnerabilidades. Por ejemplo, la autenticación básica y la autenticación implícita también son vulnerables. Una vez que un usuario inicia sesión con la autenticación Básica o Implícita, el explorador envía automáticamente las credenciales hasta que finaliza la † sesión.
†En este contexto, session hace referencia a la sesión del lado cliente durante la cual se autentica el usuario. No está relacionado con las sesiones del lado servidor ni con ASP.NET Core middleware de sesión.
Los usuarios pueden protegerse contra las vulnerabilidades de CSRF tomando precauciones:
- Cerrar la sesión de las aplicaciones web cuando termine de usarlos.
- Borre los cookie exploradores periódicamente.
Sin embargo, las vulnerabilidades de CSRF son fundamentalmente un problema con la aplicación web, no con el usuario final.
Aspectos básicos de la autenticación
CookieLa autenticación basada en es una forma popular de autenticación. Los sistemas de autenticación basados en tokens están creciendo en popularidad, especialmente para las aplicaciones de página única (SPA).
CookieAutenticación basada en
Cuando un usuario se autentica con su nombre de usuario y contraseña, se le emite un token que contiene un vale de autenticación que se puede usar para la autenticación y autorización. El token se almacena como cookie un que acompaña a cada solicitud que realiza el cliente. El middleware de autenticación realiza la generación y validación cookie Cookie de esto. El middleware serializa una entidad de seguridad de usuario en un cookie cifrado. En las solicitudes posteriores, el middleware valida , vuelve a crear la entidad de seguridad y asigna la entidad de seguridad a la cookie propiedad User de HttpContext.
Autenticación basada en tokens
Cuando se autentica un usuario, se le emite un token (no un token antiforgery). El token contiene información del usuario en forma de notificaciones o un token de referencia que señala la aplicación al estado de usuario que se mantiene en la aplicación. Cuando un usuario intenta acceder a un recurso que requiere autenticación, el token se envía a la aplicación con un encabezado de autorización adicional en forma de token de portador. Esto hace que la aplicación no tenga estado. En cada solicitud posterior, el token se pasa en la solicitud para la validación del lado servidor. Este token no está cifrado; está codificado. En el servidor, el token se descodifica para tener acceso a su información. Para enviar el token en solicitudes posteriores, almacene el token en el almacenamiento local del explorador. No se preocupe por la vulnerabilidad csrf si el token se almacena en el almacenamiento local del explorador. CSRF es un problema cuando el token se almacena en cookie . Para obtener más información, vea el ejemplo GitHub ejemplo de código SPA de problemas agrega dos cookie s.
Varias aplicaciones hospedadas en un dominio
Los entornos de hospedaje compartido son vulnerables a secuestros de sesión, CSRF de inicio de sesión y otros ataques.
Aunque example1.contoso.net y son hosts example2.contoso.net diferentes, hay una relación de confianza implícita entre los hosts del *.contoso.net dominio. Esta relación de confianza implícita permite que los hosts que no sean de confianza se afecten entre sí (las directivas del mismo origen que rigen las solicitudes AJAX no se aplican necesariamente a cookie cookie https).
Los ataques que aprovechan las vulnerabilidades de confianza entre las aplicaciones hospedadas en el mismo dominio se pueden cookie evitar al no compartir dominios. Cuando cada aplicación se hospeda en su propio dominio, no hay ninguna relación de cookie confianza implícita que aprovechar.
ASP.NET Core de antiforgeria
Advertencia
ASP.NET Core implementa antiforgeria mediante ASP.NET Core Data Protection. La pila de protección de datos debe configurarse para que funcione en una granja de servidores. Consulte Configuración de la protección de datos para obtener más información.
El middleware antiforgery se agrega al contenedor de inserción de dependencias cuando se llama a una de las siguientes API en Startup.ConfigureServices :
El middleware antiforgery se agrega al contenedor de inserción de dependencias cuando AddMvc se llama a en Startup.ConfigureServices
En ASP.NET Core 2.0 o posterior, FormTagHelper inserta tokens antiforgeria en elementos de formulario HTML. El marcado siguiente en Razor un archivo genera automáticamente tokens antiforgeria:
<form method="post">
...
</form>
De forma similar, IHtmlHelper.BeginForm genera tokens antiforgery de forma predeterminada si el método del formulario no es GET.
La generación automática de tokens antiforgeria para elementos de formulario HTML se produce cuando la etiqueta contiene el atributo y se cumple <form> cualquiera de las siguientes method="post" condiciones:
- El atributo de acción está vacío (
action=""). - No se proporciona el atributo de acción (
<form method="post">).
Se puede deshabilitar la generación automática de tokens antiforgeria para elementos de formulario HTML:
Deshabilite explícitamente los tokens antiforgeria con el
asp-antiforgeryatributo :<form method="post" asp-antiforgery="false"> ... </form>El elemento form no se incluye en los asistentes de etiquetas mediante el símbolo de exclusión del asistente de etiquetas:
<!form method="post"> ... </!form>Quite de
FormTagHelperla vista. SeFormTagHelperpuede quitar de una vista agregando la siguiente directiva a la Razor vista:@removeTagHelper Microsoft.AspNetCore.Mvc.TagHelpers.FormTagHelper, Microsoft.AspNetCore.Mvc.TagHelpers
Nota
Razor Las páginas se protegen automáticamente de XSRF/CSRF. Para obtener más información, vea XSRF/CSRF y Razor Pages.
El enfoque más común para defenderse frente a ataques CSRF es usar el patrón de token sincronizador (STP). STP se usa cuando el usuario solicita una página con datos de formulario:
- El servidor envía un token asociado a la identidad del usuario actual al cliente.
- El cliente devuelve el token al servidor para su comprobación.
- Si el servidor recibe un token que no coincide con la identidad del usuario autenticado, se rechaza la solicitud.
El token es único e impredecible. El token también se puede usar para garantizar la secuenciación adecuada de una serie de solicitudes (por ejemplo, garantizar la secuencia de solicitudes de: página 1 > página 2 > página 3). Todos los formularios de ASP.NET Core mvc y pages generan Razor tokens antiforgery. El siguiente par de ejemplos de vistas genera tokens antiforgeria:
<form asp-controller="Todo" asp-action="Create" method="post">
...
</form>
@using (Html.BeginForm("Create", "Todo"))
{
...
}
Agregue explícitamente un token antiforgery a un elemento <form> sin usar asistentes de etiquetas con el asistente HTML @Html.AntiForgeryToken :
<form action="/" method="post">
@Html.AntiForgeryToken()
</form>
En cada uno de los casos anteriores, ASP.NET Core un campo de formulario oculto similar al siguiente:
<input name="__RequestVerificationToken" type="hidden" value="CfDJ8NrAkS ... s2-m9Yw">
ASP.NET Core incluye tres filtros para trabajar con tokens antiforgeria:
Opciones de antiforgeria
Personalice las opciones de antiforgeria en Startup.ConfigureServices :
services.AddAntiforgery(options =>
{
// Set Cookie properties using CookieBuilder properties†.
options.FormFieldName = "AntiforgeryFieldname";
options.HeaderName = "X-CSRF-TOKEN-HEADERNAME";
options.SuppressXFrameOptionsHeader = false;
});
†Establezca las propiedades antiforgeria Cookie mediante las propiedades de la clase Cookie Builder.
| Opción | Descripción |
|---|---|
| Cookie | Determina la configuración utilizada para crear los cookie antiforgeria. |
| FormFieldName | Nombre del campo de formulario oculto utilizado por el sistema antiforgeria para representar tokens antiforgeria en vistas. |
| HeaderName | Nombre del encabezado utilizado por el sistema antiforgery. Si null es , el sistema solo tiene en cuenta los datos de formulario. |
| SuppressXFrameOptionsHeader | Especifica si se va a suprimir la generación del X-Frame-Options encabezado. De forma predeterminada, el encabezado se genera con un valor de "SAMEORIGIN". Tiene como valor predeterminado false. |
services.AddAntiforgery(options =>
{
options.CookieDomain = "contoso.com";
options.CookieName = "X-CSRF-TOKEN-COOKIENAME";
options.CookiePath = "Path";
options.FormFieldName = "AntiforgeryFieldname";
options.HeaderName = "X-CSRF-TOKEN-HEADERNAME";
options.RequireSsl = false;
options.SuppressXFrameOptionsHeader = false;
});
| Opción | Descripción |
|---|---|
| Cookie | Determina la configuración utilizada para crear los cookie antiforgeria. |
| CookieDomain | Dominio de cookie . Tiene como valor predeterminado null. Esta propiedad está obsoleta y se quitará en una versión futura. La alternativa recomendada es Cookie . Dominio. |
| CookieNombre | Nombre del objeto cookie. Si no se establece, el sistema genera un nombre único a partir del prefijo Cookie predeterminado (". AspNetCore.Antiforgery"). Esta propiedad está obsoleta y se quitará en una versión futura. La alternativa recomendada es Cookie . Nombre. |
| CookieRuta de acceso | Ruta de acceso establecida en cookie . Esta propiedad está obsoleta y se quitará en una versión futura. La alternativa recomendada es Cookie . Camino. |
| FormFieldName | Nombre del campo de formulario oculto utilizado por el sistema antiforgeria para representar tokens antiforgeria en vistas. |
| HeaderName | Nombre del encabezado utilizado por el sistema antiforgery. Si null es , el sistema solo tiene en cuenta los datos de formulario. |
| RequireSsl | Especifica si el sistema antiforgeria requiere HTTPS. Si true es , se producirá un error en las solicitudes que no son HTTPS. Tiene como valor predeterminado false. Esta propiedad está obsoleta y se quitará en una versión futura. La alternativa recomendada es establecer Cookie . SecurePolicy. |
| SuppressXFrameOptionsHeader | Especifica si se va a suprimir la generación del X-Frame-Options encabezado. De forma predeterminada, el encabezado se genera con un valor de "SAMEORIGIN". Tiene como valor predeterminado false. |
Para obtener más información, vea Cookie AuthenticationOptions.
Configuración de características antiforgeria con IAntiforgery
IAntiforgery proporciona la API para configurar características antiforgeria. IAntiforgery se puede solicitar en Configure el método de la clase Startup . En el ejemplo siguiente se usa middleware de la página principal de la aplicación para generar un token antiforgeria y enviarlo en la respuesta como (mediante la convención de nomenclatura Angular predeterminada que se describe más adelante en este cookie tema):
public void Configure(IApplicationBuilder app, IAntiforgery antiforgery)
{
app.Use(next => context =>
{
string path = context.Request.Path.Value;
if (
string.Equals(path, "/", StringComparison.OrdinalIgnoreCase) ||
string.Equals(path, "/index.html", StringComparison.OrdinalIgnoreCase))
{
// The request token can be sent as a JavaScript-readable cookie,
// and Angular uses it by default.
var tokens = antiforgery.GetAndStoreTokens(context);
context.Response.Cookies.Append("XSRF-TOKEN", tokens.RequestToken,
new CookieOptions() { HttpOnly = false });
}
return next(context);
});
}
Requerir validación antiforgeria
ValidateAntiForgeryToken es un filtro de acción que se puede aplicar a una acción individual, un controlador o globalmente. Las solicitudes realizadas a las acciones a las que se aplica este filtro se bloquean a menos que la solicitud incluya un token antiforgery válido.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> RemoveLogin(RemoveLoginViewModel account)
{
ManageMessageId? message = ManageMessageId.Error;
var user = await GetCurrentUserAsync();
if (user != null)
{
var result =
await _userManager.RemoveLoginAsync(
user, account.LoginProvider, account.ProviderKey);
if (result.Succeeded)
{
await _signInManager.SignInAsync(user, isPersistent: false);
message = ManageMessageId.RemoveLoginSuccess;
}
}
return RedirectToAction(nameof(ManageLogins), new { Message = message });
}
El ValidateAntiForgeryToken atributo requiere un token para las solicitudes a los métodos de acción que marca, incluidas las solicitudes HTTP GET. Si el atributo se aplica a través de los controladores de la ValidateAntiForgeryToken aplicación, se puede invalidar con el IgnoreAntiforgeryToken atributo .
Nota
ASP.NET Core no admite la adición automática de tokens antiforgeria a las solicitudes GET.
Validación automática de tokens antiforgeria solo para métodos HTTP no seguros
ASP.NET Core aplicaciones no generan tokens antiforgeria para métodos HTTP seguros (GET, HEAD, OPTIONS y TRACE). En lugar de aplicar ampliamente el atributo y, a continuación, invalidarlo por atributos, se puede usar el atributo ValidateAntiForgeryToken IgnoreAntiforgeryToken AutoValidateAntiforgeryToken. Este atributo funciona exactamente igual que el atributo , salvo que no requiere tokens para las solicitudes ValidateAntiForgeryToken realizadas mediante los métodos HTTP siguientes:
- GET
- HEAD
- OPCIONES
- TRACE
Se recomienda usar AutoValidateAntiforgeryToken ampliamente para escenarios que no son de API. Esto garantiza que las acciones POST están protegidas de forma predeterminada. La alternativa es omitir los tokens antiforgeria de forma predeterminada, a menos que ValidateAntiForgeryToken se aplique a métodos de acción individuales. En este escenario, es más probable que un método de acción POST se desproteja por error, lo que hace que la aplicación sea vulnerable a ataques CSRF. Todos los POS deben enviar el token antiforgery.
Las API no tienen un mecanismo automático para enviar la parte que no cookie es del token. La implementación probablemente depende de la implementación del código de cliente. A continuación se muestran algunos ejemplos:
Ejemplo de nivel de clase:
[Authorize]
[AutoValidateAntiforgeryToken]
public class ManageController : Controller
{
Ejemplo global:
Servicios. AddMvc(options => opciones. Filters.Add(new AutoValidateAntiforgeryTokenAttribute()));
services.AddControllersWithViews(options =>
options.Filters.Add(new AutoValidateAntiforgeryTokenAttribute()));
Invalidación de atributos globales o antiforjador de controlador
El filtro IgnoreAntiforgeryToken se usa para eliminar la necesidad de un token antiforgery para una acción (o controlador) determinada. Cuando se aplica, este filtro invalida los ValidateAntiForgeryToken filtros y AutoValidateAntiforgeryToken especificados en un nivel superior (globalmente o en un controlador).
[Authorize]
[AutoValidateAntiforgeryToken]
public class ManageController : Controller
{
[HttpPost]
[IgnoreAntiforgeryToken]
public async Task<IActionResult> DoSomethingSafe(SomeViewModel model)
{
// no antiforgery token required
}
}
Actualización de tokens después de la autenticación
Los tokens deben actualizarse después de que el usuario se autentique mediante el redireccionamiento del usuario a una vista o página Razor pages.
JavaScript, AJAX y SPA
En las aplicaciones tradicionales basadas en HTML, los tokens antiforgeria se pasan al servidor mediante campos de formulario ocultos. En las aplicaciones y LASA modernas basadas en JavaScript, muchas solicitudes se realizan mediante programación. Estas solicitudes AJAX pueden usar otras técnicas (como encabezados de solicitud cookie o s) para enviar el token.
Si se usan para almacenar tokens de autenticación y para autenticar solicitudes de API en el cookie servidor, CSRF es un posible problema. Si se usa el almacenamiento local para almacenar el token, la vulnerabilidad CSRF podría mitigarse porque los valores del almacenamiento local no se envían automáticamente al servidor con cada solicitud. Por lo tanto, se recomienda usar el almacenamiento local para almacenar el token antiforgeria en el cliente y enviar el token como encabezado de solicitud.
JavaScript
Con JavaScript con vistas, el token se puede crear mediante un servicio desde dentro de la vista. Inserta el servicio Microsoft.AspNetCore.Antiforgery.IAntiforgery en la vista y llama a GetAndStoreTokens:
@{
ViewData["Title"] = "AJAX Demo";
}
@inject Microsoft.AspNetCore.Antiforgery.IAntiforgery Xsrf
@functions{
public string GetAntiXsrfRequestToken()
{
return Xsrf.GetAndStoreTokens(Context).RequestToken;
}
}
<input type="hidden" id="RequestVerificationToken"
name="RequestVerificationToken" value="@GetAntiXsrfRequestToken()">
<h2>@ViewData["Title"].</h2>
<h3>@ViewData["Message"]</h3>
<div class="row">
<p><input type="button" id="antiforgery" value="Antiforgery"></p>
<script>
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (xhttp.readyState == XMLHttpRequest.DONE) {
if (xhttp.status == 200) {
alert(xhttp.responseText);
} else {
alert('There was an error processing the AJAX request.');
}
}
};
document.addEventListener('DOMContentLoaded', function() {
document.getElementById("antiforgery").onclick = function () {
xhttp.open('POST', '@Url.Action("Antiforgery", "Home")', true);
xhttp.setRequestHeader("RequestVerificationToken",
document.getElementById('RequestVerificationToken').value);
xhttp.send();
}
});
</script>
</div>
Este enfoque elimina la necesidad de tratar directamente con las opciones cookie de configuración del servidor o leerlas desde el cliente.
En el ejemplo anterior se usa JavaScript para leer el valor del campo oculto para el encabezado POST de AJAX.
JavaScript también puede acceder a tokens en s y usar el contenido de para cookie crear un encabezado con el valor del cookie token.
context.Response.Cookies.Append("CSRF-TOKEN", tokens.RequestToken,
new Microsoft.AspNetCore.Http.CookieOptions { HttpOnly = false });
Suponiendo que el script solicita enviar el token en un encabezado denominado , configure el X-CSRF-TOKEN servicio antiforgery para buscar el X-CSRF-TOKEN encabezado:
services.AddAntiforgery(options => options.HeaderName = "X-CSRF-TOKEN");
En el ejemplo siguiente se usa JavaScript para realizar una solicitud AJAX con el encabezado adecuado:
function getCookie(cname) {
var name = cname + "=";
var decodedCookie = decodeURIComponent(document.cookie);
var ca = decodedCookie.split(';');
for (var i = 0; i < ca.length; i++) {
var c = ca[i];
while (c.charAt(0) === ' ') {
c = c.substring(1);
}
if (c.indexOf(name) === 0) {
return c.substring(name.length, c.length);
}
}
return "";
}
var csrfToken = getCookie("CSRF-TOKEN");
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
if (xhttp.readyState === XMLHttpRequest.DONE) {
if (xhttp.status === 204) {
alert('Todo item is created successfully.');
} else {
alert('There was an error processing the AJAX request.');
}
}
};
xhttp.open('POST', '/api/items', true);
xhttp.setRequestHeader("Content-type", "application/json");
xhttp.setRequestHeader("X-CSRF-TOKEN", csrfToken);
xhttp.send(JSON.stringify({ "name": "Learn C#" }));
AngularJS
AngularJS usa una convención para abordar CSRF. Si el servidor envía un con el nombre , el servicio AngularJS agrega el valor a un encabezado cuando envía cookie XSRF-TOKEN una solicitud al $http cookie servidor. Este proceso es automático. No es necesario establecer explícitamente el encabezado en el cliente. El nombre del encabezado es X-XSRF-TOKEN . El servidor debe detectar este encabezado y validar su contenido.
Para ASP.NET Core API funcione con esta convención en el inicio de la aplicación:
- Configure la aplicación para proporcionar un token en cookie un denominado
XSRF-TOKEN. - Configure el servicio antiforgery para buscar un encabezado denominado
X-XSRF-TOKEN.
public void Configure(IApplicationBuilder app, IAntiforgery antiforgery)
{
app.Use(next => context =>
{
string path = context.Request.Path.Value;
if (
string.Equals(path, "/", StringComparison.OrdinalIgnoreCase) ||
string.Equals(path, "/index.html", StringComparison.OrdinalIgnoreCase))
{
// The request token can be sent as a JavaScript-readable cookie,
// and Angular uses it by default.
var tokens = antiforgery.GetAndStoreTokens(context);
context.Response.Cookies.Append("XSRF-TOKEN", tokens.RequestToken,
new CookieOptions() { HttpOnly = false });
}
return next(context);
});
}
public void ConfigureServices(IServiceCollection services)
{
// Angular's default header name for sending the XSRF token.
services.AddAntiforgery(options => options.HeaderName = "X-XSRF-TOKEN");
}
Vea o descargue el código de ejemplo (cómo descargarlo)
Windows autenticación y cookie antiforgeria
Al usar Windows autenticación, los puntos de conexión de la aplicación deben protegerse frente a ataques CSRF de la misma manera que para cookie . El explorador envía implícitamente el contexto de autenticación al servidor, por lo que los puntos de conexión deben protegerse frente a ataques CSRF.
Extensión de antiforgeria
El tipo IAntiForgeryAdditionalDataProvider permite a los desarrolladores ampliar el comportamiento del sistema anti-CSRF mediante el uso de datos adicionales de ida y vuelta en cada token. Se llama al método GetAdditionalData cada vez que se genera un token de campo y el valor devuelto se incrusta dentro del token generado. Un implementador podría devolver una marca de tiempo, un valor nonce o cualquier otro valor y, a continuación, llamar a ValidateAdditionalData para validar estos datos cuando se valida el token. El nombre de usuario del cliente ya está insertado en los tokens generados, por lo que no es necesario incluir esta información. Si un token incluye datos complementarios pero no IAntiForgeryAdditionalDataProvider está configurado, los datos complementarios no se validan.