Foros del Web » Programando para Internet » PHP »

Ejemplo/Aporte Separar conexion y consultas + seguridad en pocas líneas

Estas en el tema de Ejemplo/Aporte Separar conexion y consultas + seguridad en pocas líneas en el foro de PHP en Foros del Web. Bueno me animo a dejarles estas 3 pequeñas funciones por si pueden servir de ayuda a aquellos que comienzan con php y las consultas. Muchas ...
  #1 (permalink)  
Antiguo 16/07/2011, 14:24
 
Fecha de Ingreso: agosto-2010
Ubicación: Tenerife
Mensajes: 893
Antigüedad: 13 años, 8 meses
Puntos: 202
Ejemplo/Aporte Separar conexion y consultas + seguridad en pocas líneas

Bueno me animo a dejarles estas 3 pequeñas funciones por si pueden servir de ayuda a aquellos que comienzan con php y las consultas.

Muchas veces veo en este foro y en otros lugares que la gente copia al principio de cada página la conexión de la base de datos y después de todo el código lo acaba con varios mysql_free_result() y mysql_close() (Si es que los ponen)
También es habitual gente que pregunta donde está su error en la consulta cuando basta con añadir un mysql_error() para saberlo.

Igualmente la gente repite demasiado los mysql_query() y los mysql_fetch
Podemos hallar los datos con una sola línea ayudándonos de estas funciones que me dió por hacer.

Código PHP:
if($row get_rows("SELECT id FROM registro WHERE nick='$nick' and password='$password'") ) 
Muestro un ejemplo sencillito que hice:

connection.php
Código PHP:
class DBconnection{
    
    public 
$db_data;  
     
    function 
connect(){
    if(
$this->db_data mysql_connect("***""***""***") or die(mysql_error()) )
        return ( 
$db_name mysql_select_db("***"$this->db_data ) or die(mysql_error()) ) ? true false;
    }
}

function 
get_rows($result=''){
    
$con = new DBconnection;
    if (
$con->connect() and !empty($result)){
        
        
$result=mysql_query($result) or die(mysql_error()); 
        
$row mysql_fetch_array($result);
        
        
mysql_free_result($result);
        
mysql_close($con->db_data);
        
        return 
$row;
    }
}

//Seguridad para evitar ataques
function clean_var($var=''){
    
$con = new DBconnection;
    if (
$con->connect())
        return 
mysql_real_escape_string(trim(strip_tags(stripslashes($var))));

Y aquí un ejemplo de un login para mostrar como se usa. Así de paso puede ayudar a quienes empiezen en este mundillo.

Código PHP:
<?php
include("conexion/connection.php");

if (isset (
$_POST["iniciar"] )){

    
$nick     clean_var($_POST["nick"]);
    
$password clean_var($_POST["pass"]);
    
    if(
$row get_rows("SELECT id FROM registro WHERE nick='$nick' and password='$password'") ){
        
session_start();
        
$_SESSION["user_id"] = $row["id"];
        
$_SESSION["user_name"] = $nick;
        echo
'<script languaje="javascript">alert(\'Bienvenido '.$nick.'.\');</script>';
    }
    else
        echo
'<script languaje="javascript">alert(\'Los datos no coinciden.\');</script>';
}

if (isset (
$_POST["salir"]) and isset($_SESSION["user_id"]) ) // cerrar session
    
session_destroy();
?>

<?php if( ! isset($_SESSION["user_id"]) ) { ?>

<form action="<?php $_SERVER["PHP_SELF"?>" method="post">
<input type="text"     name="nick"   maxlength="14"  />
<input type="password" name="pass"   maxlength="14"  />
<input type="submit"   name="iniciar" value="Acceder"/>
</form>

<?php } else { ?>

<form action="<?php $_SERVER["PHP_SELF"?>" method="post">
<input type="text"   name="nick"  readonly="readonly" value="<?php echo $_SESSION["user_name"?>" />
<input type="submit" name="salir" value="Salir" />
</form>

<?php ?>

Explicaré las funciones ya que el ejemplo va para quienes comienzan:
  • connect() -> Establece la conexión a la base de datos.
    No llamaremos a esta función que está dentro de una clase y orientada a objetos, sino que sólo abriremos la conexión cuando se haga una consulta.
  • clean_var() -> Se encarga de la seguridad de las variables que enviemos por POST o GET.
    1. Abrimos la conexión para poder usar mysql_real_escape_string() y evitar posibles inyecciones de código.
    2. Quitamos cualquier espacio de más usando trim()
    3. Eliminamos posibles etiquetas y caracteres como < > con strip_tags()
    4. quitamos posibles barras de un string con comillas escapadas con stripslashes().
    5. IMPORTANTE: recuerda que es un ejemplo para un login, muchas de estas funciones pueden ser innecesarias, por ejemplo si quieres enviar un código html por post.
  • get_rows() -> Realiza la consulta, devuelve el array con los datos, libera la memoria de la consulta y cierra la conexión.

Seguramente sea mejorable en cuyo caso cualquier idea siempre es bien recibida
__________________
Pensaba que internet era una gran biblioteca de sabiduría, hasta que comprendí que un libro no puede tener mil páginas llenas de faltas de ortografía... :(
  #2 (permalink)  
Antiguo 16/07/2011, 19:07
(Desactivado)
 
Fecha de Ingreso: julio-2011
Mensajes: 74
Antigüedad: 12 años, 9 meses
Puntos: 4
Respuesta: Ejemplo/Aporte Separar conexion y consultas + seguridad en pocas líneas

olle pero que buena informacion pero lo de clean_var( me dejo desconsertado ¿esque no basta con mysql_real_escape_string ?¿cual es el problema?
  #3 (permalink)  
Antiguo 16/07/2011, 19:31
Avatar de Sourcegeek
Colaborador
 
Fecha de Ingreso: mayo-2009
Ubicación: $mex['B.C.'];
Mensajes: 1.816
Antigüedad: 14 años, 11 meses
Puntos: 322
Respuesta: Ejemplo/Aporte Separar conexion y consultas + seguridad en pocas líneas

Buen aporte, sólo que deberías 'ampliar' un poco la protección que ofrece clean_var. Por ejemplo, para inyecciones del tipo:
Código SQL:
Ver original
  1. 1 AND 1=0 UNION SELECT TABLE_NAME,NULL FROM informacion_schema.TABLES

De ahí en más, buen aporte!
__________________
Buscas desarrollador web? Sourcegeek. Diseño web, Maquetación y Programación
¡Escribe bien! Esto es un foro, no un Facebook para que escribas con los pies
  #4 (permalink)  
Antiguo 17/07/2011, 06:54
 
Fecha de Ingreso: agosto-2010
Ubicación: Tenerife
Mensajes: 893
Antigüedad: 13 años, 8 meses
Puntos: 202
Respuesta: Ejemplo/Aporte Separar conexion y consultas + seguridad en pocas líneas

Cita:
Iniciado por maco8899 Ver Mensaje
olle pero que buena informacion pero lo de clean_var( me dejo desconsertado ¿esque no basta con mysql_real_escape_string ?¿cual es el problema?
No hay ningún problema con esa función pero usar sólo mysql_real_escape_string no asegura al 100% todos los tipos de inyección.
Fíjate lo que comenta Sourcegeek
__________________
Pensaba que internet era una gran biblioteca de sabiduría, hasta que comprendí que un libro no puede tener mil páginas llenas de faltas de ortografía... :(
  #5 (permalink)  
Antiguo 17/07/2011, 09:07
 
Fecha de Ingreso: agosto-2010
Ubicación: Tenerife
Mensajes: 893
Antigüedad: 13 años, 8 meses
Puntos: 202
Respuesta: Ejemplo/Aporte Separar conexion y consultas + seguridad en pocas líneas

Cita:
Iniciado por Sourcegeek Ver Mensaje
Buen aporte, sólo que deberías 'ampliar' un poco la protección que ofrece clean_var. Por ejemplo, para inyecciones del tipo:
Código SQL:
Ver original
  1. 1 AND 1=0 UNION SELECT TABLE_NAME,NULL FROM informacion_schema.TABLES

De ahí en más, buen aporte!
Bueno, la verdad es que lo hice sencillito para la gente, pero efectivamente me di cuenta que la seguridad era mejorable.
Más simple usando expresiones regulares.

Código PHP:
function clean_var($var=''){
    
$con = new DBconnection;
    if (
$con->connect())
        return 
mysql_real_escape_string(trim(preg_replace("/[^a-z0-9]/","",$var)));

Saludos
__________________
Pensaba que internet era una gran biblioteca de sabiduría, hasta que comprendí que un libro no puede tener mil páginas llenas de faltas de ortografía... :(
  #6 (permalink)  
Antiguo 19/07/2011, 15:20
(Desactivado)
 
Fecha de Ingreso: julio-2011
Mensajes: 74
Antigüedad: 12 años, 9 meses
Puntos: 4
Respuesta: Ejemplo/Aporte Separar conexion y consultas + seguridad en pocas líneas

Esta fuerte eso tio mysql_real_escape_string(trim(preg_replace("/[^a-z0-9]/

pero donde lo coloco ,.tendria que ponerselo a todos los envios por post en tyoe text y etxt area?
  #7 (permalink)  
Antiguo 19/07/2011, 16:03
 
Fecha de Ingreso: agosto-2010
Ubicación: Tenerife
Mensajes: 893
Antigüedad: 13 años, 8 meses
Puntos: 202
Respuesta: Ejemplo/Aporte Separar conexion y consultas + seguridad en pocas líneas

Cita:
Iniciado por maco8899 Ver Mensaje
Esta fuerte eso tio mysql_real_escape_string(trim(preg_replace("/[^a-z0-9]/

pero donde lo coloco ,.tendria que ponerselo a todos los envios por post en tyoe text y etxt area?
Depende de que valores vayas a pasar.
El ejemplo que pongo es para un login, permitiendo únicamente valores alfanuméricos, pero si tú quieres enviar por ejemplo código html en un textarea, deberías modificar la expresión regular o cambiar la función.

Ese preg_replace("/[^a-z0-9]/ elimina de la variable todos los caracteres que no sean números o letras.
__________________
Pensaba que internet era una gran biblioteca de sabiduría, hasta que comprendí que un libro no puede tener mil páginas llenas de faltas de ortografía... :(
  #8 (permalink)  
Antiguo 19/07/2011, 19:51
(Desactivado)
 
Fecha de Ingreso: julio-2011
Mensajes: 74
Antigüedad: 12 años, 9 meses
Puntos: 4
Respuesta: Ejemplo/Aporte Separar conexion y consultas + seguridad en pocas líneas

pero yo utilizo cosas como [b] para negrita y cosas asi. ¿se puede?
  #9 (permalink)  
Antiguo 19/07/2011, 20:06
Avatar de Triby
Mod on free time
 
Fecha de Ingreso: agosto-2008
Ubicación: $MX->Gto['León'];
Mensajes: 10.106
Antigüedad: 15 años, 8 meses
Puntos: 2237
Respuesta: Ejemplo/Aporte Separar conexion y consultas + seguridad en pocas líneas

IEKK, muy buen aporte, vendra muy bien principalmente para los que comienzan con PHP, solo una observacion:

session_start(); deberia ser la primera linea del script, para evitar problemas es necesario iniciar sesion siempre, independientemente de que el usuario haya ingresado correctamente o no, en estos casos, el control lo haces simplemente creando / modificando variables en $_SESSION.
__________________
- León, Guanajuato
- GV-Foto
  #10 (permalink)  
Antiguo 20/07/2011, 03:32
 
Fecha de Ingreso: agosto-2010
Ubicación: Tenerife
Mensajes: 893
Antigüedad: 13 años, 8 meses
Puntos: 202
Respuesta: Ejemplo/Aporte Separar conexion y consultas + seguridad en pocas líneas

Cita:
Iniciado por maco8899 Ver Mensaje
pero yo utilizo cosas como [b] para negrita y cosas asi. ¿se puede?
En ese caso no, pero tan sólo modifica la función o crea otra que te permita añadir esos valores.

Teniendo en cuenta que hablas de BBcode sólo tienes que añadir a la expresión regular que permita los caracteres / [ ] =

Saludos
__________________
Pensaba que internet era una gran biblioteca de sabiduría, hasta que comprendí que un libro no puede tener mil páginas llenas de faltas de ortografía... :(
  #11 (permalink)  
Antiguo 20/07/2011, 03:43
 
Fecha de Ingreso: agosto-2010
Ubicación: Tenerife
Mensajes: 893
Antigüedad: 13 años, 8 meses
Puntos: 202
Respuesta: Ejemplo/Aporte Separar conexion y consultas + seguridad en pocas líneas

Cita:
Iniciado por Triby Ver Mensaje
IEKK, muy buen aporte, vendra muy bien principalmente para los que comienzan con PHP, solo una observacion:

session_start(); deberia ser la primera linea del script, para evitar problemas es necesario iniciar sesion siempre, independientemente de que el usuario haya ingresado correctamente o no, en estos casos, el control lo haces simplemente creando / modificando variables en $_SESSION.
Buen consejo.
Es cierto, no daría problemas ejecutando el ejemplo tal cual, pero si el usuario abriese la sesión después de haber enviado texto en la página podía dar el típico: Warning: session_start(): Cannot send session cache limiter - headers already sent

Jejeje tenía que haberlo tenido en cuenta y más teniendo en cuenta que es un post para la gente que recién comienza.

Edito: maco8899, recordé un post en el foro de GatorV donde publica una función que puedes usar si quieres enviar por post BBcode o cualquier otra cosa de forma segura.
http://www.forosdelweb.com/f18/funci...5/#post3497564
__________________
Pensaba que internet era una gran biblioteca de sabiduría, hasta que comprendí que un libro no puede tener mil páginas llenas de faltas de ortografía... :(

Última edición por IEKK; 20/07/2011 a las 05:27
  #12 (permalink)  
Antiguo 25/07/2011, 22:53
(Desactivado)
 
Fecha de Ingreso: julio-2011
Mensajes: 74
Antigüedad: 12 años, 9 meses
Puntos: 4
Respuesta: Ejemplo/Aporte Separar conexion y consultas + seguridad en pocas líneas

IEKK el de bbcode no funciona me deja la plantalla en blanco.
  #13 (permalink)  
Antiguo 25/07/2011, 23:21
Avatar de Sourcegeek
Colaborador
 
Fecha de Ingreso: mayo-2009
Ubicación: $mex['B.C.'];
Mensajes: 1.816
Antigüedad: 14 años, 11 meses
Puntos: 322
Respuesta: Ejemplo/Aporte Separar conexion y consultas + seguridad en pocas líneas

Deberías abrir un nuevo post detallando el problema y poniendo el código que utilizas para no desvirtuar éste tema y poderte brindar una ayuda detallada.

Saludos!
__________________
Buscas desarrollador web? Sourcegeek. Diseño web, Maquetación y Programación
¡Escribe bien! Esto es un foro, no un Facebook para que escribas con los pies
  #14 (permalink)  
Antiguo 26/07/2011, 01:01
(Desactivado)
 
Fecha de Ingreso: julio-2011
Mensajes: 74
Antigüedad: 12 años, 9 meses
Puntos: 4
Respuesta: Ejemplo/Aporte Separar conexion y consultas + seguridad en pocas líneas

ok voy a abrirlo
  #15 (permalink)  
Antiguo 28/11/2011, 05:41
 
Fecha de Ingreso: septiembre-2011
Mensajes: 73
Antigüedad: 12 años, 7 meses
Puntos: 0
Respuesta: Ejemplo/Aporte Separar conexion y consultas + seguridad en pocas líneas

hola,
Si no lo he entendido mal, la función get_rows da como resultado una matriz ($row) con los resultados del select (en esta caso el id), pero y si necesitaramos que $row recogiera varias lineas ¿como podría reestructurar o recorrer posteriormente la matriz?
el caso práctico es que el select arrojara varios resultados como podría ser get_rows("SELECT * FROM productos WHERE precio > 10");
Gracias
  #16 (permalink)  
Antiguo 29/11/2011, 22:43
 
Fecha de Ingreso: septiembre-2011
Mensajes: 73
Antigüedad: 12 años, 7 meses
Puntos: 0
Respuesta: Ejemplo/Aporte Separar conexion y consultas + seguridad en pocas líneas

El problema que me encontraba es que si un query da varios resultados, la función get_rows me recogía solo el primer resultado.

al final me lo resolví con el siguiente cambio

function get_rows($result=''){
$con = new DBconnection;
if ($con->connect() and !empty($result)){

$result=mysql_query($result) or die(mysql_error());

$i=0;
$row_result='';
while($row = mysql_fetch_assoc($result)){
$row_result[$i] = $row;
$i++
}


mysql_free_result($result);
mysql_close($con->db_data);

return $row_result;
}
}

No estoy seguro de lo correcto que sea el código pero me funciona.
De esta forma la función me construye un array indexado ($row_result) en el que posteriormente puedo ir recuperando los diferentes resultados almacenados en los indices [0],[1],[2] [..... cada uno de ellos compuesto por los campos que se preguntaba en el query.

Última edición por jqcod; 29/11/2011 a las 22:49

Etiquetas: conexion, html, mysql, registro, seguridad, variables
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta

SíEste tema le ha gustado a 11 personas




La zona horaria es GMT -6. Ahora son las 19:28.