martes, 27 de noviembre de 2007

Lista de permitidos vs Lista de prohibidos

Al momento de pensar en seguridad, validación y filtrado de datos, tenemos dos opciones: o decidimos que permitimos o que prohibimos.

Por un lado, se puede usar un filtro para evitar ataques XSS que se base en buscar una expresion regular buscando código javascript (ya sea etiquetas script o atributos onload, onclick, onmouseover...). Esto sería usar "blacklist" es decir, poner código que no se puede usar.

Por otro lado, se puede permitir etiquetas HTML del tipo b, i, u... y todas las otras etiquetas simplemente eliminarlas. Esto sería "whitelist", o sea, limitar al usuario en lo que sí puede hacer.

¿Cuál es preferible?

Al utlizar una "blacklist" uno tiene que pensar en todos los posibles "ataques" que pueda recibir. Esto es un riesgo, ya que si a nuestro atacante se le ocurre un método que a nosotros no se nos ocurrió, estaríamos en un grave problema. Pero, si en cambio, utilizamos un sistema de "whitelist", el usuario sólo podría acceder si cumple con nuestro patrón permitido, cuestión que sería mucho menos probable que pueda concretar un ataque.

La desventaja, por otro lado, de la whitelist, es que podemos filtrar o no permitir información que es, realmente, válida.

Entonces, con una blacklist tenemos mayor posibilidad de ser víctimas de ataques por parte de usuarios malintencionados, mientras que utilizando una whitelist podemos dejar a usuarios correctos sin la posibilidad de ingresar datos.

Personalmente, la segunda opción me parece la mejor, ya que sus consecuencias son menos severas.

jueves, 22 de noviembre de 2007

Mezclar array con objetos

La extensión SPL nos permite tener objetos que actuan como array. Una forma de hacerlo es usar la clase predefinida ArrayObject. Otra forma es implementar una interfase ArrayAccess para poder acceder a nuestros datos como si fueran un array. Un ejemplo de esto

class MyArray implements ArrayAccess {
private $data;

public function __construct($array = array())
{
$this->data = $array;
}

public function offsetGet($key)
{
return $this->data[$key];
}

public function offsetSet($key, $value)
{
return $this->data[$key] = $value;
}
public function offsetExists($key)
{
return isset($this->data[$key]);
}
public function offsetUnset($key)
{
unset($this->data[$key]);
}

public function avg()
{
if (count($this->data) > 0)
{
return array_sum($this->data) / count($this->data);
}
}
}

$array = new MyArray(array(1, 2, 3, 4));
echo (int)isset($array[0]);
echo $array[0];

unset($array[1]);
echo (int)isset($array[1]); //throw an ugly notice
echo $array[1];

$array[1] = 4;
echo (int)isset($array[1]);
echo $array[1];

echo $array->avg();

martes, 13 de noviembre de 2007

Saber si se envió un parámetro con valor por defecto

Una función puede tener argumentos opcionales. Ellos se determinan dándole un valor por defecto al definirla. Por ejemplo

function prueba($clave, $valor = null)

pero cómo podemos diferenciar si se llama a esa función con un sólo parámetro, o si se usan dos y el segundo es igual al valor predeterminado?
La solución es rebuscada, pero no difícil... Simplemente tenemos que buscar cuántos argumentos se pasaron a la función al llamarla


function prueba($clave, $valor = null)
{
if (func_num_args() > 1) {
echo '$valor se envió';
}
}
prueba('1', null);
prueba('1');

jueves, 8 de noviembre de 2007

Nombrar fechas (no en inglés)

Es muy común el problema de querer poner "8 de noviembre de 2007" y tener "8 de november de 2007"... En general se utiliza un switch para traducir el nombre del mes, pero hay una forma mucho más simple de hacerlo. PHP trae la posibilidad de configurar la localización, y de allí elegir configuración "regional" como idioma, moneda, números.

Para ello, primero debemos fijar el ámbito con setlocale y después podemos utilizar el formato de fecha con strftime

Ejemplo

lunes, 5 de noviembre de 2007

Juego de Estados

Juego:
Tomar el nombre de dos estados de Estados Unidos, mezclarlos y luego reordenar las letras para formar el nombre de otros dos estados de Estados Unidos.

Mi solución

¿Alguna sugerencia?