Posts tagged ‘PHP’

Indent your HTML code with a Smarty plugin

XHTML code

If you are using Smarty as a template system in your PHP project you will be very pleased to use this tiny-but-very-useful outputfilter that I made.

Smarty as you can read in its documentation has some extension points where you can create plugins into to extend its functionality. One of them are outputfilters, that allow us to operate on a template’s output, after the template is loaded and executed, but before the output is displayed.

So you can modify your final HTML code with those extentions point without a any pain.

Debugging PHP with XDebug and Komodo IDE

When you develop a very important web app it is pretty sure you will need debugging it. The best way to do this is using XDebug so in this article I am going to explain how to setup and use XDebug with Komodo IDE or Edit, but you can use it for Netbeans or Eclipse as well.

The first step is install XDebug in your system (I assume that you have already installed a LAMP server in your system).

How to setup a LAMP server with less than 100 characters

One of the reasons cause I love the GNU/Linux for developing is its easy and quick setup.

So if you’re a LAMP-dev you can setup a LAMP server with less than 100 chars.
With the next command you will have a apache2+php5+mysql on Debian based systems with the bonus of phpmyadmin for administer your databases.

sudo apt-get install phpmyadmin lamp-server^

Dont forget the trailing ‘^’ char.

Quick post, quick solution. Isn’t it?

SQL Injection, PHP y Bases de Datos

SQL Injection, la temida dirían algunos y la verdad es que si no tienes cuidado al programar suelen ser verdaderos quebraderos de cabeza, que ciertamente despues de retomar código es un tanto dificil de depurar si no sabes lo que ha sucedido.
Aquí voy a relatar modos de tratar ataques SQL Injection, que harán nuestras apps más seguras y a nosotros estár más tranquilos.
Las SQL Injections son consultas sql que son generadas por scripts/programas que concatenan entradas del usuario con consultas a bases de datos, y ahí es donde está el problema ya que no toda la entrada que proporciona el usuario es segura.
Por ejemplo consideremos la siguiente instrucción:

SELECT * FROM users WHERE user = 'Pepito'

Si quieres en este momento recoger una fila de la base de datos con información del usuario insertada debes reemplazar “Pepito” con la cadena proporcionada por el usuario.
En PHP se vé tal que así:

SELECT * FROM users WHERE user = '$_GET[nombreUsuario]'

El problema es simple: si el usuario inserta una cadena formateada especialmente como el nombre de usuario el puede modificar tu consulta para ejecutar lo que el desee.

Por ejemplo si inserta esto:

';DROP TABLE users;--

Ahora la consulta se verá así:

SELECT * FROM users WHERE user = '';DROP TABLE users;--'

Hay varias formas con las que alguien puede atacar nuestra base de datos mediante sql injection. Las más rudimentarias son escapar los caracteres ‘, pero no siempre funcionan correctamente ya que hay otras formas de alterar la consulta. Echemos un vistazo a esto.

Hay una solucion muy simple a este problema. No concatenes texto proporcionado por el usuario en una consulta, vinculalo. La mayoría de las bases de datos soportan bindings, mysql es una de ellas, postgresql, oracle y la lista crece. La idea es simple: proporcionas un marcador en tu consulta que será reemplazado con la variable actual, por lo que no es posible ninguna modificación posible.

Nuestra anterior consulta se puede escribir tal que así:
Mysql (en php con la extensión mysqli)

SELECT * FROM users WHERE user = ?

Oracle

SELECT * FROM users WHERE user = :user

Ejemplo de la extensión mysqli PHP (para más información lee la función de mysqli_stmt bind_param

/* recoger los datos del usuario */
$nombreUsuario = $_GET['nombreUsuario'];
/* preparar la consulta */
$stmt = $mysqli->prepare('SELECT * FROM users WHERE user = ?');
/* vincular el valor */
$stmt->bind_param('s', $nombreUsuario);
/* ejecutar la declaración preparada */
$stmt->execute();

$stmt->bind_result($name, $surname);
/* recoger los datos de usuario*/
while ($stmt->fetch())
{
  //imprimir los datos del usuario
  echo $nombre, ' =>  ', $apellido , "\n";
}
/* cerrar la operación */
$stmt->close();

Ejemplo con la extensión PHP PDO (para más información lee la función prepare de PDO

/* recoger los datos del usuario */
$nombreUsuario = $_GET['nombreUsuario'];
/* preparar la consulta */
$sth = $dbh->prepare('SELECT * FROM users WHERE user = ?');
/* vincultar y ejecutar la consulta */
$sth->execute($userName);
$row = $sth->fetchAll();

Por lo tanto es muy facil para nosotros evitar la reescritura evitando que concatenar los datos proporcionados por el usuario con nuestra consulta, pero hay escenarios donde debes generar una consulta con los datos del usuario, no solo enviando una consulta. Por ejemplo, quieres mostrar diferentes tipos de libros basados en lo que inserta el usuario. El usuario puede elegir ver libros de ciencia ficción, literatura o libros de cocina.

Podrías estar tentado a escribir algo como esto:

SELECT * FROM $_GET[categoriaLibro]

┬┐Pero, que pasa si el usuario quiere modificar tu script e inserta ‘users’ como una categoría? En ese caso podrá ver el contenido de la tabla de usuarios. La solución para este problema es comprobar la categoría proporcionada por el usuario en vez de la cadena directamente.

En php deberías hacer algo como esto:

switch ($_GET['bookCategory'])
{
        case 'sf_books':
                $table = 'sf_books';
                break;
        case 'literature_books':
                $table = 'literature_books';
                break;
        default:
                $table = 'cooking_books';
}
$query = "SELECT * FROM $table";

Si escribes tu script de esta forma, cuando el usuario inserte ‘users’ como una categoría, el verá los libros de cocina, o puedes elegir mostrar un error, esa es tu elección.
Para resumir este post, quiero decir que deberías utilizar el binding de variables cuando quieras enviar datos a la base de datos que proporciona el usuario. Y si formas tus consultas según la entrada de usuario, simpre compara lo que inserta con algun valor predefinido y usa el valor por defecto.
Nunca concatenes entrada de usuario en tus consultas, sin excepciones

Configuración de VirtualHosts en Nginx (Nginx II)

Echa la compilación de nuestro nginx ahora voy a explicar mas o menos mi sistema para gestionar virtualhosts con nginx. Primero de todo, suelo meter los virtualhosts en /opt en el que crearemos el esqueleto para cada slice.

Configuramos nginx para virtualhosts utilizando ficheros separados para cada uno de ellos:

mkdir -p /usr/local/nginx/conf/{sites-available,sites-enabled}

Substituímos con lo siguiente en el fichero /usr/local/nginx/conf/nginx.conf, para que lea todos los ficheros en sites-enabled y de paso lo limpiamos:

user www-data;
worker_processes  1; #Número de workers configurable según necesidades

error_log  /var/log/nginx/error.log;
pid        /var/run/nginx.pid;

events {
    worker_connections  1024;
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    access_log  /var/log/nginx/access.log;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;
    tcp_nodelay        on;

    gzip  on;

    include /etc/nginx/sites-enabled/*;

}

LLegados a este punto ya tenemos nuestro nginx preparado para servir cualquiera de los distintos tipos de servidores que soporta (web, proxy web inverso, mail, balanceo de carga). Como aquí nos centraremos en configurar un servidor web con virtualhosts, sigo relatando las operaciones.

Page 2 of 3