2009-08-06 11 views
7

Estoy creando un software de foro que usa el backend php y mysql, y quiero saber cuál es la forma más segura de evitar la entrada del usuario para publicaciones en el foro.¿Cuál es la forma correcta/más segura de evitar la entrada en un foro?

Conozco htmlentities() y strip_tags() y htmlspecialchars() y mysql_real_escape_string(), e incluso el escape de JavaScript() pero no sé cuál usar y dónde.

¿Cuál sería la forma más segura para procesar estos tres tipos diferentes de entrada (por el proceso, me refiero a obtener, guardar en una base de datos y pantalla):

  1. A título de un post (que también ser la base del enlace permanente de URL).
  2. El contenido de una publicación del foro se limita al ingreso de texto básico.
  3. El contenido de una publicación del foro que permite html.

Agradecería una respuesta que me diga cuántas de estas funciones de escape necesito usar en combinación y por qué. Gracias!

Respuesta

8

Al generar la salida HTLM (como lo hace para obtener datos en los campos del formulario cuando alguien está tratando de editar una publicación, o si necesita volver a mostrar el formulario porque el usuario olvidó un campo, por ejemplo), probablemente use htmlspecialchars(): escapará a <, >, ", ' y &, según las opciones que le dé.

strip_tags remueve etiquetas si el usuario ha introducido algunas - y por lo general no quieren algo que el usuario escribió a desaparecer simplemente ;-)
Al menos, no para el campo "contenido" :-)


Una vez que tenga lo que el usuario hizo entrada en forma (es decir, cuando el formulario ha sido enviado), tiene que escapar antes de enviarlo a la base de datos.
Ahí es donde se convierten en funciones como mysqli_real_escape_string útil: se escapan de datos para SQL

También puede ser que desee echar un vistazo a las declaraciones preparadas, que podría ayudar un poco ;-)
with mysqli - y with PDO

No debe usar nada como addslashes: el escaparse no depende del motor de la base de datos; es mejor/más seguro usar una función que se ajuste al motor (MySQL, PostGreSQL, ...) con el que está trabajando: sabrá exactamente qué escaparse y cómo.


Finalmente, para mostrar los datos dentro de una página:

  • para los campos que no debe contener HTML, se debe utilizar htmlspecialchars(): si el usuario hizo etiquetas HTML de entrada, los que se mostrará como- es, y no se inyecta como HTML.
  • para los campos que pueden contener HTML ... Esto es un poco más complicado: probablemente solo quiera permitir algunas etiquetas, y strip_tags (que puede hacer eso) no está realmente a la altura de la tarea (permitirá que los atributos de las etiquetas permitidas)
    • es posible que desee echar un vistazo a una herramienta llamada HTMLPUrifier: se le permitirá especificar qué etiquetas y atributos se debe permitir - y genera HTML válido, que siempre es agradable ^^
    • Esto puede llevar un tiempo calcularlo, y es probable que no desee volver a generar ese HTML cada vez que se deba mostrar; para que pueda pensar en almacenarlo en la base de datos (solo mantener ese código HTML limpio, o conservarlo tanto como el que no está limpio, en dos campos separados - ¿podría ser útil para permitir que las personas editen sus publicaciones?)


Esos son sólo unos pocos punteros ... espero que le ayudan :-)
no dude en preguntar si tiene preguntas más precisas!

4

mysql_real_escape_string() escapa todo lo que necesita para poner en una base de datos mysql. Pero debe usar declaraciones preparadas (en mysqli) en su lugar, porque son más limpias y escapan automáticamente.

Se puede hacer cualquier otra cosa con htmlspecialchars() para eliminar HTML de la entrada y urlencode() para poner las cosas en un formato para las URL.

+0

Si el campo "contenido" puede contener algo de HTML, htmlspecialchars no se debe utilizar en él: se escapará todo el HTML, incluidas las etiquetas que están "permitidas" –

+0

Exactamente. htmlspecialchars() sería para el contenido limitado al ingreso de texto básico. – rpjohnst

1

La respuesta a this post es una buena respuesta

Básicamente, utilizando la interfaz pdo para parametrizar sus consultas es mucho más seguro y menos propenso a errores que escapar de sus entradas de forma manual.

+1

También puede hacer eso con MySQLi, por cierto. – rpjohnst

0

Tengo una tendencia a escapar de todos los caracteres que serían problemáticos en la visualización de la página, Javascript y SQL, todo al mismo tiempo. Lo deja legible en la web y en HTML eMail y al mismo tiempo elimina cualquier problema con el código. una línea vb.NET de código sería:

 
SafeComment = Replace(_ 
       Replace(Replace(Replace(_ 
       Replace(Replace(Replace(_ 
       Replace(Replace(Replace(_ 
       Replace(Replace(Replace(_ 
       HttpUtility.HtmlEncode(Trim(strInput)), _ 
        ":", "&#x3A;"), "-", "&#x2D;"), "|", "&#x7C;"), _ 
        "`", "&#x60;"), "(", "&#x28;"), ")", "&#x29;"), _ 
        "%", "&#x25;"), "^", "&#x5E;"), """", "&#x22;"), _ 
        "/", "&#x2F;"), "*", "&#x2A;"), "\", "&#x5C;"), _ 
        "'", "&#x27;")

+0

Uhhh ... ¡Código feo! –

+0

Sitiación fea (sic) – Dave

3

Hay dos tipos completamente diferentes de ataque que hay que defenderse de:

  • inyección SQL: entrada que intenta manipular su base de datos. mysql_real_escape_string() y addslashes() están destinados a defenderse de esto. El primero es mejor, pero las consultas parametrizadas son mejores todavía
  • Cross-Site scripting (XSS): entrada que, cuando se muestra en su página, intenta ejecutar JavaScript en el navegador de un visitante para hacer todo tipo de cosas (como robar el datos de la cuenta). htmlspecialchars() es la forma definitiva de defenderse de esto.

Permitir "algo de HTML" mientras se evitan los ataques XSS es muy, muy difícil. Esto se debe a que hay infinitas posibilidades de contrabandear JavaScript en HTML. Si decidió hacer esto, la forma segura es usar BBCode o Markdown, es decir, un conjunto limitado de marcas no HTML que luego convierta a HTML, mientras elimina todo el HTML real con htmlspecialchars(). Incluso entonces debe tener cuidado de no permitir javascript: URL en los enlaces. En realidad, permitir que los usuarios ingresen HTML es algo que solo debes hacer si es absolutely crucial for your site.Y luego debe pasar un lote de tiempo asegurándose de que entiende completamente HTML y JavaScript y CSS.

0

Antes que nada, consejos generales: no escatime las variables literalmente al insertar en la base de datos. Hay muchas soluciones que le permiten usar declaraciones preparadas con enlace variable. La razón para no hacer esto explícitamente es porque solo es cuestión de tiempo antes de que lo olvides solo una vez.

Si está insertando texto sin formato en la base de datos, no intente limpiarlo en la inserción, sino que límpielo en la pantalla. Es decir, use htmlentities para codificarlo como HTML (y pase el argumento del juego de caracteres correcto). Desea codificar en la pantalla porque ya no confía en que los contenidos de la base de datos sean correctos, lo que no es necesariamente cierto.

Si se trata de texto enriquecido (html), las cosas se vuelven más complicadas. Eliminar los bits "malvados" de HTML sin destruir el mensaje es un problema difícil. En términos realistas, tendrá que recurrir a una solución estandarizada, como HTMLPurifier. Sin embargo, esto generalmente es demasiado lento para ejecutarse en cada vista de página, por lo que se verá obligado a hacerlo al escribir en la base de datos. También deberá asegurarse de que el usuario pueda ver su html "limpiado" y corregir la versión limpia.

Definitivamente trate de evitar "rodar su propio" filtro o solución de codificación en cualquier paso. Estos problemas son notoriamente complicados y corre un gran riesgo de pasar por alto algunos detalles menores que tienen grandes implicaciones de seguridad.

0

Me segunda Joeri, no ruedan su cuenta, vaya aquí para ver algunas de las muchas posibles ataques XSS

http://ha.ckers.org/xss.html

htmlentities() -> convierte el texto en html, conversión de caracteres a entidades. Si usa codificación UTF-8, utilice htmlspecialchars() en su lugar ya que las otras entidades no son necesarias. Esta es la mejor defensa contra XSS. Lo uso en cada variable que publico independientemente del tipo u origen a menos que pretenda que sea html. Solo hay un pequeño costo de rendimiento y es más fácil que tratar de determinar qué necesita escaparse y qué no.

strip_tags() - convierte html en texto eliminando todas las etiquetas html. Use esto para asegurarse de que no haya nada desagradable en su entrada como complemento para escapar de su salida. mysql_real_escape_string() - escapa de una cadena para mysql y es su defensa contra inyecciones SQL de pequeñas tablas Bobby (es mejor usar mysqli y prepare/bind ya que se puede escapar y evitar muchas concatenaciones de cadenas desordenadas)

El consejo dado es evitar la entrada de HTML a menos que sea esencial y optar por BBCode o similar (crea tu propio si es necesario) es muy claro.

Cuestiones relacionadas