Categories
PHP Quiz Seguridad

Autenticación de usuarios y sesiones en PHP

Continuando con la pequeña serie de posts que intentan mostrar algunas fallas comunes que hacemos los aficionados a PHP, e incluso los que se dedican profesionalmente a desarrollar aplicaciones con este lenguaje, esta vez tocaremos el tema de sesiones.

user.php, necesita de la clase ezSQL, puedes saber mas sobre esta clase en este artículo.

php:

<?php

class User {
        var $id;
        var $name;
        var $email;
       
        function Authenticate($user, $password) {
                global $db, $site_key;

                $user = $db->get_row (
                        'SELECT id, name, email, password
                                FROM users
                                WHERE username = \''
. $db->escape($user) . '\'');
               
                if ( $user && $user->password == md5( $site_key . $password ) ) {                     
                        $this->id = $user->id;
                        $this->name = $user->name;
                        $this->email = $user->email;
                        return true;
                }
                return false;
        }
}

?>

php:

// login.php
<?php

include dirname(__FILE__) . '/db.php'; # genera una instancia de la clase ezSQL
include dirname(__FILE__) . '/user.php';

/*
if ( ! empty( $_SESSION['user'] ) ) {
        header( 'Location: /admin' );
        exit();
}
*/

if ( ! empty( $_POST['user'] ) && ! empty( $_POST['password'] ) ) {     
        $user = new User();
        if ( $user->Authenticate( $_POST['user'], $_POST['password'] ) === true ) {
                $_SESSION['user'] = $user;
               
                header( 'Location: /admin' );
                exit();
        }
}

?>

¿Qué problema existe en el código mostrado? -no es un error de sintáxis 😀

Nota: si eres testigo de otros errores 🙂 y quieres compartir esa información, no dudes en contactarnos (describe el problema, una posible solucion, si ya lo publicaste en tu blog, envíanos el link para comentar el problema y citar tu post)

Categories
PHP Quiz

Redirecciones en PHP

Muchos alguna vez hemos utilizado el siguiente código para la redirección de páginas

php:

<?php

$return = '/';
if ( ! empty($_GET['return']) )
        $return = $_GET['return'];
elseif ( ! empty($_SERVER['HTTP_REFERER']) )
        $return = $_SERVER['HTTP_REFERER'];

header('Location: ' . $return);
exit();

?>

¿Cuál es el error que existe en el código mostrado?

Categories
PHP Quiz

Quiz sobre PHP – rarezas del lenguaje

Qué muestra la siguiente porción de código?

php:

<?php

$variable = 'demo';

if ( $variable > 0 )
        echo 'foo';

if ( ! $variable > 0 )
        echo 'bar';

echo 'baz';

?>

Categories
PHP Quiz Seguridad

Quiz sobre validación de datos en PHP

El código mostrado a continuación, es una versión reducida de una falla de seguridad presente en una aplicación algo conocida.

Indiquen la falla, lo que se puede hacer con ésta, una forma de explotarlo y la solución que plantean al mismo:

php:

// demo.php
<?php

include './db.php';

error_reporting(0);

$tb_url    = $_POST['url'];
$title     = $_POST['title'];
$excerpt   = $_POST['excerpt'];

if (empty($title) || empty($tb_url) || empty($excerpt)) {
        die ('Invalid values');
}

$titlehtmlspecialchars( strip_tags( $title ) );
$title = (strlen($title) > 150) ? substr($title, 0, 150) . '...' : $title;
$excerpt = strip_tags($excerpt);
$excerpt = (strlen($excerpt) > 200) ? substr($excerpt, 0, 200) . '...' : $excerpt;

$contents=@file_get_contents($tb_url);
if(!$contents) {       
        die('The provided URL does not seem to work.');
}

$query = "INSERT INTO tabla (url, title, excerpt) VALUES ('%s', '%s', '%s')";

$db->query
        (
                sprintf (
                        $query,
                        $db->escape($tb_url),
                        $db->escape($title),
                        $db->escape($excerpt)
                        )
        );

?>

php:

// show.php
<!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">
        <head>
                <title>Bug</title>
        </head>
        <body>

                <ul>
                <?php

                include './db.php';
                $items = $db->get_results('SELECT url, title, excerpt FROM tabla');

                foreach ($items as $tb) :
                        echo '<li><a href="'.$tb->url.'" title="'.$tb->excerpt.'">'.$tb->title.'</a></li>';               
                endforeach;

                ?>
                </ul>

        </body>
</html>

Para el acceso a datos se usa la clase ez_sql, el método escape en mi versión, contiene lo siguiente:

php:

function escape($string) {
        if (get_magic_quotes_gpc())
                $string = stripslashes($string);
        return mysql_real_escape_string( $string, $this->dbh );
}
Categories
.NET Quiz

Quiz: Números aleatorios en .NET

La siguiente porción de código será usado para determinar el ganador del sorteo del voucher para un exámen de certificación Microsoft

csharp:

using System;
using System.Collections.Generic;
using System.IO;

class Participante
{
    private string Nombre, Email;
    public Participante(string nombre, string email)
    {
        Nombre = nombre;
        Email = email;
    }
    public override string ToString()
    {
        return string.Format("Nombre: {0}\t\tEmail: {1}", Nombre, Email);
    }
}
class Program
{
    static void Main(string[] args)
    {
        StreamReader reader = null;
        try
        {
            reader = new StreamReader("sorteo.txt");
            List<Participante> participantes = new List<Participante>();
            string line;

            while ((line = reader.ReadLine()) != null)
            {
                participantes.Add(new Participante(line.Split(',')[0], line.Split(',')[1]));
                Console.WriteLine(participantes[participantes.Count - 1]);
            }
           
            int ganador = ObtenerGanador(participantes.Count);

            Console.WriteLine("\n\nEl ganador es: {0}", participantes[ganador]);
        }
        finally
        {
            if (reader != null)
                reader.Close();
        }
    }
    public static int ValorAleatorio()
    {
        int semilla = DateTime.Now.Millisecond;
        Random rnd = new Random(semilla);
       
        int maximo = rnd.Next(0, semilla) * semilla;
       
        return rnd.Next(0, maximo % int.MaxValue);
    }
    public static int ObtenerGanador(int numeroParticipantes)
    {
        int ganador = 0;
        for (int i = 0; i < numeroParticipantes; i++)
            ganador += ValorAleatorio();

        return ganador % numeroParticipantes;
    }
}

El archivo sorteo.txt, tiene la siguiente estructura:

code:

Nombre Apellidos,Email
Nombre Apellidos,Email
Nombre Apellidos,Email

Determinen si el código mostrado sirve o no para los propósitos antes mencionados, si observan algún comportamiento raro, comenten abajo indicando las correcciones del caso.

Pueden descargar el código en C# o VB, para compilarlo -como se habrán dado cuenta- necesitan el .NET Framework 2.0

Nota: El código se ejecutará en una máquina con procesador AMD Athlon 64 3200+ y 1GB RAM.