Pregunta

Quiero evitar ataques XSS en mi aplicación web.Descubrí que codificar HTML la salida realmente puede prevenir ataques XSS.Ahora el problema es: ¿cómo codifico HTML cada salida de mi aplicación?¿Hay alguna manera de automatizar esto?

Agradezco respuestas para JSP, ASP.net y PHP.

¿Fue útil?

Solución

No desea codificar todo el HTML, solo desea codificar en HTML cualquier entrada del usuario que esté generando.

Para PHP: entidades html y html caracteres especiales

Otros consejos

Una cosa que tu no debería Lo que se debe hacer es filtrar los datos de entrada a medida que llegan.La gente suele sugerir esto, ya que es la solución más fácil, pero genera problemas.

Los datos de entrada se pueden enviar a varios lugares, además de generarse como HTML.Podría estar almacenado en una base de datos, por ejemplo.Las reglas para filtrar los datos enviados a una base de datos son muy diferentes de las reglas para filtrar la salida HTML.Si codifica todo en HTML en la entrada, terminará con HTML en su base de datos.(Esta es también la razón por la que la función de "comillas mágicas" de PHP es una mala idea).

No puede anticipar todos los lugares a los que viajarán sus datos de entrada.El enfoque seguro es preparar los datos. justo antes se envía a alguna parte.Si lo envía a una base de datos, escape las comillas simples.Si está generando HTML, escape de las entidades HTML.Y una vez que se haya enviado a alguna parte, si aún necesita trabajar con los datos, use la versión original sin escape.

Esto supone más trabajo, pero puede reducirlo utilizando bibliotecas o motores de plantillas.

Para los JSP, puedes tener tu pastel y comértelo también, con la etiqueta c:out, que escapa a XML de forma predeterminada.Esto significa que puede vincular sus propiedades como elementos sin procesar:

<input name="someName.someProperty" value="<c:out value='${someName.someProperty}' />" />

Cuando se vincula a una cadena, someName.someProperty contendrá la entrada XML, pero cuando se envíe a la página, se escapará automáticamente para proporcionar las entidades XML.Esto es particularmente útil para enlaces para validación de páginas.

Una buena manera que utilicé para escapar de todas las entradas del usuario es escribiendo un modificador para Smarty que escape todas las variables pasadas a la plantilla;excepto aquellos que tienen |unescape adjunto.De esa manera, solo otorgas acceso HTML a los elementos a los que otorgas acceso explícitamente.

Ya no tengo ese modificador;pero aproximadamente la misma versión se puede encontrar aquí:

http://www.madcat.nl/martijn/archives/16-Using-smarty-to-prevent-HTML-injection..html

En la nueva versión de Django 1.0 esto funciona exactamente de la misma manera, jay :)

Mi preferencia personal es codificar diligentemente cualquier cosa que proviene de la base de datos, la capa empresarial o del usuario.

En ASP.Net esto se hace usando Server.HtmlEncode(string) .

La razón por la que codificar cualquier cosa es que incluso las propiedades que podría suponer que son booleanas o numéricas podrían contener código malicioso (por ejemplo, los valores de las casillas de verificación, si se hacen incorrectamente, podrían regresar como cadenas.Si no los codifica antes de enviar el resultado al usuario, entonces tiene una vulnerabilidad).

Podrías envolver eco/imprimir, etc.en sus propios métodos que luego puede usar para escapar de la salida.es decir.en lugar de

echo "blah";

usar

myecho('blah');

Incluso podría tener un segundo parámetro que desactive el escape si lo necesita.

En un proyecto teníamos un modo de depuración en nuestras funciones de salida que hacía invisible todo el texto de salida que pasaba por nuestro método.¡Entonces supimos que nada de lo que quedaba en la pantalla NO se había escapado!Fue muy útil rastrear esas partes traviesas que no se escaparon :)

Si realmente codifica HTML cada salida, el usuario verá el texto sin formato <html>en lugar de una aplicación web que funcione.

EDITAR:Si codifica HTML cada entrada, tendrá problemas para aceptar una contraseña externa que contenga <etc.

La única manera de protegerse verdaderamente contra este tipo de ataque es filtrar rigurosamente todas las entradas que acepta, específicamente (aunque no exclusivamente) de las áreas públicas de su aplicación.Te recomiendo que eches un vistazo a Daniel Morris. Clase de filtrado PHP (una solución completa) y también el Zend_Filter paquete (una colección de clases que puede utilizar para crear su propio filtro).

PHP es mi lenguaje preferido cuando se trata de desarrollo web, así que me disculpo por el sesgo en mi respuesta.

Kieran.

OWASP tiene una buena API para codificar la salida HTML, ya sea para usarla como texto HTML (p. ej.párrafo o <textarea> contenido) o como valor de un atributo (p. ej.para <input> etiquetas después de rechazar un formulario):

encodeForHTML($input) // Encode data for use in HTML using HTML entity encoding
encodeForHTMLAttribute($input) // Encode data for use in HTML attributes.

El proyecto (la versión PHP) está alojado en http://code.google.com/p/owasp-esapi-php/ y también está disponible para algunos otros idiomas, p..NETO.

Recuerda que debes codificar todo (no solo entrada del usuario), y lo más tarde posible (no cuando se almacena en la base de datos sino cuando se genera la respuesta HTTP).

La codificación de salida es, con diferencia, la mejor defensa.Validar la entrada es excelente por muchas razones, pero no es 100% de defensa.Si una base de datos se infecta con XSS mediante un ataque (es decir,ASPROX), error o validación de entrada maliciosa no hace nada.La codificación de salida seguirá funcionando.

Hubo un buen ensayo de Joel sobre software (creo que hacer que el código incorrecto parezca incorrecto, estoy en mi teléfono, de lo contrario tendría una URL para ti) que cubría el uso correcto de la notación húngara.La versión corta sería algo como:

Var dsFirstName, uhsFirstName : String;

Begin

uhsFirstName := request.queryfields.value['firstname'];

dsFirstName := dsHtmlToDB(uhsFirstName);

Básicamente anteponga sus variables con algo como "a nosotros" para cuerdas inseguras, "ds" para que la base de datos sea segura, "hs" para HTML seguro.Sólo desea codificar y decodificar donde realmente lo necesita, no todo.Pero al usar prefijos que infieren un significado útil, al mirar tu código verás muy rápidamente si algo no está bien.Y de todos modos necesitarás diferentes funciones de codificación/decodificación.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top