Evitar SQL-injection en PHP

Los ataques SQL-Injection son unos de los más habituales en el mundo web. Aquí vamos a ver una serie de consejos para evitar estos agujeros en la seguridad:

Lo primero es seguir una serie de consejos a nivel de administración, como limitar los permisos del usuario a nivel de base de datos. Por ejemplo, en la mayoría de aplicaciones web lo habitual es que no tenga que utilizarse DROP, por lo que por seguridad sería mejor no permitir ya al usuario hacerlo. También sería interesante no dar información extra al atacante evitando sacar en pantalla los errores de la base de datos. En ese caso lo ideal es capturar el error haciendo uso de exception. Tampoco hay que confiarlo todo a las validaciones por javascript, porque el atacante puede saltárselas desactivándolo desde el navegador, por lo que mejor hacer las validaciones del lado del servidor. Y finalmente escapar las comillas con msqli_real_scape_string (en caso de que usemos MySQL), pg_scape_string (en caso de PostgreSQL) o addslashes (por si utilizamos otro SGBD). También podemos utilizar htmlentities para convertir los textos en entidades html, como un plus a la seguridad. Abajo un simple ejemplo:


<?php

try{
  $query = sprintf("SELECT * FROM users WHERE id=%d", mysqli_real_escape_string($id));
  $query = htmlentities($query);
  mysqli_query($query);
}catch(Exception $e){
    echo('Lo sentimos, ha habido un error en la conexión');
}
?>

Como medida extra se podrían utilizar expresiones regulares para evitar la inserción de ciertas palabras (SELECT, DROP, UNION…), si bien puede resultar poco práctico, sobre todo si tu software está destinado al mercado británico.

Pero si todo esto te parece lioso, hay una alternativa: la clase PDO. Dicha clase nos facilitará mucho la vida a la hora de trabajar con bases de datos, ya que nos permite abstraernos del SGDB que estemos utilizando. Si por ejemplo, en una página donde no utilices PDO o algo similar sino el mysql_connect simple, decides migrar tu web de MySQL a PostgreSQL tendrías que cambiar todos los métodos del conector de MySQL por los métodos de PostgreSQL. Con PDO bastaría con que cambiaras una sola línea de código, concretamente la de la creación del objeto PDO, y el resto de la aplicación seguiría funcionando. PDO además te permitirá usar consultas parametrizadas (como los Prepared Statements de java) o realizar transacciones. En fin, en el enlace de arriba tenéis todo el manual de PDO para estudiarlo si queréis. Ahora vamos con un simple ejemplo de Prepared Statement, para que veáis lo sencillo que es (dando por sentado para el ejemplo que ya hemos creado el objeto PDO, tal cual está explicado en el manual del enlace).


<?php
  $prepared_statement = $pdo->prepare("SELECT name FROM usuarios WHERE id = :id");/*preparamos la consulta*/
  $prepared_statement->bindParam(':id', $_GET['id'], PDO::PARAM_INT); /*Le pasamos el parámetro, asociado al parámetro de la consulta y definiendo su tipo (si no, por defecto lo trata como string)*/
  $prepared_statement->execute(); /*ejecutamos*/
  $prepared_statement = $statement->fetch(); /*recogemos los resultados, como un array. Se pueden utilizar parámetros para especificar otro tipo de respuesta, como por ejemplo PDO::FETCH_ASSOC para obtener un array asociativo*/
?>

Y con estos breves consejos lograrás que tu página sea más segura. El consejo: utiliza PDO, por ahorrarte comeduras de cabeza, por seguridad y por portabilidad de tu código.

Evitar ataques XSS con PHP Input Filter

Hoy una lección de seguridad en programación web: Evitar que a vuestra página le hagan un ataque por XSS (Cross Site Scripting). Si no sabéis lo que es el Cross Site Scripting… os lo explica mejor la wikipedia y así me centro en el tema (una vez le hice un ataque de estos a la página de un grupúsculo neonazi que redirigía a un vídeo del desfile del orgullo gay en Youtube)

Bueno, hay frameworks como Symphony o CakePHP que ya se encargar de implementar este tipo de seguridad, al igual que también lo hacen ciertos gestores de contenidos. Pero si se da el caso de que no estás usando ninguno, estás haciendo PHP «a pelo», lo mejor será que recurramos a la clase PHP Input Filter. Dicha clase permite filtrar código malicioso ingresado en los formularios para prevenir ataques XSS de manera sencilla, pero tiene la cualidad de no limpiar determinadas etiquetas o atributos si queremos.

Para utilizar esta clase, la descargaremos desde el enlace anterior e incluiremos class.inputfilter.php al inicio de nuestro códgi. Luego crearemos una instancia de la clase InputFilter, entonces podremos filtrar los datos con el método process:

    require_once("class.inputfilter.php");
    $filter = new InputFilter();
    $variable = $filter->process($_POST['variable']);

Esto nos permitiría limpiar de etiquetas la variable enviada por $_POST llamada variable. ¿Y si queremos limpiar todos los campos enviados por el método post? Pues basta con pasarle todo el array:

$_POST = $filter->process($_POST);

Y con eso tendríamos el array $_POST limpio de etiquetas y securizado.

Pero ¿y si queremos permitir ciertas etiquetas? Imaginemos que desde un input text metemos texto formateado, y nos interesa que sí puedan subir saltos de línea, texto en negrita o cursiva. Pues muy sencillo también, ya que basta con pasar en la creación del objeto InputFilter un array con las etiquetas que queremos conservar como parámetro:

    $filter = new InputFilter(array('em', 'i', 'br', 'b', 'strong'));
    $_POST = $filter->process($_POST);

Y esto se puede llevar más allá, porque también podemos decir que se permitan ciertos atributos de ciertas etiquetas. Por ejemplo, imaginemos que queremos permitir que inserten enlaces junto a su href y a su id, pero ningún atributo más:

    $filter = new InputFilter(array('a'), array('href', 'id'));
    $enlace = $filter->process($_POST['enlace']);

Tras el array de etiquetas pasamos otro array de atributos, simplemente.

Con estos sencillos consejos lograrás que tus formularios sean más seguros en PHP.

Cinco webs sobre seguridad que no debes dejar de mirar

Hoy toca lista, en este caso de páginas web sobre seguridad y asistencia técnica informática en castellano. Por no perder la costumbre de este sitio, la lista será de cinco sitios web.

seguridad informática

Dicho listado está formado por las cinco que más suelo seguir para mantenerme informado del tema, ya sea a través de RSS o de Twitter. Últimamente no tengo tanto tiempo para leer como cuando estaba desempleado, pero sigo siguiendo los artículos que más me interesan en la medida de lo posible.

  • El lado del Mal: El blog de Chema Alonso es sin duda mi favorito en este tema. Mayormente por el humor con el que suele tocar los temas, haciendo así más amena la experiencia de lectura. Pero que no te engañe, el que sea más fácil de leer que otros blogs técnicos no hace que su contenido sea menos útil. Tendrás desde artículos sobre auditoria de redes a otros sobre seguridad en Windows o Apple, en una amplia gama de temas.
  • Daboweb: Veterano site con múltiples actualizaciones mensuales recopilando noticias sobre seguridad y redes. Sobre todo es muy interesante su sección de manuales y tutoriales y sus recomendaciones de software para mantenimiento.
  • INTECO: El Instituto Nacional de Tecnologías de Comunicaciones pone a tu disposición en su web múltiple información sobre seguridad, control de calidad… Además de un área de formación donde podrás realizar diversos cursos de manera gratuita encontrarás información actualizada sobre malware y vulnerabilidades.
  • Sophos Iberia: Hace poco que les he descubierto a través de Twitter, pero ya he ojeado algún artículo interesante en esta web. Merece al menos una ojeada a sus artículos, sobre todo porque ofrecen entradas para todo tipo de usuarios, desde profesionales hasta usuarios medios.
  • Segu-Info: Interesante página web argentina sobre seguridad. Incluye listas de enlaces, blog, foro, formación… todo tipo de cuestiones que se te puedan ocurrir sobre seguridad informática (y en caso de duda siempre puedes recurrir al foro).

En algunos casos ciertos artículos pueden resultar excesivamente técnicos para el usuario medio, pero en todas ellas encontraréis múltiple información muy útil para mantener vuestro equipo y vuestra red protegidos.

Redes Zombi

Uno de los aspectos más interesantes de la seguridad en redes son las llamadas Redes Zombi, o botnets. Muchas veces nos encontramos con noticias en los medios sobre ataques DDoS o spam masivo, y detrás de esto suelen encontrarse las llamadas redes zombi.

Se trata de conjuntos de ordenadores infectados por software malicioso con una funcionalidad de puerta trasera (backdoor). Esto permite que el atacante tome el control de las máquinas sin disponer de acceso físico a las mismas y sin que el usuario lo sepa, pudiendo utilizarlas para su uso personal (lo que se conoce como drone o bot).

El ciclo de vida de una red zombi comienza con la fase de diseño del software malicioso, que se desarrolla con la intención de provocar una infección masiva. Tras esto llega la fase más importante, la implantación: se infecta a un primer equipo y se deja que el software, de forma vírica, vaya extendiéndose, infectando a más equipos (generalmente a través del correo electrónico, o de malware camuflado como si fuera sofware legítimo). Estas redes se explotan hasta que se detectan y corrigen las vulnerabilidades que lo permiten. Entonces llega una fase de decadencia y finalmente la inactividad de la red.

¿Por qué se crean bots? Tienen muchas formas de explotación, ilegales aunque no siempre ilegítimas. Pueden utilizarse por ejemplo para realizar ataques DDoS (peticiones masivas a un servidor para provocar su caída, a veces con fines económicos aunque en la mayoría de los casos estos ataques se hacen más como medida de protesta contra empresas que realizan prácticas inmorales, como pueden ser Facebook, Amazon, Apple, Microsoft…), aunque su utilización más habitual es para otro tipo de actividades con fines económicos:

  • Spam: Se utilizan las redes para hacer publicidad masiva (buzoneo on-line) por medio del correo electrónico.
  • Fraudes: Puede utilizarse para manipular encuestas, para mejorar estadísticas de jugadores en juegos on-line, para clickar en anuncios y generar beneficios por publicidad…

Otra de sus utilidades es servir como red de proxys para buscar el anonimato en la navegación, dificultando la traza de los datos desde el emisor hasta el receptor. Permiten además disponer de una red de computación distribuida para actividades que requieren mucha potencia, como para intentar romper contraseñas por fuerza bruta.

La forma de explotar estas redes es muy variada. Puede ser realizada de forma personal por el creador de la red, puede alquilar sus servicios a terceros (manteniéndose él como administrador) o puede venderles el software para que ellos creen sus propias redes.

Los consejos para protegerse de este tipo de redes son los básicos consejos de seguridad de siempre:

  • Nunca, jamás, reveléis vuestras contraseñas a servicios dudosos (sí, seguid con esa mierda de «Qué superhéroe eres?» o «Qué tolay con espada de Juego de Tronos serías» en Facebook, que os va dar la risa).
  • El sistema operativo siempre actualizado (quita esa mierda de Vista/XP pirata y ponte un Linux, hombre, que es gratis y la actualización te dará un plus de seguridad)
  • El antivirus, actualizado también, nunca sobra.
  • Ojo con lo que descargas. Si es software libre bájalo desde la web del fabricante. Si estás crackeando algo privativo, intenta que sea de una fuente relativamente fiable.

Y pensad que aunque os molen los zombis, que os zombifiquen el ordenador no es nada bueno. Si queréis participar en un ataque DDoS o prestar algo de vuestro procesador para alguna actividad de red distribuida (legal o no), hacedlo pero sin perder el control sobre vuestro equipo.

Encriptar una columna en MS-SQL Server con clave simétrica

Siguiendo con la racha de entradas sobre SQL, vamos a ver cómo encriptar una columna de una tabla SQL-Server usando una clave simétrica.

Bueno, lo primero, tras haber seleccionado la base de datos que queremos usar, es crear una clave maestra si no existe ya, con un password seguro (largo, con mayúsculas, minúsculas, números y símbolos), luego crear un certificado y finalmente una clave simétrica eligiendo el algoritmo a usar (en este caso AES256, robusto y seguro):

IF NOT EXISTS 
    (SELECT * FROM sys.symmetric_keys WHERE symmetric_key_id = 101)
    CREATE MASTER KEY ENCRYPTION BY 
    PASSWORD = 'PoNGo@1#pa55w0rd!fuEr73@para½q@no$me()lo_tAngUen'
GO

CREATE CERTIFICATE NombreDelCertificado
   WITH SUBJECT = 'Certificado Para Ejemplo';
GO

CREATE SYMMETRIC KEY SSN_Clave_Simétrica_01
    WITH ALGORITHM = AES_256
    ENCRYPTION BY CERTIFICATE NombreDelCertificado;
GO

Ok, con esto ya tenemos nuestra clave creada, con su contraseña. Un dato, si sois usuarios de Windows XP o de Windows Server 2000 no podéis usar AES, esos sistemas operativos no lo soportan, tenéis que usar DES (menos robusto y seguro, pero es lo que hay por usar sistemas sin actualizar). Ahora para introducir datos cifrados tienes que hacer lo siguiente:

-- Primero abre la clave simétrica.
OPEN SYMMETRIC KEY SSN_Clave_Simétrica_01
   DECRYPTION BY CERTIFICATE NombreDelCertificado;

--Luego introduce los datos
UPDATE BDEjemplos.Ejemplo
SET ColumnaDatosEncriptados = EncryptByKey(Key_GUID('SSN_Clave_Simétrica_01'), 'Una cadena cualquiera');
GO

En este caso usé un UPDATE pero podría haberlo hecho dentro de un INSERT. En todo caso, la función EncryptByKey() que recibe el identificador de la clave como primer parámetro y el dato a encriptar (String, Real, Float…) como segundo, es la clave de la operación.

Y para acceder a los datos cifados la cosa tampoco se torna muy compleja, es má o menos lo mismo, primero abrir y luego usar una función para desencriptar en la SELECT.En el ejemplo sacaríamos en una columna los datos encriptados y al lado el mismo dato desencriptado.

OPEN SYMMETRIC KEY SSN_Clave_Simétrica_01
   DECRYPTION BY CERTIFICATE NombreDelCertificado;
GO

SELECT ColumnaDatosEncriptados 
    AS 'Dato Encriptado',
    CONVERT(nvarchar, DecryptByKey(ColumnaDatosEncriptados)) 
    AS 'Dato Desencriptado'
    FROM BDEjemplos.Ejemplo;
GO

Existe la posibilidad de hacer esto también con un autenticador para fortalecer la seguridad. Si os interesa podéis mirarlo en la web de ayuda de Microsoft o presionarme para que publique aquí como hacerlo.

Seguridad: Protege tu privacidad en sencillos pasos.

Es evidente que este mundo de internet no es todo lo seguro que debería, y que las leyes que pretenden «mejorarlo» no son más que excusas para hacerles el juego a determinados lobbies y multinacionales.

Nadie está libre de ser hackeado ni de sufrir un disgusto con sus datos en línea, pero aunque no se pueda conseguir una seguridad del 100% eso no quiere decir que no se puedan minimizar los riesgos, solo has de seguir estos consejos para disfrutar de las redes sociales y otros servicios de internet de forma segura:

  • Conéctate siempre en redes seguras. Intenta no utilizar redes públicas en la medida de lo posible, y si te estás enganchando sin permiso a la red del vecino asegúrate de que este no sea informático (tengo colegas que se han divertido mucho a causa de un vecino listillo que les estaba auditando la red).
  • En tu casa fortifica siempre tu red, y vigila que no haya intrusos en la misma. Es importante que nuestra red doméstica esté bien monitorizada, sobre todo con el advenimiento del IOT.
  • Mantén tu sistema operativo limpio de virus y malware. No hace falta que te gastes una pasta pero tampoco vayas por ahí sin antivirus. Recuerdo la frase de una «genia» de la informática que me decía «Los antivirus son una mierda, antes en el trabajo no tenía y funcionaba todo, ahora cada dos por tres me está dando avisos» (olé!!!! igual los datos de tu empresa ya los tienen a la venta hasta en un rastro de Taiwan, por guay).
  • Ten un sistema operativo seguro y siempre actualizado. Ya seas usuario de Android, Linux, Windows, Apple… da igual, las actualizaciones de seguridad siempre instaladas para minimizar riesgos. Ojo con los dispositivos IOT, que suelen ser vulnerables al tener pocas posibilidades de actualización.
  • Los pagos con tarjeta, por dios, siempre en páginas seguras. Si la página tiene el https tachado, publicidad de sitios porno y los alerts de windows salen en chino o en cirílico… pues mejor no pagues ahí. Ojo a las que te pidan tu contraseña de Paypal sin redirigirte antes a su plataforma. Puedes mirar esta guía para compras en línea.
  • Cuidado con lo que instalas. Bájate las cosas siempre de sitios de confianza, mejor de la web del fabricante que de páginas de terceros. En caso de apps para móviles mira siempre que tengan sentido los permisos que te solicitan.
  • Si transportas datos en un dispositivo de almacenamiento externo, tipo pendrive o disco duro, lo mejor es cifrarlo.

Esto son consejos generales, ahora me permito unos para redes sociales y foros:

El más importante para mi: Si no quieres que algo no sea público, no lo subas. Esto es así, todo lo que alojes en cualquier servicio es susceptible de acabar llegando a malas manos. Así que si hay algo que quieras mantener como privado, lo mejor es no publicarlo por muchas medidas de seguridad que pretendas ponerle. Recuerda esta máxima: la red no olvida, las cosas que subes no «se pierden en los mares de internet» sino que permanecen durante años almacenadas en servidores que no están bajo tu control. Añado además una serie de consejos:

  1. Soy partidario de separar tu actividad social en varias cuentas, no tanto por «ocultarse tras un pseudónimo» sino por mantener un poco separadas distintas esferas de tu vida. Además, ese pseudómino no te hace tan anónimo como crees, así que no digas nada desde esa cuenta que no dirías desde una que tuviese puestos públicamente tu nombre, apellidos, DNI y dirección.
  2. Para el curriculum utiliza un e-mail que sólo uses recibir información laboral, no mezcles ese correo con otras cuentas para intentar minimizar el spam.
  3. Ten una cuenta de correo «basura» para registrarte en redes sociales, foros o para usar en concursos on-line y otras chorradas que creas que pueden derivar en exceso de spam. Si tienes dudas del servicio pero quieres probarlo y necesitas un correo, esta cuenta «burn-out» es lo ideal.
  4. No subas fotos donde aparezcan terceras personas sin su permiso. Tampoco subas fotos tuyas si no estás muy seguro de que quieres que sean públicas a largo plazo. Si llegar a la paranoia tampoco, aunque hayas leído que a una profesora de Minnesotta la despidieron por poner una foto bebiendo un vaso de vino es improbable que eso te ocurra (además, en España no sería siquiera legal que lo hicieran).
  5. No des demasiada información sobre tu lugar de trabajo, empresa, dirección postal… Si estás en una red social orientada al empleo, como LinkedIn es normal que pongas tu lugar de trabajo, pero en Instagram o Twitter no suele ser relevante y podrías estar revelando demasiada información sobre ti.
  6. No aceptes amistad de nadie si no sabes quién es.
  7. Cuidado con las aplicaciones tipo «juegos«, «tests» y demás que enlazan con tus cuentas en redes sociales. Las aplicaciones de terceros podrían tener acceso a datos que no quieres que conozcan, recuerda que el escándalo de Cambridge Analítica vino por esas aplicaciones.
  8. Ten cuidado con las cosas que piden geolocalización, he visto conseguir la dirección de una persona simplemente cruzando datos de Foursquare con los de Facebook.
  9. Controla qué cosas están como públicas y cuales como privadas, aunque recordando la máxima que aunque estén como privadas no implica que estén totalmente seguras.
  10. Si tienes la opción de «resetar» tu cuenta (borrar los mensajes antiguos en masa), hazlo cada seis meses. Recuerda que lo escribes en la red queda en la red para siempre.
  11. Y recuerda, ten siempre una buena contraseña, una contraseña fuerte. Los servicios de gestores de contraseñas son muy cómodos para esto.

Y si no quieres seguir estos consejos pues haz como Richard M. Stallman, no tengas cuentas y no tendrás que preocuparte de casi nada (porque nada te libra de que otra persona cuelgue una foto tuya «comprometedora«, aunque también te contamos cómo actuar en ese caso.).