Foros del Web » Programando para Internet » PHP »

Usando Hash en URL

Estas en el tema de Usando Hash en URL en el foro de PHP en Foros del Web. Hola amigos, Estoy desarrollando una aplicación web, en donde entre dos o más empresas se pueden mandar un link para subir archivos a la BD, ...
  #1 (permalink)  
Antiguo 03/07/2013, 02:43
 
Fecha de Ingreso: agosto-2011
Ubicación: por ahi
Mensajes: 28
Antigüedad: 12 años, 8 meses
Puntos: 0
Pregunta Usando Hash en URL

Hola amigos,

Estoy desarrollando una aplicación web, en donde entre dos o más empresas se pueden mandar un link para subir archivos a la BD, supongamos que tenemos el index.php, donde la Empresa-1 puede mandar un correo a la Empresa-2 que contiene un link+hash, y con esto Empresa-2 puede subir archivos (además de titulo, comentario,etc. en la BD) de ahi mandarle el link+hash de descarga a Empresa1 de vuelta.

Espero haber explicado hasta aqui, la duda existencial que traigo es, yo estoy usando el hash guardado de cada Recipiente(empresa2,empresa..N) en la URL, la pregunta es, Qué tan seguro es hacer esto? me podrian insertar codigo malicioso por la URL?, porque alguna persona con malas intenciones y conocimientos informaticos estaria dandose cuenta del Hash que es un campo importante en la BD.

Esta aplicación estará solo en la intranet entre las empresas, pero aun asi me gustaria evitar estos problemas.

Muchas gracias a todos de antemano.

Saludos!
  #2 (permalink)  
Antiguo 03/07/2013, 02:46
Avatar de repara2  
Fecha de Ingreso: septiembre-2010
Ubicación: München
Mensajes: 2.445
Antigüedad: 13 años, 7 meses
Puntos: 331
Respuesta: Usando Hash en URL

Claro que abres un brecha de seguridad pero no sé hasta que punto puedes tener problemas en tu caso concreto. Documentate un poco sobre el tema private key / public key a ver si eso te da algunas ideas de cómo implementarlo, salu2.
__________________
Fere libenter homines, id quod volunt, credunt.
  #3 (permalink)  
Antiguo 03/07/2013, 05:29
 
Fecha de Ingreso: agosto-2011
Ubicación: por ahi
Mensajes: 28
Antigüedad: 12 años, 8 meses
Puntos: 0
Respuesta: Usando Hash en URL

Muchas gracias repara2, voy a investigar acerca del tema, otra pregunta aqui rapido, quiero pasar mi aplicación a un framework ya sea Codeigniter, Synfony,etc.
Estás usando alguno de estos? si? cual me recomendarias?

Saludos!! =)
  #4 (permalink)  
Antiguo 03/07/2013, 06:15
Avatar de repara2  
Fecha de Ingreso: septiembre-2010
Ubicación: München
Mensajes: 2.445
Antigüedad: 13 años, 7 meses
Puntos: 331
Respuesta: Usando Hash en URL

Yo recomiendo Symfony2 con Doctrine o bien Zend Framework. Respecto de "pasar" la aplicación, no es posible, el proceso implica reescribirlo todo. Salu2
__________________
Fere libenter homines, id quod volunt, credunt.
  #5 (permalink)  
Antiguo 04/07/2013, 00:35
 
Fecha de Ingreso: agosto-2011
Ubicación: por ahi
Mensajes: 28
Antigüedad: 12 años, 8 meses
Puntos: 0
De acuerdo Respuesta: Usando Hash en URL

Muy bien jaja, eso habia pensado, pero igual me sirve para practicar y seguir aprendiendo, muchas gracias por la recomendación.

Saludos!
  #6 (permalink)  
Antiguo 04/07/2013, 13:16
Avatar de Nemutagk
Colaborador
 
Fecha de Ingreso: marzo-2004
Ubicación: México
Mensajes: 2.633
Antigüedad: 20 años
Puntos: 406
Respuesta: Usando Hash en URL

No es correcto como aplicas tu logica de hast vs empresa, en todo caso es una relación de 1 a muchos, por lo cual deberías tener una tabla única y exclusivamente con los hash generados, y mejor aún generar un campo (en la misma tabla) donde se deshabilite dicho hash una vez usado, así te evitas problemas, por otro lado, una brecha de seguridad implica mas cosas que solo enviar un hash vía URL, lo mas recomendable seria que publicaras tu código y de hay observar y poder darte una ayuda mas completa...
__________________
Listo?, tendría que tener 60 puntos menos de IQ para considerarme listo!!!
-- Sheldon Cooper
http://twitter.com/nemutagk
PD: No contestaré temas vía mensaje personal =)
  #7 (permalink)  
Antiguo 04/07/2013, 21:29
Avatar de gildus  
Fecha de Ingreso: agosto-2003
Mensajes: 1.495
Antigüedad: 20 años, 8 meses
Puntos: 105
Respuesta: Usando Hash en URL

Holas,

Podria yo opino que emplearse varios temas de seguridad como SSL, tokens, Llaves firmadas publicas y privadas, control de ips, o puertos, registro de logs, etc. Pero como mencionan los amig@s deseamos codigo para opinarte mejor.

Saludos,
__________________
.: Gildus :.
  #8 (permalink)  
Antiguo 05/07/2013, 06:48
 
Fecha de Ingreso: agosto-2011
Ubicación: por ahi
Mensajes: 28
Antigüedad: 12 años, 8 meses
Puntos: 0
Respuesta: Usando Hash en URL

Hola amigos, gracias por las respuestas, voy a explicar más o menos como es la estructura de la aplicación.

En la BD tengo 3 Tablas:
Proceso: id,fechaCreado,FechaModificado,email,hash,tipoProc eso,hash_Usado,transferenciaTerminada,nombre,titul o, mensaje.
Files:id,fechaCreado,fechaModificado,nombre,tipo,hash,f ile,tamano, Ref_process.
Recipientes:id,fechaCreado,FechaModificado,nombre,email,hash, hash_usado,transferencia_confirmada,Ref_process.

En el codigo tengo un index principal, que es donde el usuario puede mandar un Email con el link+hash.
Este sería el archivo PHP que procesa la info:
Código PHP:
<?php
include_once '../mailer/class.phpmailer.php';
include_once 
'conec.php';    
            
$mail = new PHPMailer(true);            
            if(isset(
$_POST['name']) && !empty($_POST['name']) AND isset($_POST['email']) && !empty($_POST['email']) AND isset($_POST['switch']) OR isset($_POST['email2']) && !empty($_POST['email2']) AND isset($_POST['mailfrom']) && !empty($_POST['mailfrom'])){
                
$name mysql_escape_string($_POST['name']);
                
$opcion mysql_escape_string($_POST['switch']);
                if(
$opcion == "op1"){
                    
$emailC $_POST['email'].'@'.$_POST['filiales'];
                    
$email mysql_escape_string($emailC);  
                }else{
                    
$emailTo mysql_escape_string($_POST['email2']);
                    
$email2 $_POST['mailfrom'].'@'.$_POST['filiales2'];
                    
$email mysql_escape_string($email2); 
                }
                          
            if(
preg_match("/^([a-zA-Z0-9])+([a-zA-Z0-9\._-])*@/"$_POST['email']) or preg_match("/^([a-zA-Z0-9])+([a-zA-Z0-9\._-])*@([a-zA-Z0-9_-])+([a-zA-Z0-9\._-]+)+$/"$_POST['email']))
            {
                
// Return Error - Invalid Email                
                
echo 0;                
            }else{
                
                if(!
preg_match("/^([a-zA-Z0-9])+([a-zA-Z0-9\._-])*@([a-zA-Z0-9_-])+([a-zA-Z0-9\._-]+)+$/"$email)){
                    
// Return Error - Invalid Email
                    
echo 0;
                }else{                        
                    
// Return Success - Valid Email    
                    
                    
$hash md5(uniqid(rand())); // Generate random 32 character hash and assign it to a local variable.
                     
$horaActual date("d-m-Y H:i:s");
                     if(
$opcion == "op1"){
                         
$tipo 0;
                     }else if(
$opcion == "op2"){
                         
$tipo 1;
                     }                    
                    
mysql_query("INSERT INTO Proceso(correo, token, tipo, token_usado, nombre, titulo, mensaje) VALUES(
                    '"
mysql_escape_string($email) ."',
                    '"
mysql_escape_string($emailTo) ."',  
                    '"
mysql_escape_string($hash) ."', 
                    '"
mysql_escape_string($tipo) ."', 
                    '"
mysql_escape_string(0) ."', 
                    '"
mysql_escape_string($name) ."', 
                    '"
mysql_escape_string('') ."', 
                    '"
mysql_escape_string('') ."') ") or die(mysql_error());     
                                        
                    
$mail->From $email;
                    
$mail->FromName 'smth';
                    
$mail->IsHTML(true); // Set email format to HTML                    
                    
$mail->Subject 'smth';
                    if(
$opcion == 'op1'){
                        
$mail->AddAddress($email'smth');  // Add a recipient
                        
$mail->Body    '
<b>Thanks a lot!</b><br />
Your account has been validated, you can send a file by pressing the url below.
<br />
    ------------------------<br />
    Name: '
.$name.'        <br />        
    ------------------------<br />

Please click this link:<br />
http://dominio.com/verify/verify.php?hash='
.$hash.'

                    '
// Our message above including the link
                    
}else if($opcion == 'op2'){
                        
$mail->AddAddress($emailTo'smth');  // Add a recipient
                            
$mail->Body    '
<b>Hello</b><br />
You have received a link to upload a file, you can use it by pressing the url below.
<br />
Please click this link:<br />
http://dominio.com/verify/verify.php?hash='
.$hash.'

                    '
// Our message above including the link
                    
}                    
                    if(!
$mail->Send()) {
                       echo 
'Message could not be sent.';
                       echo 
'Mailer Error: ' $mail->ErrorInfo;
                       exit;
                    }else{
                        echo 
1;
                    }         
                    } 
// End second else 
                
// End first else
            
// End IF
            
mysql_close();            
?>
Cuando el usuario recibe el correo con el link+hash, los mando un archivo para verificar el estado del hash, como sigue:
Código PHP:
<?php        
    
include_once 'conec.php';        

    if(isset(
$_GET['hash']) && !empty($_GET['hash'])){
        
// Verify data    
        
if( ! ctype_alnum($_GET['hash'])){            
            
$hash strip_tags($_GET['hash']); // Set hash variable
            
$cons mysql_query("SELECT email FROM proceso WHERE hash='".$hash."' AND hash_usado='0'") or die(mysql_error());
            
$valida mysql_fetch_array($cons);
            
$email $valida[0];
            
$search mysql_query("SELECT email, hash, hash_usado FROM proceso WHERE email='".$email."' AND hash='".$hash."' AND hash_usado='0'") or die(mysql_error()); 
            
$match  mysql_num_rows($search);
            
$today date("Y-m-d H:i:s"); 
            if(
$match 0){
            
// We have a match, activate the account
                
mysql_query("UPDATE proceso SET hash_usado='1',record_modified ='".$today."' WHERE email='".$email."' AND hash='".$hash."' AND hash_usado='0'") or die(mysql_error());
                
header('Location: ../index.php?hash='.$hash);
                exit();
            }else{
            
// No match -> invalid url or account has already been activated.
                //echo '<div class="alert alert-error">The url is either invalid or you already have not been activated your account.</div>';
                
header('Location: ../404.html');
                exit();
            }
        }else{
            
// Invalid approach
            
header('Location: ../404.html');
            exit();
        }                
    }else{
    
// Invalid approach
        //echo '<div class="alert alert-error">Invalid approach, please use the link that has been send to your email.</div>';
        
header('Location: ../404.html');
        exit();
    }
    
mysql_close();
?>
Bueno aqui si todo sale bien, modifico el campo de "token_usado" a 1 (o true, que es mejor para ustedes?) en la tabla Proceso.
y lo redirijo a la parte donde puede mandar correo a N Recipientes con N Files mediante un link+hash del proceso, todos los recipientes tendrian el ID-Refencia del proceso.

Lo dejare hasta aqui por hoy, en el archivo dondeles agradezco cualquier consejo o critica, que quieran hacer.

Gracias de antemano.
  #9 (permalink)  
Antiguo 05/07/2013, 07:45
Avatar de Nemutagk
Colaborador
 
Fecha de Ingreso: marzo-2004
Ubicación: México
Mensajes: 2.633
Antigüedad: 20 años
Puntos: 406
Respuesta: Usando Hash en URL

En tu archivo que recibes el hash no entiendo para que usas el operador negativo ( ! ) en la función ctype_alnum(), lo que estas diciendo es que si la variable $_GET['hash'] contiene caracteres no alfanuméricos pase la validación, si contiene únicamente caracteres alfanuméricos envías un error 404, por lo que a mi parecer es lo contrario!, otra cosa, veo que no verificas si el hash generado ya existe, es poco probable, pero aun así deberías verificarlo, y referente a la seguridad a pesar que mysql_escape_string() es "potente" a mi aun así se me hace inseguro, ya que no es necesario escribir directamente las comillas para que el servidor MySQL las interprete, por ejemplo escribiendo %27 se interpreta como una comilla simple, para evitar estos problemas prefiero directamente pasar a PDO y evitarme dolores de cabeza, aparte que como ya se ah dicho infinidad de veces en este foro, las funciones mysql_* están obsoletas, por lo tanto queda usar PDO o en su defecto mysqli...

Y por ultimo, no le veo caso hacer 2 accesos a la tabla proceso para traer los mismos datos, si el hash es único (que así debería de ser) ya obtendrías todos los datos y evitar trabajo doble...

PD Se me olvidaba lo mas importante, tal vez te convenga mas usar OAuth que un sistema "arcaico" de validación con hash, digo, que para eso se desarrollo OAuth precisamente...
__________________
Listo?, tendría que tener 60 puntos menos de IQ para considerarme listo!!!
-- Sheldon Cooper
http://twitter.com/nemutagk
PD: No contestaré temas vía mensaje personal =)

Última edición por Nemutagk; 05/07/2013 a las 07:50
  #10 (permalink)  
Antiguo 05/07/2013, 08:04
Avatar de gildus  
Fecha de Ingreso: agosto-2003
Mensajes: 1.495
Antigüedad: 20 años, 8 meses
Puntos: 105
Respuesta: Usando Hash en URL

Holas,

En la parte que generas tu hash yo lo usaria asi:

Código PHP:
Ver original
  1. $hash = sha1(uniqid(mt_rand()));

Ahora en la parte que envias la URL, porque no tambien enviar el email como parametro ?, algo como:

'http://dominio.com/verify/verify.php?hash='.$hash.'&email='.$email;

Ahora cuando lo valides en el archivo verify.php ya no consultarias dos veces sino una sola vez ,aunque viendolo como lo realizas puedes tambien unirlos en una sola consulta:

Código PHP:
Ver original
  1. /// ..
  2. $search = mysql_query("SELECT email, hash, hash_usado FROM proceso WHERE hash='".$hash."' AND hash_usado='0'") or die(mysql_error());
  3. $match  = mysql_num_rows($search);
  4. if($match > 0){
  5.     $today = date("Y-m-d H:i:s");
  6.     $valida = mysql_fetch_array($search);
  7.     $email = $valida['email'];
  8. /// ...


Y un detalle tambien, que no te recomendaria lo de mostrar el error mysql_error() al usuario final porque pueda ser que muestres datos que no deberian podrias usar algo generico por ejemplo die('Error en confirmación').

Otro detalle pueda que pueda ser util, es que uses SALT, para generar tus hash, por ejemplo:

Cuando envies la URL
Código PHP:
Ver original
  1. $salt = sha1(uniqid());
  2. $token = sha1($email.$salt).'$'.$salt;
  3. echo 'http://dominio.com/verify/verify.php?t='.$token.'&e='.$email;
Y cuando lo recibas o verifiques

Código PHP:
Ver original
  1. $tokenRecibido = $_GET['t'];
  2. $emailRecibido = $_GET['e'];
  3. list($emailHashed, $saltEnviado) = explode('$', $tokenRecibido);
  4. if($emailHashed == sha1($emailRecibido.$saltEnviado)) {
  5.     //Ahora recien consultas a tu BD, ... WHERE SHA1(email) = '.$email.' ....
  6. } else {
  7.     // echo 'Ups!';
  8.               // redicciona a un 404 por ejemplo.
  9. }


Bueno espero que te pueda servir de algo, éxitos!.

Saludos,

PD: Tratemos de dejar la libreria mysql usemos PDO o sino Mysqli
__________________
.: Gildus :.
  #11 (permalink)  
Antiguo 08/07/2013, 12:49
Avatar de chalchis  
Fecha de Ingreso: julio-2003
Mensajes: 1.773
Antigüedad: 20 años, 9 meses
Puntos: 21
Respuesta: Usando Hash en URL

porque no simplemente les generas un modulo de profile de empresas de todas maneras tienen que entrar a tu aplicacion y en el server o por logica los ruteas a donde tienen que usbir cada empresa sus archivos

Cita:
Iniciado por gio_vela10 Ver Mensaje
Hola amigos,

Estoy desarrollando una aplicación web, en donde entre dos o más empresas se pueden mandar un link para subir archivos a la BD, supongamos que tenemos el index.php, donde la Empresa-1 puede mandar un correo a la Empresa-2 que contiene un link+hash, y con esto Empresa-2 puede subir archivos (además de titulo, comentario,etc. en la BD) de ahi mandarle el link+hash de descarga a Empresa1 de vuelta.

Espero haber explicado hasta aqui, la duda existencial que traigo es, yo estoy usando el hash guardado de cada Recipiente(empresa2,empresa..N) en la URL, la pregunta es, Qué tan seguro es hacer esto? me podrian insertar codigo malicioso por la URL?, porque alguna persona con malas intenciones y conocimientos informaticos estaria dandose cuenta del Hash que es un campo importante en la BD.

Esta aplicación estará solo en la intranet entre las empresas, pero aun asi me gustaria evitar estos problemas.

Muchas gracias a todos de antemano.

Saludos!
__________________
gerardo

Etiquetas: hash, seguridad, url
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




La zona horaria es GMT -6. Ahora son las 04:50.