Menú
Es gratis
registro
casa  /  Firmware/ Compruebe la existencia de la variable php. Comprobando la existencia de una variable

Compruebe la existencia de la variable php. Comprobando la existencia de una variable

El material está destinado principalmente a programadores web principiantes.

Introducción.

A menudo se me acercan clientes que tienen instalado un CMS escrito por ellos mismos o módulos escritos por programadores web novatos que no entienden lo que se necesita para proteger los datos y, a menudo, copian funciones de filtrado sin pensar en cómo funcionan y qué es exactamente lo que se debe hacer con ellas. .

Aquí intentaré describir con el mayor detalle posible los errores comunes al filtrar datos en Secuencia de comandos PHP y dar consejos sencillos cómo filtrar correctamente los datos.

Hay muchos artículos en Internet sobre el filtrado de datos, pero no están completos y sin ejemplos detallados.

Interrogación.

Filtración. Error # 1
Para las variables numéricas, se utiliza la siguiente verificación:
$ número = $ _GET ["input_number"]; if (intval ($ número)) (... ejecutar consulta SQL ...)
¿Por qué conducirá a inyección SQL? El punto es que el usuario puede especificar en la variable número de entrada significado:
1 "+ UNIÓN + SELECCIONAR
En este caso, la verificación se aprobará con éxito. la función intval obtiene el valor entero de la variable, es decir 1, pero en la propia variable $ número nada ha cambiado, entonces todo código malicioso se pasará a la consulta SQL.
Filtrado correcto:
$ número = intval ($ _ GET ["input_number"]); if ($ número) (... ejecutar la consulta SQL ...)
Por supuesto, la condición puede cambiar, por ejemplo, si solo necesita obtener un rango específico:
if ($ número> = 32 Y $ número<= 65)

Si está utilizando casillas de verificación o selecciones múltiples con valores numéricos, marque esto:
$ checkbox_arr = array_map ("intval", $ _POST ["checkbox"]);
array_map
También me encuentro con el filtrado en la forma:
$ número = htmlspecialchars (intval ($ _ GET ["input_number"]));
htmlspecialchars
O:
$ número = mysql_escape_string (intval ($ _ GET ["input_number"]));
mysql_escape_string

No puede causar nada más que una sonrisa :)

Filtración. Error # 2.
Para las variables de cadena, se utiliza el siguiente filtrado:
$ input_text = añade barras ($ _ GET ["input_text"]);
La función Addlashes escapa a los especiales. caracteres, pero no tiene en cuenta la codificación de la base de datos y el filtrado se puede omitir. No copiaré el texto del autor que describió esta vulnerabilidad y solo daré un enlace a Chris Shiflett (puede buscar la traducción en Internet en ruso).

Utilice la función mysql_escape_string o mysql_real_escape_string, ejemplo:
$ input_text = mysql_escape_string ($ _ GET ["input_text"]);
Si no tiene la intención de entrar etiquetas html, entonces es mejor hacer el siguiente filtrado:
$ input_text = strip_tags ($ _ GET ["input_text"]); $ input_text = htmlspecialchars ($ input_text); $ input_text = mysql_escape_string ($ input_text);
strip_tags: elimina las etiquetas html.
htmlspecialchars: convierte archivos especiales. caracteres en la entidad html.
Esto lo protegerá de ataques XSS distintos de la inyección SQL.
Si necesita etiquetas html, pero solo para mostrar el código fuente, entonces es suficiente usar:
$ input_text = htmlspecialchars ($ _ GET ["input_text"]); $ input_text = mysql_escape_string ($ input_text);

Si es importante para usted que el valor de la variable no esté vacío, utilice la función de recorte, por ejemplo:
$ input_text = trim ($ _ GET ["input_text"]); $ input_text = htmlspecialchars ($ input_text); $ input_text = mysql_escape_string ($ input_text);

Filtración. Error número 3.
Se trata de búsqueda en bases de datos.
Para buscar por números, use el filtrado descrito en el primer error.
Para buscar por texto, utilice el filtrado descrito en el segundo error, pero con salvedades.
Para que el usuario no pueda realizar un error lógico, es necesario eliminar o filtrar el especial. Símbolos SQL.
Ejemplo sin añadir. procesamiento de línea:
$ input_text = htmlspecialchars ($ _ GET ["input_text"]); // Buscar: "%" $ input_text = mysql_escape_string ($ input_text);
En la salida, obtenemos una solicitud del formulario:
... DONDE text_row LIKE "%". $ Input_text. "%" ... // DONDE text_row LIKE "%%%"
Esto aumentará significativamente la carga en la base.
En mi script, uso una función que elimina los caracteres no deseados de la búsqueda:
function strip_data ($ text) ($ quotes = array ("\ x27", "\ x22", "\ x60", "\ t", "\ n", "\ r", "*", "%", "<", ">","? ","! "); $ goodquotes = array (" - "," + "," # "); $ repquotes = array (" \ - "," \ + "," \ # "); $ text = trim (strip_tags ($ text)); $ text = str_replace ($ quotes, "", $ text); $ text = str_replace ($ goodquotes, $ repquotes, $ text); $ text = ereg_replace ("+" , "", $ texto); return $ texto;)
Por supuesto, no todos los símbolos anteriores son peligrosos, pero en mi caso no son necesarios, así que realizo una búsqueda y reemplazo.
Un ejemplo de uso de filtrado:
$ input_text = strip_data ($ _ GET ["input_text"]); $ input_text = htmlspecialchars ($ input_text); $ input_text = mysql_escape_string ($ input_text);
También te aconsejo que limites el número de caracteres en la búsqueda, al menos no menos de 3, porque si tiene una gran cantidad de registros en la base de datos, una búsqueda de 1 a 2 caracteres aumentará significativamente la carga en la base de datos.
Filtración. Error # 4.
Los valores de una variable no se filtran $ _GALLETA... Algunas personas piensan que dado que esta variable no se puede pasar a través del formulario, esto es una garantía de seguridad.
Esta variable es muy fácil de falsificar por cualquier navegador editando las cookies del sitio.
Por ejemplo, en un CMS conocido se verificó la plantilla de sitio utilizada:
if (@is_dir (MAIN_DIR. "/ template /". $ _COOKIE ["skin"])) ($ config ["skin"] = $ _COOKIE ["skin"];) $ tpl-> dir = MAIN_DIR. "/ plantilla /". $ config ["piel"];
En este caso, puede sustituir el valor de la variable $ _COOKIE ["piel"] y provocar un error, como resultado de lo cual verá la ruta absoluta a la carpeta del sitio.
Si utiliza el valor de las cookies para guardar en la base de datos, utilice uno de los filtros descritos anteriormente, esto también se aplica a la variable $ _SERVER.
Filtración. Error # 5.
Directiva incluida register_globals... Asegúrese de apagarlo si está encendido.
En algunas situaciones, puede pasar el valor de una variable que no debería haberse pasado, por ejemplo, si hay grupos en el sitio, entonces la variable $ group debería estar vacía o igual a 0 para el grupo 2, pero es suficiente para falsificar el formulario agregando el código:

En el script PHP, la variable $ grupo será igual a 5 si no se declaró con un valor predeterminado en el script.
Filtración. Error # 6.
Revisa tus descargas.
Compruebe los siguientes puntos:
  1. Extensión de archivo. Es conveniente prohibir la descarga de archivos con extensiones: php, php3, php4, php5, etc.
  2. ¿El archivo está subido al servidor? Move_uploaded_file
  3. tamaño del archivo
Examen. Error # 1.
Me encontré con casos en los que para una solicitud AJAX (por ejemplo: aumentar la reputación) se pasaba el nombre de usuario o su ID (a quien se aumenta la reputación), pero en PHP no se verificaba la existencia de dicho usuario.
Por ejemplo:
$ id_usuario = intval ($ _ REQUEST ["id_usuario"]); ... INSERT INTO REPLOG SET uid = "($ user_id)", más = "1" ... ... ACTUALIZAR Usuarios SET reputación = reputación + 1 DONDE user_id = "($ user_id)" ...
Resulta que creamos un registro en la base de datos, que es completamente inútil para nosotros.
Examen. Error # 2.
Al realizar varios tipos de acciones (agregar, editar, eliminar) con datos, no olvide verificar los derechos del usuario para acceder a esta función y características adicionales(usando etiquetas html o la capacidad de publicar material sin verificación).

Durante mucho tiempo solucioné un error similar en un módulo del foro, cuando cualquier usuario podía editar el mensaje de administración.

Examen. Error número 3.
Cuando se utilizan varios archivos php haz una simple comprobación.
En archivo index.php(o en cualquier otro archivo principal) escriba esta línea antes de incluir otros archivos php:
define ("READFILE", verdadero);
Al comienzo de otros archivos php, escriba:
if (! defined ("READFILE")) (exit ("Error, forma incorrecta de archivar.
Ir a la principal."); }
Esto restringirá el acceso a los archivos.
Examen. Error # 4.
Utilice hash para los usuarios. Esto ayudará a evitar que XSS llame a una función en particular.
Un ejemplo de generación de hash para usuarios:
$ clave_secreta = md5 (strtolower ("http://site.ru/". $ miembro ["nombre"]. sha1 ($ contraseña). fecha ("Ymd"))); // $ secret_key es nuestro hash
A continuación, en todas las formas importantes, sustituya una entrada con el valor del hash actual del usuario:

Durante la ejecución del script, verifique:
if ($ _POST ["clave_secreta"]! == $ clave_secreta) (salir ("Error: clave_secreta!");)
Examen. Error # 5.
Cuando muestre errores de SQL, haga una restricción simple en el acceso a la información. Por ejemplo, establezca una contraseña para una variable GET:
if ($ _GET ["passsql"] == "contraseña") (... Salida de error SQL ...) else (... Solo información de error, sin detalles ...)
Esto ocultará información al pirata informático que podría ayudarlo a piratear el sitio.
Examen. Error # 5.
Intente no incluir archivos obteniendo nombres de archivos de forma externa.
Por ejemplo:
if (isset ($ _ GET ["nombre_archivo"])) (incluya $ _GET ["nombre_archivo"]. ". php";)
Usa el interruptor

Quiero comprobar si existe una variable. Ahora estoy haciendo algo como esto:

Pruebe: myVar excepto NameError: # Haga algo.

¿Hay otras formas sin excepciones?


2018-05-09 13:10

Respuestas:

Para verificar la presencia de una variable local:

Si "myVar" en locals (): # myVar existe.

Para verificar la existencia de una variable global:

Si "myVar" en globals (): # myVar existe.

Para comprobar si un objeto tiene un atributo:

Si hasattr (obj, "attr_name"): # obj.attr_name existe.


2018-05-09 13:16

Usar variables que no se han definido o establecido (implícita o explícitamente) casi siempre es malo Ningún ya que esto indica que la lógica del programa no se pensó correctamente y es probable que conduzca a un comportamiento impredecible.

El siguiente truco, que es similar al suyo, asegurará que la variable tenga algunos valor antes de su uso:

Prueba: myVar excepto NameError: myVar = None # Ahora eres libre de usar myVar sin que Python se queje.

Sin embargo, todavía no creo que sea una buena idea; en mi opinión, debería refactorizar su código para evitar esta situación.


2018-05-09 13:19

Usando try / except - La mejor manera comprobar la existencia de una variable. Pero es casi seguro que hay una mejor manera de hacer lo que está haciendo que configurar / probar globales.

Por ejemplo, si desea inicializar una variable de nivel de módulo la primera vez que llama a alguna función, será mejor que haga algo como esto con el código:

My_variable = None def InitMyVariable (): global my_variable si my_variable es None: my_variable = ...


2018-05-09 13:27

para objetos / módulos, también puede

"var" en dir (obj)

Por ejemplo,

>>> clase Algo (objeto): ... pasar ... >>> c = Algo () >>> ca = 1 >>> "a" en dir (c) Verdadero >>> "b" en dir (c) Falso


2017-10-28 18:39

La forma fácil es inicializarlo primero myVar = None

Entonces despúes:

Si myVar no es None: # Haga algo


2018-06-04 18:46

Supongo que la prueba se usará en una función similar a la respuesta del usuario97370. No me gusta esta respuesta porque contamina el espacio de nombres global. Una forma de solucionar esto es usar una clase en su lugar:

Clase InitMyVariable (objeto): my_variable = None def __call __ (self): si self.my_variable es None: self.my_variable = ...

No me gusta esto porque complica el código y abre preguntas como si esto confirma el patrón de programación Singleton. Afortunadamente, Python ha permitido que las funciones tengan atributos por un tiempo, lo que nos da esta sencilla solución:

Def InitMyVariable (): si InitMyVariable.my_variable es None: InitMyVariable.my_variable = ... InitMyVariable.my_variable = None


2018-03-25 20:31

2018-05-09 13:12

Una forma que a menudo funciona bien para manejar este tipo de situación es no verificar explícitamente si la variable existe, sino seguir adelante y envolver el primer uso de la variable posiblemente no existente en un try / except NameError.

función nula (11)

Tengo (o no) una variable $ _GET ["myvar"] proveniente de mi cadena de consulta y quiero verificar si esta variable existe y también si el valor coincide con algo dentro de mi declaración if:

Lo que estoy haciendo y creo que no es la mejor manera de hacerlo:

if (isset ($ _ GET ["myvar"]) && $ _GET ["myvar"] == "algo"): haz algo

Este es un caso simple, pero imagina que quieres comparar muchas de estas variables $ myvar.

Respuestas

Esto es similar a la respuesta aceptada, pero usa in_array en su lugar. Prefiero usar empty () en esta situación. También sugiero usar la nueva declaración de matriz de cadenas que está disponible en PHP 5.4.0+.

$ permitido = ["algo", "nada"]; if (! empty ($ _ GET ["myvar"]) && in_array ($ _ GET ["myvar"], $ permitido)) (..)

Aquí hay una función para probar varios valores a la vez.

$ arrKeys = array_keys ($ _ OBTENER); $ permitido = ["algo", "nada"]; función checkGet ($ arrKeys, $ permitido) (foreach ($ arrKeys como $ clave) (if (in_array ($ _ GET [$ clave], $ permitido)) ($ valores [$ clave];)) devuelve $ valores ;)

Yo uso todo el mío función útil exst (), que declara variables automáticamente.

$ elemento1 = exst ($ arr ["clave1"]); $ val2 = exst ($ _ POST ["key2"], "novalue"); / ** * Función exst () - Comprueba si la variable ha sido configurada * (cópiala / pégala en cualquier lugar de tu código) * * Si la variable está configurada y no está vacía, devuelve la variable (sin transformación) * Si la variable no está configurado o vacío, devuelve el $ valor predeterminado * * @param mixed $ var * @param mixed $ default * * @return mixed * / function exst (& $ var, $ default = "") ($ t = "" ; if (! isset ($ var) ||! $ var) (if (isset ($ default) && $ default! = "") $ t = $ default;) else ($ t = $ var;) if (is_string ($ t)) $ t = recortar ($ t); devolver $ t;)

Bueno, puedes arreglártelas con solo if ($ _ GET ["myvar"] == "algo") ya que esta condición supone que la variable también existe. Si no es así, la expresión también se evaluará como falsa.

Creo que está bien hacerlo en condiciones como las anteriores. En realidad, no hay daño.

Mi pregunta es, ¿hay alguna manera de hacer esto sin declarar la variable dos veces?

No, no hay forma de hacerlo bien sin hacer dos comprobaciones. Eso también lo odio.

Una forma de evitar esto es importar todas las variables GET relevantes en un punto central en una matriz u objeto de un tipo específico (la mayoría de MVC lo hace automáticamente) y establecer las propiedades que se necesitan más adelante. (En lugar de acceder a las variables de solicitud a través del código).

If (isset ($ _ GET ["myvar"]) == "algo")

Gracias a Mellowsoon y Pekka, investigué un poco aquí y se me ocurrió esto:

  • Verifique y declare cada variable como nula (si es así) antes de usarla (como se recomienda):
! isset ($ _ GET ["myvar"])? $ _GET ["myvar"] = 0: 0;

* ok, esto es simple pero funciona muy bien, puede comenzar a usar la variable en todas partes después de esta línea

  • Usando una matriz para todos los casos:
$ myvars = matriz ("var1", "var2", "var3"); foreach ($ myvars como $ clave)! isset ($ _ GET [$ clave])? $ _GET [$ clave] = 0: 0;

* después de eso, puede usar sus variables (var1, var2, var3 ... etc.),

PD: una función que obtenga un objeto JSON debería ser mejor (o una cadena delimitada simple para bang / bang);

Se agradecen los mejores enfoques :)

ACTUALIZAR:

Use $ _REQUEST en lugar de $ _GET, de esta manera cubrirá las variables $ _GET y $ _POST.

Isset ($ _ REQUEST [$ key])? $ _REQUEST [$ clave] = 0: 0;

La solución que encontré en el juego es hacer esto:

If ($ x = & $ _ GET ["myvar"] == "algo") (// hacer cosas con $ x)

Como sugerencia, podría considerar este enfoque:

Required = array ("myvar" => "defaultValue1", "foo" => "value2", "bar" => "value3", "baz" => "value4"); $ missing = array_diff ($ obligatorio, array_keys ($ _ GET)); foreach ($ falta como $ clave => $ predeterminado) ($ _GET [$ clave] = $ predeterminado;)

Establece los valores predeterminados y establece los parámetros no recibidos en los valores predeterminados :)

Desafortunadamente, esta es la única forma de hacerlo. Pero existen enfoques para trabajar con arreglos grandes. Por ejemplo, algo como esto:

$ required = array ("myvar", "foo", "bar", "baz"); $ missing = array_diff ($ obligatorio, array_keys ($ _ GET));

La variable $ missing ahora contiene una lista de valores que son obligatorios pero que faltan en la matriz $ _GET. Puede usar $ missing array para mostrar el mensaje al visitante.

O puedes usar algo como esto:

$ required = array ("myvar", "foo", "bar", "baz"); $ missing = array_diff ($ obligatorio, array_keys ($ _ GET)); foreach ($ falta como $ m) ($ _GET [$ m] = null;)

Ahora cada elemento requerido tiene un valor predeterminado. Ahora puede usar if ($ _ GET ["myvar"] == "algo") sin preocuparse de que la clave no esté configurada.

Actualizar

Otra forma de limpiar el código sería usar una función que verifique si se ha establecido un valor.

Función getValue ($ key) (if (! Isset ($ _ GET [$ key])) (return false;) return $ _GET [$ key];) if (getValue ("myvar") == "algo") ( / / Haz algo)

por qué no crear una función para hacer esto, convertir la variable que desea verificar en una variable real, por ejemplo.

Función _FX ($ nombre) (si (isset ($$ nombre)) devuelve $$ nombre; de ​​lo contrario, devuelve nulo;)

luego haces _FX ("param") == "123", solo un pensamiento

Encontré (mucho) mejor codigo para hacer esto si desea probar algo en.

Si [[$ 1 = ""]] entonces echo "$ 1 está en blanco" si no echo "$ 1 está lleno" fi

¿Por qué es todo esto? Todo lo que existe en Bash, pero está vacío de forma predeterminada, por lo que test -z y test -n no pueden ayudarte.

Si [$ (# 1) = 0] entonces echo "$ 1 está en blanco" si no echo "$ 1 está lleno" fi

Puede comprobar si existe una determinada variable (es decir, si está inicializada). Para hacer esto, use la función:

Isset (variable);

Si la variable en este momento no existe (no se le ha asignado un valor en ninguna parte antes o ha sido eliminado por una función desarmado () ), luego la función Está establecido () devoluciones falso , de lo contrario - cierto :

$ x = 5;

si (isset ($ x))

eco ‘< BR > Variable $ X existe "," su valor es $ X < BR >”;

La pantalla mostrará:

Variable $ X existe, su valor es 5

Es importante recordar que no podemos usar una variable no inicializada en el programa; esto generará una advertencia del intérprete. PHP .

Para saber si un valor es una variable vacío , la función se utiliza:

vacío ( variable);

Si el valor de la variable es cero ,“0”, NULO , linea vacia (“” ), falso, la variable no está declarada o es una matriz vacía entonces esta función regresa cierto , de lo contrario - falso .

Verificar un tipo variable, las funciones se utilizan:

Is_string (variable);

es _ En t (variable);

es _ flotador (variable);

es _ nulo (variable);

es _ formación (variable);

es _ numérico (variable); - si la variable es numérica ( entero , flotador ) o una cadena que contiene solo números.

Estas funciones regresan cierto si la variable es del tipo especificado.

Salida de datos

Salida sin formato

Sin formato la salida de cadenas o valores de variables la realiza la función:

eco lista de variables;

eco línea;

donde lista de variables - los nombres de las variables de salida, separados por comas.

Si estamos trabajando con un navegador web, esta función dirige la salida al lado del cliente del navegador (a su ventana).

Como ya se dijo, si en una línea encerrada en doble comillas, se encuentran nombres de variables, se muestran los valores correspondientes en lugar de estos nombres. Además, si dicha cadena contiene etiquetas HTML (descriptores entre paréntesis angulares), el navegador muestra este HTML -codificar la forma en que debería hacerlo cuando se interprete HTML -documento:

$ año = 2012;

$ mensaje = " Deseo a todos felicidad !”;

eco "

Mi Felicidades !

”;

eco " Ha llegado $ año año !
$ mensaje
”;

?>

Se mostrará el título del nivel. H 3 y un saludo posterior, con la palabra “ ¡felicidad!" se imprimirá en negrita y cursiva:

¡Mis felicitaciones!

¡2012 ha llegado! Les deseo a todos ¡felicidad!

Así es como creas sitios dinámicos.

Salida formateada

Formateado la salida le permite representar los números generados en diferentes sistemas numéricos y en el sistema decimal, en diferentes formas ( formatos ). Es similar a la salida formateada en Si y lo llevan a cabo las funciones:

printf ("Formato", lista de salida);

sprintf ("Formato", lista de salida);

La primera función envía datos formateados a la ventana del navegador y devuelve su cantidad.

La segunda función solo formatea los datos de salida, pero no los genera.

Formato Es una secuencia de descriptores de conversión para valores de salida.

Transformar descriptor para cada valor tiene la forma:

% Tipo de precisión de longitud de alineación de marcador de posición

- Agregar Es un carácter que se utilizará para completar el resultado de la conversión al especificado longitud (defecto - espacio ); si es otro carácter, va precedido de una comilla simple ( apóstrofe ),

- Alineación - por defecto - por derecho el borde del campo de salida; si hay un menos - ), entonces por izquierda ,

- Longitud - ancho del campo de salida - el número de espacios de caracteres asignados para la salida de este valor. Si el valor mostrado contiene menos familiaridad que el especificado longitud entonces el espacio restante se llenará espacios o caracteres de relleno,

- Exactitud - el número de posiciones decimales en la parte fraccionaria del número,

- Un tipo - tipo de valor de salida:

B binario ,

Con símbolo ,

D entero en notación decimal,

mi material en forma exponencial (punto flotante),

F material en forma de punto fijo,

s línea ,

O entero en el sistema de números octales,

X entero en notación hexadecimal.

Ejemplo:

php

$ zarp _1 = 6543.21;

$ zarp _2 = 45321.67;

$ fam _1 = "Balaganov";

$ fam _2 = "Bender";

printf ("< H 1> Nómina h 1>");

printf ("%" .- 12s% ". 10.2f frotar.", $ fam_1, $ zarp_1);

eco "
";

printf ("%" .- 12s% ". 10.2f frotar.", $ fam_2, $ zarp_2);

eco "
";

?>

El punto fue elegido como marcador de posición ( ‘. ). Los apellidos están alineados a la izquierda ( - ) en un campo de ancho 12 caracteres. Los números se representan en forma de punto fijo en un campo amplio 10 personajes y con precisión 2 lugares decimales, justificado a la derecha.