CAPITULO 12 FORMULARIOS
Mi intencion con lo detallado a continuacion es orientar , no copies , explora por ti mismo , los codigos podrian tener algun error y no son un aporte , falta parte de verificaciones que en este capitulo no se detallan , tan solo es un ejemplo .
A continuacion explicare el siguiente formulario y las medidas de seguridad que lleva.
Ejemplo formulario de login:
Código HTML:
Ver original<form action="validar.php?FDW=<? echo $_SESSION['TOKEN']; ?>" method="post">
<div id="login"><input type="text" value="k_username" name="k_username" required></div> <input type="hidden" value="" name="usuario" > <input type="text" value="Introduce tu comentario" id="comentario" name="comentario" required>
<input type="text" name="<? echo $_SESSION['FORMULARIO'][$_SESSION['TOKEN']]['USUARIO']; ?> " pattern="^[a-zA-Z0-9-_]{3,15}$" maxlength="15" size="15" required>
</p>
<input type="password" name="<? echo $_SESSION['FORMULARIO'][$_SESSION['TOKEN']]['PASSWORD']; ?>" pattern="(?=^.{10,30}$)((?=.*\d)(?=.*\W+))(?![.\n])(?=.*[A-Z])(?=.*[a-z]).*$" size="30" maxlength="30" required>
</p>
<input type="submit" value="Iniciar sesion" name="login" formenctype="application/x-www-form-urlencoded" >
Codigo fuente:
Código HTML:
Ver original<form action="validar.php?FDW=8ce3eaa2695cb5d2e7edab515dd9e8b7cd7d4278cf2681cb16b6443d105ba361/1378930760" method="post">
<div id="login"><input type="text" value="k_username" name="k_username" required></div> <input type="hidden" value="" name="usuario" required> <input type="text" value="Introduce tu comentario" id="comentario" name="comentario" required>
<input type="text" name="165414168" pattern="^[a-zA-Z0-9-_]{3,20}$" maxlength="20" size="20" required></p>
<input type="password" name="847424868" pattern="(?=^.{10,20}$)((?=.*\d)(?=.*\W+))(?![.\n])(?=.*[A-Z])(?=.*[a-z]).*$" size="20" maxlength="20" required></p>
<input type="submit" value="Iniciar sesion" name="login" formenctype="application/x-www-form-urlencoded" >
Se puede apreciar varias cosas , entremos en detalle.
PROCEDENCIA
Vamos a usar lo visto en el capitulo 10 cross site request forgery.
Creamos una session con un hash y tambien enviamos en el action por get el token y despues lo comparamos.
Código PHP:
Ver original<? $_SESSION['TOKEN'] = hash('haval256,5',rand(),false); ?>
<form action="validar.php?FDW=<? echo $_SESSION['TOKEN']; ?>" method="post">
<input type="submit" value="Iniciar sesion" name="login" formenctype="application/x-www-form-urlencoded" >
lado del servidor:
Verificamos de donde vino el usuario , donde la url deberia de ser la url de la pagina del formulario en este caso 'http://localhost/login/' .
Código PHP:
Ver originalif( empty($_SERVER['HTTP_REFERER']) || $_SERVER['HTTP_REFERER'] === 'http://localhost/login/') {
// esta verificacion no es segura el referer se puede modificar
}
Verificamos el token y comprobamos si existen datos del formulario login
Código PHP:
Ver originalif(!empty($_SESSION['TOKEN']) and
!empty($_GET['FDW']) and
$_GET['FDW'] === $_SESSION['TOKEN']) {
if(isset($_POST['login']) and
$_POST['login'] === 'Iniciar sesion') {
// CONTINUAMOS
PROTEGIENDO LOS CAMPOS CLAVE
Creamos una session con los campos clave del formulario , en el formulario no mostraremos ni user ni passwor mas bien numeros aleatorios que identifican al campo y lo relacionan con la session.
Código PHP:
Ver original$_SESSION['FORMULARIO'][$_SESSION['TOKEN']] = array(
'USUARIO' => rand(1,9999999999), 'PASSWORD' => rand(1,9999999999)
);
$_SESSION['FORMULARIO'][$_SESSION['TOKEN']] el token es el identificador de la session del formulario , para despues acceder a los datos no servira con un simple $_POST['user'] debera de ser $_SESSION['FORMULARIO'][$_SESSION['TOKEN']][$_POST['user']]
Código PHP:
Ver original<form action="validar.php?FDW=<? echo $_SESSION['TOKEN']; ?>" method="post">
<p>Usuario:<br>
<input type="text" name="<? echo $_SESSION['FORMULARIO'][$_SESSION['TOKEN']]['USUARIO']; ?>" pattern="^[a-zA-Z0-9-_]{3,15}$" maxlength="15" size="15" required></p>
<p>Password:<br>
<input type="password" name="<? echo $_SESSION['FORMULARIO'][$_SESSION['TOKEN']]['PASSWORD']; ?>" pattern="(?=^.{10,30}$)((?=.*\d)(?=.*\W+))(?![.\n])(?=.*[A-Z])(?=.*[a-z]).*$" size="30" maxlength="30" required></p>
<input type="submit" value="Iniciar sesion" name="login" formenctype="application/x-www-form-urlencoded" >
</form>
lado del servidor:
Código PHP:
Ver original$user = $_SESSION['FORMULARIO'][$_GET['FDW']]['USUARIO'];
$password = $_SESSION['FORMULARIO'][$_GET['FDW']]['PASSWORD'];
if(!empty($_POST[$user]) and
!empty($_POST[$password])) {
// CONTINUAMOS
// para acceder a los datos $_POST[$user] $_POST[$password] , $user y $password identifican el campo del formulario
}
else
{
// existe algun campo vacio o no es valido como null , 0 , false etc.......
}
EXPRESIONES REGULARES
Solo se aceptaran usuarios con letras mayusculas/minusculas numeros y guion bajo _ y guion - minimo 3 caracteres y maximo 15 caracteres , este input es requerido.
pattern="^[a-zA-Z0-9-_]{3,15}$"
Código HTML:
Ver original<input type="text" name="<? echo $_SESSION['FORMULARIO'][$_SESSION['TOKEN']]['USUARIO']; ?>" pattern="^[a-zA-Z0-9-_]{3,15}$" maxlength="15" size="15" required>
</p>
El password debe de contener al menos una mayucula una minuscula un numero un caracter especial y minimo 10 caracteres maximo 30 caracteres , este input es requerido.
pattern="(?=^.{10,30}$)((?=.*\d)(?=.*\W+))(?![.\n])(?=.*[A-Z])(?=.*[a-z]).*$"
Código HTML:
Ver original<input type="password" name="<? echo $_SESSION['FORMULARIO'][$_SESSION['TOKEN']]['USUARIO']; ?>" pattern="(?=^.{10,30}$)((?=.*\d)(?=.*\W+))(?![.\n])(?=.*[A-Z])(?=.*[a-z]).*$" size="30" maxlength="30" required>
</p>
Esta medida de seguridad es altamente saltable ya que se puede modificar el codigo html y saltarse la verificacion, por ello debemos verificar en el lado del servidor.
lado del servidor:
Código PHP:
Ver originalif(!empty($_POST[$user])) {
if(strlen($_POST[$user]) >= 3 and
strlen($_POST[$user]) <= 15) {
if( preg_match('|^[a-zA-Z0-9-_]{3,15}$|', $_POST[$user], $coincidencias) !== 1 ) {
exit('usuario no valido'); }
}
else
{
exit('longitud no valida'); }
}
else
{
exit('debe de rellenar todos los datos'); }
if(!empty($_POST[$password])) {
if(strlen($_POST[$password]) >= 10 and
strlen($_POST[$password]) <= 30) {
if( preg_match('|(?=^.{10,30}$)((?=.*\d)(?=.*\W+))(?![.\n])(?=.*[A-Z])(?=.*[a-z]).*$|', $_POST[$password], $coincidencias) !== 1 ) {
exit('password no valido'); }
}
else
{
exit('longitud no valida'); }
}
else
{
exit('debe de rellenar todos los datos'); }
ANTIBOTS
Ocultaremos campos como se hablo en el capitulo 11 , añadiendo un campo escondido en un div oculto.
Código CSS:
Ver original<style>
input#comentario,#login { display:none; }
</style>
Código HTML:
Ver original<div id="login"><input type="text" value="k_username" name="k_username" required></div>
<input type="hidden" value="" name="usuario" >
<input type="text" value="Introduce tu comentario" id="comentario" name="comentario" required>
lado del servidor:
Código PHP:
Ver originalif(empty($_POST['usuario']) and
isset($_POST['comentario']) and
$_POST['comentario'] === 'Introduce tu comentario' and
!empty($_POST['k_username']) and
$_POST['k_username'] === 'k_username' ) {
// continuamos
}
else
{
// bot
}
Parte 2 A continuacion