domingo, 4 de agosto de 2013

PHP orientado a objetos - Herencia

Introducción

A grandes rasgos, el termino herencia significa que una o varias clases pueden derivar de una clase base o 'padre'. Una clase que hereda de otra se llama subclase. Esta hereda todas los atributos y métodos de la clase 'padre'. Y además añade sus propias características (atributos y métodos). Por eso se suele decir que una subclase extiende a la clase base.
El concepto de herencia es el mismo que en el mundo real: hijos heredan características de los padres. Por lo que una subclase tendrá a su disposición todas los atributos y métodos de la clase base. Pero esta última (clase base) no podrá utilizar ninguna de las características que extiendan las clases herederas.
Podríamos concluir la introducción con lo dicho en los anteriores párrafos respecto al total acceso a las características de la clase base por parte de las subclases. Pero estaríamos equivocados. Ya que no hemos tenido en cuenta el concepto de visibilidad explicado en el anterior tutorial. Ya que como explicamos, los lenguajes de programación orientados a objetos permiten indicar que atributos y métodos son internos de la clase base y cuáles son accesibles desde fuera de la clase. Y eso quiere decir que la clase heredera solo podrá tener acceso a los atributos y métodos que se hayan especificado con una visibilidad pública (public) o protegida (protected). Los miembros privados  no serán accesibles directamente. Por lo que nuevamente estamos ante el concepto de encapsulación ya que  la clase hija no puede acceder a todas la implementación interna de la clase padre. Solamente puede acceder a ciertos atributos y métodos que la clase padre permita.

miércoles, 31 de julio de 2013

PHP orientado a objetos - Introducción

Definición de clase

Una clase se podría definir como una plantilla de código para generar objetos.

En PHP una clase la definiremos con la palabra clave class seguida del nombre que queramos que tenga dicha clase. El nombre puede ser cualquier combinación de letras, guiones 'bajos' y números. Pero no puede empezar por un número. Ni el nombre puede ser igual al de alguna palabra reservada de PHP. Finalmente una par de llaves limitarán el contenido de la clase.

 class Producto{  
   //contenido de la clase  
 }  

Un objeto se compone  de datos que han sido estructurados de acuerdo con la plantilla definida en una clase. Por lo tanto un objeto es una instancia (representación) o un tipo definido por una clase.
Entonces vamos a ver como generar una instancia de una clase. Para ello utilizaremos el operador new de la siguiente forma:

 p1 = new Producto();  
 p2 = new Producto();  
 p3 = new Producto();  

Como vemos podemos generar tantas instancias (objetos) como queramos de un mismo tipo (clase).

lunes, 29 de julio de 2013

Patrón PHP POST/Redirect/GET

Todas las aplicaciones web tienen dos objetivos básicos:
- Poder obtener información enviada por el usuario desde un navegador.
- Mostrar resultados obtenidos por el procesado de la información anterior.
Esto se consigue mediante los métodos HTTP POST y GET.
En anteriores tutoriales  ya describimos las peculiaridades de utilizar cada método (POST/GET) para el traslado de información en la comunicación cliente-servidor. Y concluimos que para el envío de información importante desde el navegador al servidor era necesario utilizar el método POST. Debido a que los datos no viajaban en la URL, sino que lo hacían junto con las cabeceras.
Además también comentamos que los datos enviados mediante POST son almacenados en la memoria caché de los navegadores. Y aunque a priori este hecho no pueda parecer problemático, vamos a presentar un problema por el cual se puede ocurrir un doble envío de datos.

Para evitar tener que solicitar varias veces los mismos recursos (datos o imágenes) el navegador almacena en el disco duro dichos recursos. De esta forma, si alguien entra  en una página web, el navegador intentará cargar recursos que tenga almacenados. Ya que si no es la primera vez que se visita la página, el navegador habrá guardado recursos en caché.

lunes, 22 de julio de 2013

Seguridad PHP - Cross Site Request Forgery (CSRF)

Los ataques XSS se centraban en explotar la confianza de un usuario en un sitio web, ya que confiaba en la seguridad del servidor para que los atacantes no pudieran apoderarse de información de los usuarios, mediante la inserción de código 'malicioso'.
Pues existen otro tipo de ataques cuya idea es parecida. Este tipo de ataques ocurren cuando un sitio web permite que un usuario autenticado realice acciones sin verificar si realmente es él quien las está realizando. El ataque CSRF puede hacer que el navegador de la víctima envíe una petición HTTP 'fraudulenta'.  Y la aplicación (servidor) vulnerable piensa que es una petición de la víctima. Esto permitiría al atacante forzar al navegador de la víctima a hacer peticiones que la aplicación vulnerable pensaría que son peticiones legítimas.

sábado, 20 de julio de 2013

Seguridad PHP - Robo de sesiones

Introducción

Antes de nada conviene recordar el funcionamiento de las sesiones y las cookies de sesión explicados en anteriores tutoriales.
PHP tiene soporte nativo para trabajar con sesiones. Cada sesión viene identificada  un id aleatorio (32 caracters hexadecimales), que se crea la inicializar dicha sesión con la función session_start(), y que se almacena en una variable llamada PHPSESSID. Este id es esencial ya que cuando creamos una sesión, se crea un array superglobal que almacenará la información de la sesión. Y éste se almacena en el servidor, en un archivo temporal cuyo nombre está formado por 'sess' + dicho ID de sesión (depende de la configuración de php.ini).
Ahora necesitamos que el cliente tenga una forma de hacer peticiones al servidor y que
este sepa que se está comunicando en un contexto de sesión determinado. O dicho de otra forma el servidor tiene que saber que las peticiones del cliente pertenecen a la sesión.

Esquema intercambio cliente-servidor de cookie de sesión

En una comunicación bidireccional hay dos posibilidades para la comunicación de identificador de sesión:

viernes, 19 de julio de 2013

Seguridad PHP - Cross Site Scripting (XSS)

Mientras que un ataque 'SQL injection' pretendía insertar código 'malicioso' en las consultas SQL de una base de datos, XSS pretende que la aplicación web ejecute código JavaScript o similar. Es una vulnerabilidad que aprovecha la falta de mecanismos de filtrado y validación en los campos de entrada. Permitiendo así el envío de scripts completos (como Visual Basic Scripts o JavaScripts) con secuencias de comandos maliciosos que podrían impactar directamente en el sitio web o en el equipo de un usuario. Este código malicioso intenta aprovecharse de la confianza de un usuario en un sitio web, para engañarlo en la realización de alguna acción o forzarlo a enviar algún tipo de información a otro sitio que no es de confianza.

Por lo tanto, la diferencia en la ideología del ataque es que con 'SQL injection' se pretende aprovecharse de la poca seguridad del servidor para obtener acceso o alterar recursos del mismo mediante inserción de código SQL en el mismo. Mientras que con XSS se pretende introducir código JavaScript con el  propósito de que dicho código  al ser ejecutado por un cliente confiado lleve a cabo una acción maliciosa. Por ejemplo, un atacante colocar un enlace en un foro que al ser pinchado revele la información de identificación del usuario y la envíe a una dirección.

jueves, 18 de julio de 2013

Seguridad PHP - SQL injection

Las aplicaciones web permiten que a través de datos introducidos por los usuarios se realicen consultas y operaciones sobre las bases de datos que integran.
Al intento de  insertar o inyectar código dentro del código SQL para alterar el funcionamiento normal y hacer que se ejecute el código 'malicioso' dentro del sistema se le llama 'inyección de sql' o 'sql injection' (en ingles).
La solución para no permitir la inyección de este código es el correcto tratamiento de los datos que llegan a la aplicación de manera externa. Ya que como hemos dicho anteriormente, nunca hay que fiarse de lo que va hará o no un usuario.

Ejemplos de ataques

A) Acceso de administrador

- La siguiente consulta podría ser una consulta real para averiguar la existencia del usuario introducido en el formulario:

 $usuario = $_POST['usuario'];  
 $pass = $_POST['password'];  
 SELECT * FROM usuarios WHERE usuario = '$usuario' AND password = '$pass';  

Supongamos que dichas variables provienen de los inputs usuario y password del formulario de login y que existe un usuario llamado admin. Que pasaría si el usuario introdujese la cadena admin como login y  'or '1'='1 en la contraseña. Pues que la consulta se evaluaría de la siguiente manera:

 SELECT * FROM usuarios WHERE usuario = 'admin' AND password = '' OR '1'='1';  

Pues sí, podríamos ganarnos el pase como admin!!!. Evidentemente pueden haber variantes en el ataque ya que a parte de que admin puede no existir, puede que en la consulta las variables no estén entre comillas.

Seguridad PHP - Validación y filtrado 2

FILTER_CALLBACK


Como habréis visto en el anterior tutorial la cantidad de filtros es bastante decente pero evidentemente no cubre todas las necesidades que puede tener un desarrollador a la hora de filtrara datos. Por lo tanto tenemos que recurrir a funciones creadas por nosotros o a un tipo de filtro especial con llamada a funciones.

El tipo de filtro FILTER_CALLBACK nos permite hacer lo que nos indica su nombre. Llamar a una función nuestra para utilizarla como filtro o como función de filtrado. Y la única opción que permite es el nombre de la función que queremos aplicar.

Vamos a ver un sencillo ejemplo:

 function convertirEspacio($cadena) {  
      return str_replace(" ", "_", $cadena);  
 }  
 $string = "Esto es un ejemplo";  
 echo filter_var($string, FILTER_CALLBACK, array("options"=>"convertirEspacio"));  

Seguridad PHP - Validación y filtrado 1

La primera regla cuando tratamos con datos, ya sean provenientes de peticiones POST o GET, es que nunca nos podemos fiar de lo que pueda o no haber enviado el usuario. Por lo tanto debemos que validar cualquier dato ya que solo podemos permitir la entrada esperada. Y por supuesto no confiar únicamente en la posible validación en el lado cliente del sistema.

PHP nos presenta un conjunto de funciones que nos permitirán la validación y saneamiento de datos de una forma sencilla. La funcion filter_var (PHP >=5.2) nos permite filtrar una variable según el filtro especificado.

La sintaxis de la función es simple:

 mixed filter_var ( mixed $AFiltrar , int $tipo_filtro , mixed $opciones_filtro [opcional] );  

La salida será los datos filtrados o false en caso de fallo. Importante es el último parámetro  en el que podemos añadir opciones, en formato array asociativo o banderas. Existen diferentes formas de especificar tanto opciones como banderas:

Seguridad PHP - register_globals

El primer paso antes de validar cualquier datos de entrada, es comprobar que la directiva register_globals este desactivada. Desde PHP 5.3 fue declarada obsoleta y a partir de la versión 5.4 fue eliminada. Pero hay que tener cuidado si se usa una versión de PHP anterior. Por lo que  podemos usar la función phpinfo() para que nos diga si esta a activada o no.

El tener activa esta directiva ocasiona problemas graves de seguridad. Cuando register_globals está definida a “On” dentro del php.ini, se permitiría que un usuario cualquiera pudiera inicializar una variable remotamente. Y esto es un peligro en combinación con  de la naturaleza de PHP que no obliga a inicializar las variables.