2009-11-27 14 views
10

Estoy trabajando mucho en un CMS basado en PHP en este momento, y mientras estoy en ello me gustaría mover todo el manejo y el saneamiento de la entrada del usuario a un lugar central. (Por el momento, es un $ _REQUEST aquí, un $ _GET allí, y así sucesivamente).¿Por qué filter_input() está incompleto?

Me gusta filter_input() y me gustaría utilizarlo para el saneamiento básico, pero no estoy seguro si esta función realmente está lista para producción. Por ejemplo, los nombres documentation los siguientes parámetros para el tipo $

INPUT_GET, INPUT_POST, INPUT_COOKIE, INPUT_SERVER, INPUT_ENV, INPUT_SESSION (not implemented yet) and INPUT_REQUEST (not implemented yet).

la función existe desde 5.2.0, ¿por qué son dos elementos cruciales no se han aplicado todavía? Si quiero obtener datos de $ _REQUEST, debe usar una solución de las notas aportadas por el usuario. ¿Hay alguna razón especial para esto? ¿Esta función todavía está en algún tipo de beta? ¿Es confiable como la primera llamada para manejar datos entrantes?

Tal vez alguien familiarizado con el proceso de desarrollo de PHP pueda arrojar algo de luz sobre esto.

+1

y en 2015 todavía parece haber ninguna aplicación por $ _SESSION, al menos, no se comprueba que otros todavía im sólo acaba de recoger la pelota php de nuevo, pero filter_var es una alternativa. – Chris

+2

'INPUT_SESSION' y' INPUT_FILES' no están implementados (aunque '$ _FILES' presenta un caso de uso multidimensional y no es como los demás de manera predeterminada). Utilice 'filter_var_array()' para '$ _SESSION'. También podría notar que tampoco existe una "BASE_DATOS_INPUT", pero aún tienes responsabilidades allí. Nuevamente, intente 'filter_var_array()'. –

Respuesta

8

quisiera mover todo el manejo y el saneamiento de la entrada del usuario a un lugar central

Sí, lo bonito que sería. No se puede hacer. No es así como funciona el procesamiento de texto.

Si está insertando texto de un contexto a otro, debe usar los escapes correctos. (mysql_real_escape_string para literales de cadenas MySQL, htmlspecialchars para contenido HTML, urlencode para parámetros de URL, otros para contextos específicos). Al comienzo de su secuencia de comandos cuando está filtrando, no sabe dónde terminará su entrada, por lo que no sabe cómo escapar de ella.

Tal vez una cadena de entrada va tanto a la base de datos (necesita ser escapada en SQL) como directamente a la página (necesita ser escapada en HTML). No hay escapatoria que cubra ambos casos. Puede usar ambos escapes uno después del otro, pero luego el valor en el HTML tendrá barras invertidas raras y la copia en la base de datos estará llena de símbolos. Unas cuantas rondas de esta codificación errónea y obtienes esa situación en la que cada vez que editas algo, salen largas cadenas de \\\\\\\\\\\\\\\\\\\\ y &.

La única manera que puede filtrar de forma segura en una sola vez en el momento de inicio es mediante la eliminación por completo todos los caracteres que deben ser escapado en cualquier de los contextos que vas a estar utilizando. Pero eso significa que no hay apóstrofes o barras diagonales inversas en su HTML, sin ampersands o menos en su base de datos, y probablemente una gran cantidad de otros signos de puntuación no deseados por la URL tenga que ir también. Para un sitio simple que no toma texto arbitrario, tal vez pueda salirse con la suya. Pero usualmente no.

Así que solo puede escapar sobre la marcha cuando un tipo de texto entra en otro. La mejor estrategia para evitar el problema es evitar concatenar texto en otros contextos tanto como sea posible, por ejemplo, usando consultas parametrizadas en lugar de creación de cadenas SQL y definiendo una función echo(htmlspecialchars()) con un buen nombre corto para hacerlo Menos trabajo para escribir, o usar un sistema de plantillas alternativo que escapa HTML de forma predeterminada.

+0

Escribes respuestas terriblemente largas (aunque una buena explicación). –

+0

@bobince: Digo que se puede hacer hasta cierto punto si 1.) sabe qué va a necesitar en el guión, y 2.) marca las variables sanitizadas como lo que son. He tenido mi parte de \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ :) Mi objetivo principal es tener un "punto de control de seguridad" básico con un conjunto definido de controles, en lugar de extraer elementos de las matrices en todo el código. –

+0

Una explicación simple es que el filtrado/sanitización es solo una parte del proceso por el que deben pasar sus datos. Los datos desinfectados aún deben ser escapados. p.ej. no colocaría una dirección de correo electrónico sin comillas en una consulta SQL, sin importar cuán válida sea. –

3

En la programación, debe ser tan restrictivo en su entrada como sea posible. Eso también se aplica a las fuentes de datos. $ _REQUEST contiene todo en $ _GET, $ _POST y $ _COOKIE, lo que puede ocasionar problemas.

Piense, por ejemplo, qué sucede si un complemento de su CMS introduce una nueva clave especial en uno de ellos, que pasa a existir como una clave significativa en otro complemento?

Así que NO use nunca $ _REQUEST. Use $ _GET, $ _POST o $ _COOKIE, lo que se ajuste a su situación. Es una buena práctica ser lo más estricto posible, y eso no tiene nada que ver con PHP, sino con la programación en general.

+1

Punto válido para $ _REQUEST, pero deberían decirlo en lugar de dejarlo sin implementar. –

Cuestiones relacionadas