Consejos de seguridad en el desarrollo de aplicaciones web

La seguridad es un aspecto muy importante al que hay que prestar atención cuando se desarrolla. Es importante tenerla en cuenta desde el mismo comienzo del desarrollo, no dejando la seguridad como algo secundario a realizar en momentos posteriores. Es por esto que vamos a dejar algunos consejos de como mejorar la seguridad durante el desarrollo de nuestras aplicaciones.

No confies en los usuarios

Esta es una de las reglas más importantes. Considera todas los datos que tus usuarios envíen como maliciosos.

$id = intval($_GET['id']);
mysql_query("SELECT username, email, password FROM users WHERE id = $id");

Con una sola linea podemos evitarnos una inyección SQL, por ejemplo.

Validación de datos en el servidor

Es importante realizar la validación de los datos en el servidor. Aunque realicemos también validación en cliente, mediante JavaScript por ejemplo, no hay que olvidarse que es relativamente fácil saltarse esta. Validando los datos en el servidor desde el principio nos evitamos bastantes problemas.

Presta atención a los archivos subidos

Si permites que tus usuarios suban archivos al servidor comprueba estos adecuadamente. Si son imágenes comprueba su tamaño, su tipo MIME, etc, con la función getimagesize. En caso de que sean otro tipo de archivos puedes usar fileinfo (disponible desde la versión 5.3.0) para obtener información de los archivos. Por ejemplo:

Asegura tus formularios contra los bots

Usa algún tipo de captcha para asegurar tus formularios contra bots de spammers. Hay distintas técnicas, puedes implementar uno propio, hacer uso de algún servicio externo o usar una librería de terceros.

Permisos mínimos para el usuario de la base de datos

Da los mínimos permisos al usuario de la base de datos. Si la aplicación solo va a realizar consultas SELECT, INSERT y UPDATE que el usuario de la base de datos solo pueda realizar SELECT, INSERT y UPDATE. No es nada complicado y te puede evitar algún que otro quebradero de cabeza.

Estos consejos son una “traducción” muy libre de estos otros:

http://www.osmialowski.me/blog/web-development-security-tips/

Artículos relacionados:

Comparte esta entrada:
Delicious Digg Google Technorati Menéame Fresqui Reddit Facebook Twitter Yahoo! Buzz MySpace Email BarraPunto

Cheat sheets para todos los gustos

Navegando por estos mundos de Internet he encontrado una colección de cheat sheets muy interesante. Podemos verlas todas en el siguiente enlace: Cheat Sheets.

Me han parecido muy interesantes las siguientes:

Por supuesto hay muchas más que pueden ser de mucha utilidad mientras se desarrolla.

Artículos relacionados:

Comparte esta entrada:
Delicious Digg Google Technorati Menéame Fresqui Reddit Facebook Twitter Yahoo! Buzz MySpace Email BarraPunto

Generando CSS mediante PHP

Si algo se hecha de menos en CSS es el no poder hacer uso de variables o de cierta lógica. Hay que tener en cuenta que CSS es un lengauje meramente estilístico, sirve para describir los estilos y la presentación de los elementos de la página.

Si alguna vez necesitamos incluir lógica en los CSS, por ejemplo para cambiar la paleta de colores en función de la estación del año, podemos usar PHP para esto. Lo que vamos a tener ahora es un archivo PHP en lugar del CSS, por ejemplo style.php. En este archivo lo primero que tendremos será:

header("Content-type: text/css; charset: UTF-8");

De esta forma le decimos al navegador que el contenido será del tipo CSS. Veamos un ejemplo donde el color de fondo y el color del texto se seleccionará de forma aleatoria. Primero el código de nuestra página:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"  dir="ltr" lang="es-ES">
<head>
<link rel="stylesheet" type="text/css" href="style.php"/>
</head>
<body>
<div id="bloque">Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Aliquam at facilisis odio. Integer sollicitudin facilisis tortor, id
ullamcorper dolor dignissim vel. Curabitur tristique pellentesque iaculis.
Vivamus molestie condimentum hendrerit. In hac habitasse platea dictumst.</div>
</body>
</html>

Y ahora el del script PHP que genera la CSS:

<?php

header("Content-type: text/css; charset: UTF-8");

$colores = array(
  array('bg' => '#000', 'fg' => '#fff'),
  array('bg' => '#00f', 'fg' => '#fff'),
  array('bg' => '#fff', 'fg' => '#f00')
);

$color = $colores[rand(0,2)];
?>

#bloque {
color: <?php echo $color['fg'];?>;
background-color: <?php echo $color['bg'];?>;
}

Se puede ver como se elige una u otra paleta de forma aleatoria en este enlace.

Artículos relacionados:

Comparte esta entrada:
Delicious Digg Google Technorati Menéame Fresqui Reddit Facebook Twitter Yahoo! Buzz MySpace Email BarraPunto

Generando thumbnails con PHP

Ya hemos visto en este blog como usar algunas de las funciones de la librería GD. Hoy le va a tocar el turno a la función imagecopyresampled, que nos va a permitir escalar una imagen. El código para generar el thumbnail mediante esta función es el siguiente:

<?php
define('ANCHO', 100);
$image_path = $_GET['i'];

#Cargamos la imagen original
$original = imagecreatefromjpeg($image_path);

#obtenemos el ancho y el alto
$original_x = imagesx($original);
$original_y = imagesy($original);

#calculamos el nuevo alto de la imagen, para que guarde la relación
#de aspecto
$alto_destino = round($original_y * ANCHO / $original_x, 0);

#creamos la imagen del thumbnail
$destino = imagecreatetruecolor(ANCHO, $alto_destino);

#copiamos la imagen original y la escalamos
imagecopyresampled($destino, $original, 0, 0, 0, 0, ANCHO, $alto_destino, $original_x, $original_y);

#mostramos la imagen del thumbnail
header('Content-Type: image/jpeg');
imagejpeg($destino);

#destruimos las imagenes
imagedestroy($destino);
imagedestroy($original);

Podríamos modificar este script para que guardara los thumbnails en un directorio, y si ya existe no haría falta volver a generarlo, pero eso lo dejamos mejor como pequeña práctica.

Artículos relacionados:

Comparte esta entrada:
Delicious Digg Google Technorati Menéame Fresqui Reddit Facebook Twitter Yahoo! Buzz MySpace Email BarraPunto

Tutorial de ADOdb: Parte II

En el anterior tutorial vimos como conectarnos a una base de datos. Hoy veremos como realizar consultas a la base de datos. Para ello vamos a ver un ejemplo donde nos conectaremos a una base de datos, MySQL en nuestro caso, y mediante el método Execute realizaremos una consulta a la base de datos (el ejemplo es muy parecido al de la anterior parte).

<?php

include('adodb.inc.php');

$conexion = NewADOConnection('mysqli');
$conexion->Connect('localhost', 'user', 'password', 'db');

$recordSet = $conexion->Execute('SELECT user_id, user_name FROM users');

if($recordSet != false)
{
 while(!$recordSet->EOF)
 {
  echo $recordSet->fields[0].':'.$recordSet->fields[1].'<br>';
  $recordSet->MoveNext();
 }
}

?>

Lo que hacemos es conectarnos a la base de datos, como vimos en la primera parte, y después ejecutamos una consulta con el método Execute. Este método nos devuelve una instancia de la clase ADORecordSet o false si ha ocurrido algún error. Esta clase nos provee de una serie de métodos y propiedades para manejar los datos devueltos por la consulta.

Una vez hecha la consulta comprobamos si se ha ejecutado correctamente la consulta. Acto seguido realizamos un bucle while siempre que no se haya llegado al final del recordset. Para ello comprobamos la propiedad EOF que nos indica si hemos llegado o no al final.

Luego imprimimos los datos. Para acceder a los datos de cada registro hacemos uso de la propiedad fields. Esta propiedad es un array que contiene cada uno de los campos de nuestro registro. Una vez que ya hemos hecho lo que queríamos, en este caso simplemente mostrar los datos, nos desplazamos al siguiente registro con el método MoveNext de la clase ADORecordSet.

Pero también podemos realizar otro tipo de consultas, por ejemplo de inserción o de modificación de registros. Para ello hacemos uso también del método Execute de la clase ADOConnection. Veamos un ejemplo:

<?php

include('adodb.inc.php');

$conexion = NewADOConnection('mysqli');
$conexion->Connect('localhost', 'user', 'password', 'db');

if($conexion->Execute('UPDATE user_name FROM users WHERE user_id = 1'))
{
 echo "Actualización realizada.";
}
else
{
 echo "Error al actualizar";
}

?>

En este caso el método devuelve true si la consulta se realiza satisfactoriamente y false si ocurre algún error.

Paso de parámetros a las consultas

Una de las cosas que podemos hacer con el método Execute es añadirle parámetros a las consultas. Para ello tenemos que construir la consulta de una forma especial, para indicar donde están los parámetros, y pasarle al método Execute un array con el valor de dichos parámetros. Veamos como hacerlo:

$rs = $conexion->Execute('SELECT user_name FROM users WHERE user_id=?', array($user_id));

Se puede apreciar que en la consulta se ha usado el símbolo ? para indicar donde va el parámetro. Como segundo parámetro del método execute se le pasa un array con los valores, en este caso es uno solo, de los parámetros.

Se puede usar este método con más de un parámetro:

$rs = $conexion->Execute('SELECT user_name FROM users WHERE user_id=? AND user_login =?', array($user_id, $user_login));

Podemos ver también que las cadenas no deben ir entre comillas en los parámetros, pues las comillas se le añaden a posteriori.

Otros métodos de la clase ADORecordSet

Métodos que devuelven una sola fila
Método: Descripción:
FetchRow() Devuelve una fila como un array y se desplaza al siguiente registro implícitamente.  No es necesario llamar después al método MoveNext.
FetchObject($toupper=true) Devuelve una fila como un objeto, siendo cada miembro un campo del registro. Si $toupper es igual a true los nombres de los campos irán en mayúsucula. Se recomienda usar el método FetchNextObject.
FetchNextObject($toupper=true) Igual que FetchObject pero mueve el puntero de posición al siguiente registro.
FetchObj() Igual que FetchObject(false)
FetchNextObject() Igual que FetchNectObject(false)
Métodos que devuelven todas las filas
Método: Descripción:
GetArray([$numRows]) Devuelve un array bidimensional con las filas desde la posición 0 a la $numRows -1. Si no se define $numRows devuelve toda la fila.

La clase RecordSet tiene muchos más métodos que nos pueden ser útiles, pero de momento con esto es suficiente. Si se quiere ver el resto de métodos se puede ver la documentación de la clase.

Artículos relacionados:

Comparte esta entrada:
Delicious Digg Google Technorati Menéame Fresqui Reddit Facebook Twitter Yahoo! Buzz MySpace Email BarraPunto