Está en la página 1de 36

THE ORIGINAL HACKER

SOFTWARE LIBRE, HACKING y PROGRAMACIN, EN UN PROYECTO DE

EUGENIA BAHIT

Buenos Aires, 3 de Diciembre de 2013

@eugeniabahit
GLAMP HACKER Y PROGRAMADORA EXTREMA
HACKER ESPECIALIZADA EN PROGRAMACIN EXTREMA E INGENIERA INVERSA DE CDIGO SOBRE GNU/LINUX, APACHE, MYSQL, PYTHON Y PHP. EUGENIABAHIT.COM DOCENTE E INSTRUCTORA DE TECNOLOGAS GLAMP CURSOS.EUGENIABAHIT.COM CURSOSDEPROGRAMACIONADISTANCIA .COM MIEMBRO DE FOUNDATION FOUNDATION
LA FREE SOFTWARE FSF.ORG, THE LINUX LINUXFOUNDATION.ORG E INTEGRANTE DEL EQUIPO DE DEBIAN HACKERS DEBIANHACKERS.NET.

NDICE DE LA EDICIN NRO2


INGENIERA INVERSA : DESARROLLAR SOFTWARE APLICANDO LA INGENIERA INVERSA : EL ARTE DE LA C I E N C I A ......................................3 PYTHON SCRIPTING : MANIPULAR ARCHIVOS DE C O N F I G U R A C I N M E D I A N T E C O N F I G P A R S E R ..........8 INGENIERA DE SOFTWARE: AGREGADO DE ARCHIVOS
CRON Y EJECUCIN PERIDICA DE PROCESOS EN LOS P A Q U E T E S . D E B ...............................18

CREADORA DE PYTHON-PRINTR, EUROPIO ENGINE, JACKTHESTRIPPER. VIM CONTRIBUTOR. FUNDADORA DE HACKERS N' DEVELOPERS MAGAZINE Y RESPONSABLE EDITORIAL HASTA OCTUBRE '13.

E U R O P I O E N G I N E L A B : C M O S E H I C I E R O N L O S ABM D E L A W E B T H E O R I G I N A L H A C K E R L I B R A R Y ?...21 SEGURIDAD INFORMTICA: CAPAS DE SEGURIDAD I N T E L I G E N T E S E N PHP S A N E A M I E N T O D E L A R R A Y S U P E R G L O B A L $_ POST.........................31

2013 Eugenia Bahit www.eugeniabahit.com Bajo Licencia Creative Commons BY-NC-SA

The Original Hacker www.originalhacker.org

DESARROLLAR SOFTWARE APLICANDO LA INGENIERA INVERSA: EL ARTE DE LA


CIENCIA
DESARROLLAR SOFTWARE
PUEDE CONVERTIRSE EN UN VERDADERO ARTE CIENTFICO SI SE ES CAPAZ DE COMBINAR PARALELAMENTE, LGICA Y PENSAMIENTO LATERAL. Y ESO, ES LO QUE LA INGENIERA INVERSA NOS PROPONE. EN ESTA EDICIN DE THE ORIGINAL HACKER, VEREMOS EN QU CONSISTE LA INGENIERA INVERSA DE SOFTWARE APLICADA DURANTE SU DESARROLLO.

i alguna vez te viste envuelto en una maraa de ideas y procedimientos al momento de desarrollar una determinada funcionalidad y terminaste enredndote tanto que decidiste dibujar! lo que necesitabas alcanzar y desde all"# fuiste sustituyendo tu dibujo! por c$digo hasta terminarlo# lo que hiciste# fue aplicar un procedimiento de ingenier"a inversa para resolver ese requerimiento que tanto te enredaba. & la ingenier"a inversa muchas veces se le suele tener miedo y esto sucede 'creo yo' por la inmensa cantidad de mitos alrededor de este maravilloso concepto pero por sobre todo 'y en definitiva'# por la gran ignorancia y desconocimiento sobre su e(istencia.

La ingeniera inversa plantea una forma lateral de alcanzar objetivos, partiendo del resultado -el qu- para obtener el modo de alcanzarlo -el cmoLa ingenier"a inversa es amplia. )s amplia como ciencia y como t*cnica pero tambi*n como concepto# ya que si bien posee un +nico significado# sus aplicaciones son tan variadas y dis"miles que es all" donde se produce la distorsi$n conceptual que tantos miedos genera.

&l proponer el inicio de los procesos partiendo del objeto final# es que com+nmente se la relaciona con una de sus aplicaciones ms frecuentes, -ngenier"a -nversa de .ardware, aquella que# partiendo de un componente f"sico /hardware0 cuyo

2013 Eugenia Bahit www.eugeniabahit.com Bajo Licencia Creative Commons BY-NC-SA

The Original Hacker www.originalhacker.org

c$digo es privativo /no libre# no abierto0# intenta obtener un software que permita reemplazar al controlador del fabricante. %in embargo# no es +nicamente en esta rea donde la ingenier"a inversa se aplica. La ingenier"a inversa tiene much"simas ms aplicaciones# entre ellas, -ngenier"a -nversa de c$digo , aquella que va siguiendo la pista! del c$digo fuente de una aplicaci$n ya sea tanto para entender la forma en la que *sta funciona como para detectar fehacientemente vulnerabilidades que no podr"an ser halladas mediante herramientas para pruebas de intrusi$n automatizadas /que tan de moda se han puesto en los +ltimos tiempos pero que sin embargo# no han sido capaces hasta el momento# de sustituir ni reemplazar la inteligencia humana01 -ngenier"a -nversa de %oftware , ya sea para descomposici$n de aplicaciones /generalmente# aplicada para desentraar un %oftware cerrado y privativo0 o para el caso contrario# la composici$n de %oftware# a la cual nos dedicaremos en este art"culo.

TDD: EL EJEMPLO PERFECTO DE INGENIERA INVERSA DE SOFTWARE APLICADA AL DESARROLLO


La t*cnica e(trema 233 (Test-Driven Development)# que en espaol se traduce como Desarrollo guiado por prue as# es un claro ejemplo de c$mo la -ngenier"a -nversa aplicada al desarrollo de %oftware logra l$gicas realmente simples de comprender y prcticamente un"vocas e inequ"vocas. 4uy frecuentemente# confundimos 5nit 2esting !nit "esting Las pruebas unitarias simplemente son funciones destinadas a evaluar una +nica acci$n del c$digo fuente. )s as" que si en nuestra aplicaci$n tenemos una funci$n destinada a eliminar etiquetas .24L de una cadena de te(to# podremos tener# en paralelo 8 m*todos por ejemplo# que pasen 8 cadenas de te(to diferentes a nuestra funci$n y comprueben que el valor de retorno sea efectivamente el esperado. Las pruebas unitarias como tales# no requieren de -ngenier"a -nversa y de hecho# hasta pueden ser generadas de forma automatizada# por lo que de forma aislada# no pueden considerarse como una t*cnica e(trema. %in ir ms lejos# las pruebas unitarias podr"an escribirse una vez que la aplicaci$n se encontrase ya desarrollada. )n principio# podemos decir que 5nit 2esting# 2est' 6irst 7rogramming y 233# son tres t*cnicas donde de menor a mayor! una es requerida por la otra. )s decir que 233 necesita de 2est'6irst 7rogramming y *ste# de 5nit 2esting. )s por ello# que comenzaremos defini*ndolos de menor a mayor!. "est-#irst $rogramming )sta es una t*cnica que consiste en escribir primero las pruebas unitarias y luego el c$digo de la aplicaci$n. /pruebas unitarias0 con 2est'3riven 3evelopment y 2est'6irst 7rogramming. )stos errores de concepto pueden generar que jams se logre entender con e(actitud# qu* es la -ngenier"a -nversa# c$mo se aplica y para qu* es necesario implementarla. 7or ello# me gustar"a tratar de e(plicar los tres conceptos con la esperanza de que por fin# queden claramente diferenciados entre s".

2013 Eugenia Bahit www.eugeniabahit.com Bajo Licencia Creative Commons BY-NC-SA

The Original Hacker www.originalhacker.org

)sta t*cnica ya es un poco ms compleja que el mero hecho de escribir pruebas unitarias pero sin embargo# no alcanza a ser una t*cnica de -ngenier"a -nversa# puesto que podr"a facilitarse tranquilamente# el diseo de lo que se quiere lograr /es decir# el c$mo!0 antes de contar e(actamente con el objeto /es decir# el qu*!0. "DD % "est-Driven Development )l desarrollo guiado por pruebas# es pura y e(clusivamente una t*cnica e(trema de -ngenier"a -nversa que plantea pensar primero en lo que se quiere lograr /es decir el qu*!0 y partiendo de

pseudo'prototipos /que a veces no son ms que el resultado hardcodeado de un ejemplo de lo que se desea lograr0 ir implementando el m"nimo c$digo necesario para que dicho pseudo'prototipo deje de serlo. 9 para escribir el m"nimo c$digo necesario# propone utilizar 2est'6irst 7rogramming c$mo t*cnica para la implementaci$n de las pruebas unitarias. &$or 'u( de)imos 'ue la t()ni)a de "DD es *ngenier+a *nversa pura, 7orque para que *sta est* bien implementada# se debe partir el desarrollo desde lo que se quiere lograr para alcanzar de a poco el c$mo lograrlo.

COMPRENDIENDOEL QU: COMENZAR POR EL RESULTADO


& lo largo de los aos he notado que lo que ms le cuesta entender a todas las personas es qu* es e(actamente a lo que nos referimos cuando hablamos de resultado!# es decir# qu* es e(actamente el qu*!. 9 de verdad# que de tan simple que me resulta# a veces creo que esa obviedad es la que lo hace tan dif"cil de entender como quizs tambi*n de e(plicar. El resultado es e-a)tamente lo 'ue esperas ver )uando ha.as terminado tu apli)a)i/n . la utili)es por primera ve01 7aso a paso# un ejemplo muy sencillo y de fcil comprensi$n sobre c$mo se implementar"a la -ngenier"a -nversa en el desarrollo de %oftware# podr"a ser el siguiente, :. Se identi2i)a lo 'ue se 'uiere al)an0ar3 por ejemplo# un generador de formularios de contacto1 21 Se identi2i)a a'uello 'ue produ)ir4 nuestro So2t5are terminado3 por ejemplo# un formulario .24L1 31 Se )rea un prototipo del produ)to de nuestra apli)a)i/n3 es decir# se crea un archivo .24L con un formulario de contacto a modo de ejemplo1 61 Se implementa el m+nimo )/digo ne)esario para 'ue ese 2ormulario sea retornado3 por ejemplo# desde el lenguaje de programaci$n en el que se vaya a desarrollar la aplicaci$n# se proceder"a a crear una funci$n que lea el contenido del archivo .24L y lo retorne. & continuaci$n# una instrucci$n# llamar"a a dicha funci$n imprimiendo en pantalla el valor de retorno1 71 Se pro)eder+a a repetir el paso 68 de a un +tem por ve03 esto se har# hasta lograr que el formulario .24L sea generado de forma :;;< dinmica1

2013 Eugenia Bahit www.eugeniabahit.com Bajo Licencia Creative Commons BY-NC-SA

The Original Hacker www.originalhacker.org

=uando adems# se implementa "DD como t*cnica para lograr el paso ># la di2eren)ia )on la gu+a anterior8 es 'ue tras el paso 38 se apli)a Test-First Programming para lograr el paso >.

TROUBLESHOOTING: INGENIERA INVERSA


)ste subt"tulo fue puesto e( profeso a fin de que a trav*s del humor ' considerando a la -ngenier"a -nversa un problema a resolver! ' se puedan plantear formas amenas y humanas! de llevar a cabo tal t*cnica. $ro lema3 se )on2unde el 'u( )on el )/mo 3escripci$n del problema, ?eneralmente# el primer problema al que uno se enfrenta es saber identificar el qu* sin pensar en el c$mo. 9 esto# se soluciona solo y +nicamente con un cambio radical de actitud. @bjetivo, 7erderle el miedo a lo desconocido1 &prender a convivir con la incertidumbre y aceptar que el c$mo llegar a su debido momento1 &ceptar que lo simple es preferible a lo complejo y lo complejo es preferible a lo complicado1 .acerse a la idea de que todo es posible y que alcanzar objetivos no es un problema, el problema es identificarlos1 %oluci$n, :. 3efinir lo que se quiere lograr a modo de .istoria de 5suario, como AusuarioB puedo Aacci$nB1 C. 7ensar en la acci$n de la .istoria de 5suario como en una aplicaci$n completa /un todo01 D. .acerse la pregunta Equ* voy a obtener cuando la funcionalidad est* operativaF 9 responder a ella con una sola frase corta utilizando la menor cantidad de calificativos y de verbos posibles. Lo ideal es centrarse en los sustantivos. $ro lema3 se tiende a pensar en 9el )/mo: )omo un todo . en ve0 de )omen0ar el desarrollo por el 2inal se )omien0a por el prin)ipio 3escripci$n del problema, @tro de los problemas ms frecuentes es que una vez hallado el qu*! no se logra implementar un desarrollo inverso y por el contrario# se comienza a escribir el c$digo de la manera que se lo har"a tradicionalmente. )sto genera un estancamiento en el desarrollo y consecuente falta de prolijidad en el c$digo generado. @bjetivo, &prender a pensar lateralmente1 -mplementar la l$gica y el pensamiento lateral en paralelo para aplicar la -ngenier"a -nversa de forma correcta.

2013 Eugenia Bahit www.eugeniabahit.com Bajo Licencia Creative Commons BY-NC-SA

The Original Hacker www.originalhacker.org

%oluci$n, 4ientras que en pasos anteriores se defini$ de forma lineal lo que se pretend"a lograr# ahora es momento de razonar de manera l$gica para obtener el siguiente paso /como si se tratase de una secuencia a la que se quiere dar continuidad0. )s decir# el siguiente paso consiste en escribir el m"nimo c$digo necesario para sustituir secuencia l$gica1 7ara encontrar dicha secuencia# una gran parte de las veces# puede ser necesario mirar el problema! desde diversos ngulos# es decir# analizar lo que se tiene de forma lateral1 .allada la secuencia# se debe elegir uno y solo un! punto de partida y concentrarse solo y +nicamente en escribir el c$digo que resuelva ese 'y no otro' "tem# evitando pensar en otros "tem o en lo que se necesitar resolver ms adelante. algo!. )se algo! es el que debe estar desencadenado por una

Es importante comprender que la Ingeniera Inversa demandar hacer un uso continuo del Refactoring y tomar la no-necesidad de refactorizacin del cdigo como un error de diseo prcticamente asegurado.

2013 Eugenia Bahit www.eugeniabahit.com Bajo Licencia Creative Commons BY-NC-SA

The Original Hacker www.originalhacker.org

PYTHON SCRIPTING: MANIPULAR ARCHIVOS DE CONFIGURACIN MEDIANTE CONFIGPARSER


EL
MDULO CONFIGPARSER DE PYTHON RESULTAR DE UNA GRAN AYUDA PARA DESARROLLAR SCRIPTS QUE NOS PERMITAN AUTOMATIZAR TAREAS GENERALMENTE RELACIONADAS CON LA INSTALACIN DE APLICACIONES EN LAS CUALES, TANTO LA CONFIGURACIN COMO LA OPTIMIZACIN Y ASEGURAMIENTO DE LAS MISMAS, CUMPLA UN PAPEL PRCTICAMENTE PROTAGNICO.

3
cabeza.

esde herramientas como failCban hasta aplicaciones como 4y%GL y 7.7# utilizan archivos de configuraci$n basados en secciones y# nada ms usual# que la necesidad de crear scripts automatizados que ayuden a los administradores de sistemas o especialistas en seguridad /o .acHers Iticos si eres de os que disfruta los eufemismos marketineros0 a configurar de forma $ptima estos archivos. ?eneralmente# como programadores# resolvemos esta necesidad haciendo malabares!# utilizando e(presiones regulares# reemplazando archivos y un sinf"n de alternativas que si bien solucionan el problema# claramente nos dan hartos dolores de

%in embargo# desde hace much"simo tiempo# 7ython nos provee en su librer"a estndar un m$dulo cuya responsabilidad# es justamente# la de permitirnos la manipulaci$n de archivos de configuraci$n basados en secciones. %e trata del m$dulo ConfigParser /renombrado a configparser en 7ython D0. )l m$dulo =onfig7arser permite tanto la lectura como edici$n de archivos de configuraci$n basados en secciones. =omo bien coment* al inicio# ejemplo de este tipo de archivos# podr"an ser fail2ban.conf de failCban# my.cnf de 4y%GL o php.ini de 7.7# entre otros tantos.

Jo obstante# ConfigParser no ser +nicamente un m$dulo destinado solo a un p+blico relacionado a la administraci$n del sistema1 tambi*n puede ser una buena alternativa# para que los programadores implementen sistemas de configuraci$n a sus propias aplicaciones. -ncluso hasta puede ser sumamente +til para implementar en aplicaciones Keb en las cules se requieran interfaces en m+ltiples idiomas.

2013 Eugenia Bahit www.eugeniabahit.com Bajo Licencia Creative Commons BY-NC-SA

The Original Hacker www.originalhacker.org

)n estos casos# los archivos de configuraci$n podr"an servir para definir te(tos estticos en los diversos idiomas que la aplicaci$n requiera y toda alternativa de personalizaci$n que se le quiera permitir al usuario# podr"a realizarse de forma sencilla# evitando el consumo de recursos producido por la implementaci$n de bases de datos. 7or ejemplo# suponiendo una aplicaci$n Keb en espaol# ingl*s y cataln# podr"an tenerse tres archivos,

textos.es textos.ca textos.en

9 cada uno de ellos# contar con las mismas secciones y variables /reconocidas por ConfigParser como opciones!0# pero por supuesto# diferentes valores,

; Archivo textos.es [modulos] clientes = Clientes proveedores = Proveedores [acciones] administrar = Administrar editar = Modificar eliminar = liminar ; Archivo textos.en [modulos] clientes = Clients proveedores = !uppliers [acciones] administrar = Manage editar = dit eliminar = "elete

=omo se puede ver# la finalidad de ConfigParser es directamente proporcional a la cantidad de usos que se le puede dar a los archivos de configuraci$n basados en secciones y el +nico l"mite# est en la imaginaci$n y creatividad del programador.

CREAR ARCHIVOS DE CONFIGURACIN CON CONFIGPARSER


=uando se trata de efectuar tareas de administraci$n yLo de seguridad# dif"cilmente se necesiten crear los archivos de configuraci$n de las aplicaciones que se estn optimizando. ?eneralmente# la )rea)i/n de estos ar)hivos8 ser4 ;til )uando se los re'uiera para apli)a)iones propias1

La no inclusin de archivos de configuracin por defecto en aplicaciones propias, puede utilizarse como parmetro condicional

2013 Eugenia Bahit www.eugeniabahit.com Bajo Licencia Creative Commons BY-NC-SA

The Original Hacker www.originalhacker.org

10

deductivo para la lgica de instalacin


7or supuesto# que estos archivos podr"an incluirse por defecto en la aplicaci$n# pero la no inclusi$n# podr"a utilizarse como parmetro deductivo en la l$gica de instalaci$n, si el ar)hivo no e-iste8 la instala)i/n no se ha )on)luido.

ConfigParser fue renombrado a configparser desde Python 3. La herramienta 2to3 efecta el cambio de nombre automtico en la importacin del mdulo, al momento de convertir el cdigo fuente.

5n ejemplo bsico de c$mo crear un archivo de configuraci$n desde ConfigParser aplicando una l$gica deductiva# podr"a verse como el siguiente,

#!/usr/bin/env python # -*- coding: utf-8 -*from ConfigParser import RawConfigParser from os import path # Si el rchivo de configur ci!n no existe if path.exists('myapp.conf') is False: # "regunto si se lo dese cre r print #$a aplicaci%n a&n no se ha configurado correctamente# continuar = ra'(input)#*"esea configurarla ahora+ ),-n. #. # #reo el rchivo de configur ci!n if continuar.lo'er). == #y#/ cparser = RawConfigParser() # Se cre el ob$eto #onfig" rser 'ith open)#myapp.conf#0 #'b#. as archivo/ cparser.write(archivo) # Se escribe el rchivo de configur ci!n else/ exit). # %in li&o l plic ci!n si el usu rio eligi! no concluir l inst l ci!n print #Contin&o con la e1ecuci%n...#

2a'ConfigParser es el objeto de configuraci$n bsico que utiliza ConfigParser. %in embargo# el objeto SafeConfigParser tambi*n se encuentra disponible,

#!/usr/bin/env python # -*- coding: utf-8 -*from ConfigParser import SafeConfigParser #... if continuar.lo'er). == #y#/ cparser = SafeConfigParser() 'ith open)#myapp.conf#0 #'b#. as archivo/ cparser.'rite)archivo.

2013 Eugenia Bahit www.eugeniabahit.com Bajo Licencia Creative Commons BY-NC-SA

The Original Hacker www.originalhacker.org

11

& simple vista# no se puede notar ninguna di2eren)ia entre RawConfigParser . SafeConfigParser# sin embargo# este +ltimo cuenta con una caracter"stica que lo convierte en mgico!, permite la interpolaci$n de variables en los archivos de configuraci$n.

A diferencia de ' (#onfig" rser, SafeConfigParser permite la interpolacin de variables en los arc ivos de configuracin

; Archivo de configur ci!n ; )$e*plo de interpol ci!n de v ri bles [miseccion] carga(maxima(permitida = 344 !ni"a"#"e#me"i"a = M5 (!ni"a"#"e#me"i"a)s l v lor de unid d-de-*edid

; el valor de carga_maxima_permitida ser +,, conc ten do ; es decir: 100 MB

%e debe tener en cuenta que la interpolaci$n anterior# solo ser posible si se utiliza !afeConfigParser. )n el ejemplo anterior# nos limitamos a crear un archivo de configuraci$n en blanco# lo cual claramente# no tendr"a mucho sentido. %in embargo# completar el archivo# no es nada dif"cil. Basta con agregar las se))iones con a""#section)#nombre(de(la(seccion#. e in)luir varia les y valores con set)#seccion#0 #variable#0 #valor#.. & continuaci$n# un sencillo ejemplo que lo aclarar todo,

67-usr-bin-env python 6 898 coding/ utf8: 898 from ConfigParser import SafeConfigParser from os import path if path.exists)#myapp.conf#. is ;alse/ print #$a aplicaci%n a&n no se ha configurado correctamente# continuar = ra'(input)#*"esea configurarla ahora+ ),-n. #. if continuar.lo'er). == #y#/ cparser = SafeConfigParser() cparser.a""#section('$ccesos') cparser.set('$ccesos'% 'servi"or'% '&'(.)*+.,-../') cparser.set('$ccesos'% '!s!ario'% 'pepegrillo') cparser.set('$ccesos'% 'p!erto'% '&//&') 'ith open)#myapp.conf#0 #'b#. as archivo/ cparser.write(archivo) else/ exit). # ...

Lo anterior# generar el siguiente archivo de configuraci$n,

2013 Eugenia Bahit www.eugeniabahit.com Bajo Licencia Creative Commons BY-NC-SA

The Original Hacker www.originalhacker.org

12

[Accesos] servidor = 32<.=>?.@:.A4 usuario = pepegrillo puerto = 3443

Male aclarar que una forma de crear el mismo archivo de forma personalizada# podr"a haber sido la utilizaci$n de ra'(input para asignar los valores de cada variable,

cparser.add(section)#Accesos#. cparser.set)#Accesos#0 #servidor#0 raw#inp!t('Servi"or: '). cparser.set)#Accesos#0 #usuario#0 raw#inp!t('0s!ario: '). cparser.set)#Accesos#0 #puerto#0 raw#inp!t('P!erto: ').

OBTENIENDO VALORES
%upongo que a esta altura# e(istiendo un m*todo set).# la obviedad de que seguramente se dispone de un m*todo get).# no ser necesaria mencionarla. 7ues como siempre sucede en 7ython# la l$gica# el sentido com+n# la intuici$n y por sobre todo# la prolijidad y la coherencia# van de la mano.

Antes de poder obtener un valor concreto es necesario leer el archivo con el mtodo read

Lo +nico que se necesita &J2)% de invocar al m*todo get('secci1n'% 'varia2le') /ya sea de 2a'ConfigParser como de !afeConfigParser0 es disponemos de un m*todo rea"(), leer! el archivo de configuraci$n. 9 para ello#

#!/usr/bin/env python # -*- coding: utf-8 -*from ConfigParser import !afeConfigParser from os import path cparser = SafeConfigParser() if path.exists)#myapp.conf#. is ;alse/ print #$a aplicaci%n a&n no se ha configurado correctamente# continuar = ra'(input)#*"esea configurarla ahora+ ),-n. #. if continuar.lo'er). == #y#/ cparser.add(section)#Accesos#. cparser.set)#Accesos#0 #servidor#0 #32<.=>?.@:.A4#. cparser.set)#Accesos#0 #usuario#0 #pepegrillo#. cparser.set)#Accesos#0 #puerto#0 #3443#. 'ith open)#myapp.conf#0 #'b#. as archivo/ cparser.'rite)archivo. else/ exit). else/

2013 Eugenia Bahit www.eugeniabahit.com Bajo Licencia Creative Commons BY-NC-SA

The Original Hacker www.originalhacker.org

13

cparser.rea"('myapp.conf') print cparser.get('$ccesos'% '!s!ario')

Lo anterior /siguiendo los mismos ejemplos que al crear el archivo0# arrojar pepegrillo como salida en caso que el archivo de configuraci$n ya e(ista. @tras opciones para obtener valores mediante ConfigParser son los m*todos sections). y options). que retornan la lista de secciones y variables /opciones0 del archivo de configuraci$n le"do# respectivamente,

from ConfigParser import !afeConfigParser cparser = !afeConfigParser). cparser.read)#myapp.conf#. for seccion in cparser.sections()/ print seccion print cparser.options(seccion)

Lo anterior# retornar"a,
Accesos [#servidor#0 #usuario#0 #puerto#]

%in embargo# es muy probable que se desee no solo obtener las variables )options. sino tambi*n sus valores. 5na forma de lograrlo# es mediante el m*todo items).# similar a options). pero que agrega los valores al elemento de retorno# en forma de tuplas,

from ConfigParser import !afeConfigParser cparser = !afeConfigParser). cparser.read)#myapp.conf#. for seccion in cparser.sections)./ print seccion print cparser.items)seccion. # . s lid de lo nterior ser/: # Accesos # 012servidor23 2+45.67.898.:,2;3 12usu rio23 2pepegrillo2;3 12puerto23 2+,,+2;<

6inalmente# es posible que se necesite verificar las variables obteniendo errores si no se cumple con el tipo de datos esperado. 7ara ello# D m*todos se encuentran disponibles, getint).# getfloat). y getboolean).# aunque es importante entender que el uso de estos tres m(todos8 solo se <usti2i)ar4 si se desea o tener error en )aso de 'ue el elemento soli)itado no se )orresponda al tipo de datos pedido ,

cparser.getboolean)#Accesos#0 #puerto#.

# = lue)rror: >ot

boole n: +,,+

2013 Eugenia Bahit www.eugeniabahit.com Bajo Licencia Creative Commons BY-NC-SA

The Original Hacker www.originalhacker.org

14

%i bien los m*todos generan error cuando el tipo de datos no es el esperado# no fallan cuando la conversi$n previa es posible,

cparser.getfloat)#Accesos#0 #puerto#.

# +,,+.,

AGREGAR SECCIONES Y/U OPCIONES


=uando se desea agregar una o ms secciones a un archivo de configuraci$n# se realiza e(actamente de la misma forma en la que se ha efectuado el agregado al momento de la creaci$n del archivo. )sta regla aplica tambi*n# como es de esperarse# cuando lo que se desea agregar son opciones a las secciones que se estn incorporando. %in embargo# si se quieren agregar opciones a secciones e(istentes# la invocaci$n al m*todo read). se har necesaria,

#!/usr/bin/env python # -*- coding: utf-8 -*from ConfigParser import !afeConfigParser from os import path cparser = !afeConfigParser). if path.exists)#myapp.conf#. is ;alse/ print #$a aplicaci%n a&n no se ha configurado correctamente# continuar = ra'(input)#*"esea configurarla ahora+ ),-n. #. if continuar.lo'er). == #y#/ # Se agrega nueva seccin y nuevas opciones cparser.add(section)#Accesos#. cparser.set)#Accesos#0 #servidor#0 #32<.=>?.@:.A4#. cparser.set)#Accesos#0 #usuario#0 #pepegrillo#. cparser.set)#Accesos#0 #puerto#0 #3443#. else/ exit). else/ # Para agregar nuevas opciones a secciones existentes # primero se lee el arc ivo y luego se reali!a la agregacin cparser.rea"('myapp.conf') cparser.set)#Accesos#0 #rsa(file(path#0 ra'(input)#2uta llave 2!A/ #.. 'ith open)#myapp.conf#0 #'b#. as archivo/ cparser.'rite)archivo.

ANALIZAR O EVALUAR EL CONTENIDO DE UN ARCHIVO DE


CONFIGURACIN
&lgo tan simple como verificar si una determinada secci$n u opci$n se encuentra presente en un archivo de configuraci$n antes de ejecutar una instrucci$n concreta# es posible gracias a los m*todos has#section y has#option,

2013 Eugenia Bahit www.eugeniabahit.com Bajo Licencia Creative Commons BY-NC-SA

The Original Hacker www.originalhacker.org

15

#!/usr/bin/env python # -*- coding: utf-8 -*from ConfigParser import !afeConfigParser from os import path cparser = !afeConfigParser). if path.exists)#myapp.conf#. is ;alse/ print #$a aplicaci%n a&n no se ha configurado correctamente# continuar = ra'(input)#*"esea configurarla ahora+ ),-n. #. if continuar.lo'er). == #y#/ cparser.add(section)#Accesos#. cparser.set)#Accesos#0 #servidor#0 #32<.=>?.@:.A4#. cparser.set)#Accesos#0 #usuario#0 #pepegrillo#. cparser.set)#Accesos#0 #puerto#0 #3443#. else/ exit). else/ cparser.read)#myapp.conf#. # "ntes de agregar una nueva opcin# verifica si la seccin existe$ if cparser.has#section('$ccesos'): # % &ue la opcin a agregar no se encuentre ya presente if not cparser.has#option('$ccesos'% 'rsa#file#path'): cparser.set)#Accesos#0 #rsa(file(path#0 ra'(input)#2uta llave 2!A/ #.. 'ith open)#myapp.conf#0 #'b#. as archivo/ cparser.'rite)archivo.

MODIFICAR VALORES DE OPCIONES EXISTENTES


)n este caso# con tan solo mezclar un poco de read). con algo de set).! ser suficiente. %iempre que se desee modificar un valor puntual# debe primero leerse el archivo y recurrir al m*todo set). para modificar el valor de una variable. )sto puede hacernos llegar a la conclusi$n que,

al invocar al mtodo set si la opcin pasada por parmetro existe, modifica su valor; en caso contrario, la crea.

)n el siguiente ejemplo# si la secci$n &ccesos! e(iste# se modificar el valor de la variable rsa(file(path en caso que e(ista o se crear la opci$n# en caso contrario,

#... if cparser.has(section)#Accesos#./ cparser.set('$ccesos'% 'rsa#file#path'% raw#inp!t('R!ta llave RS$: ')) #...

ELIMINAR SECCIONES U OPCIONES


6inalmente# lo que nos faltaba para poder manipular archivos de configuraci$n de forma completa# era una

2013 Eugenia Bahit www.eugeniabahit.com Bajo Licencia Creative Commons BY-NC-SA

The Original Hacker www.originalhacker.org

16

forma de eliminar secciones yLu opciones. 7ara lograrlo# primero necesitaremos leer el archivo de configuraci$n# luego# invocar a los m*todos remove#section)#secci%n#. o remove#option)#secci%n#0 #variable#. para eliminar una secci$n u opci$n respectivamente y por +ltimo# guardar el archivo,

# )li*in tod l secci!n Accesos cparser.remove(section)#Accesos#. # )li*in solo l opci!n rs -file-p th de l secci!n Accesos cparser.remove(option)#Accesos#0 #rsa(file(path#.

Es muy importante saber que si la seccin u opcin pasada a remove_section o remove_option no existe, ninguno de los dos mtodos arrojar un error.

RESUMEN DE CONFIGPARSER
# ?*port ci!n del *!dulo en "ython 4.x from ConfigParser import !afeConfigParser from ConfigParser import 2a'ConfigParser # ?*port ci!n del *!dulo en "ython 5.x from configparser import !afeConfigParser from configparser import 2a'ConfigParser # ?nici li& r el p rser cparser = !afeConfigParser). cparser = 2a'ConfigParser). # " r soporte de interpol ci!n # Sin soporte de interpol ci!n # " r soporte de interpol ci!n # Sin soporte de interpol ci!n

# #on soporte de interpol ci!n # Sin soporte de interpol ci!n cre r

# .eer el rchivo )@#)"AB si se lo v cparser.read)#-ruta-al-archivo#. # Agreg r secciones cparser.add(section)#!ecci%n#.

# Agreg r o *odific r opciones cparser.set)#!ecci%n#0 #Bariable#0 #Balor#. # Bbtener v lores: # Bbtener un opci!n: cparser.get)#!ecci%n#0 #Bariable#. # Bbtener un opci!n especific ndo el tipo de d tos p r # f ll ndo en c so de error cparser.getint)#!eccion#0 #variable#. cparser.getfloat)#!eccion#0 #variable#. cparser.getboolean)#!eccion#0 #variable#. # Bbtener un list cparser.sections). con tod s l s secciones ser convertido o

2013 Eugenia Bahit www.eugeniabahit.com Bajo Licencia Creative Commons BY-NC-SA

The Original Hacker www.originalhacker.org

17

# Bbtener un list con tod s l s opciones de un cparser.options)#!ecci%n#.

secci!n secci!n3 dentro de tupl s

# Bbtener un list con l s opciones y v lores de un cparser.items)#!ecci%n#. # S ber si un secci!n existe cparser.has(section)#!ecci%n#. # S ber si un opci!n existe cparser.has(option)#!ecci%n#0 #variable#. # Cu rd r un rchivo de configur ci!n 'ith open)#-ruta-al-archivo#0 #'b#. as archivo/ cparser.'rite)archivo. # )li*in r un secci!n cparser.remove(section)#!ecci%n#. # )li*in r un opci!n cparser.remove(option)#!ecci%n#0 #variable#.

FORMATO DE LOS ARCHIVOS DE CONFIGURACIN


; co*ent rios inici dos por punto y co* # t *biDn son ignor d s lEne s inici d s con el signo nu*er l [Combre de la !ecci%n] opci%n = valor tipo string entero = 3444 flotante = 3A.> booleano = Drue ; opciones interpol d s ; reFuieren S fe#onfig" rser variable = !e hicieron E)horas.i horas extras horas = 32 ; el v lor de v ri ble ser/: Se hicieron +4 hor s extr s

2013 Eugenia Bahit www.eugeniabahit.com Bajo Licencia Creative Commons BY-NC-SA

The Original Hacker www.originalhacker.org

18

DE SOFTWARE: AGREGADO DE ARCHIVOS CRON Y EJECUCIN PERIDICA DE PROCESOS EN LOS PAQUETES .DEB
ESTA
SERIE DE PAPERS QUE COMENZ EN LA EDICIN NRO. 11 DE LA REVISTA HACKERS & DEVELOPERS MAGAZINE EXPLICANDO CMO CREAR PAQUETES DEBIAN Y CONTINU EN LA EDICIN ANTERIOR DE THE ORIGINAL HACKER HABLANDO ACERCA DE CMO DESARROLLAR ARCHIVOS PRE Y POST INSTALACIN PROPIOS, COMIENZA A LLEGAR A SU FIN EN ESTA ENTREGA, EN LA QUE ME CONCENTRAR EN LA NECESIDAD DE NUESTRAS APLICACIONES DE INCLUIR LA EJECUCIN PERIDICA DE PROCESOS QUE PARA CORRER, REQUIERAN ALMACENARSE EN LOS DIRECTORIOS /ETC/CRON.9

INGENIERA

uando desarrollamos aplicaciones# frecuentemente incluimos instrucciones# sugerencias y hasta incluso directivas de mantenimiento en archivos N)&34) o en la documentaci$n de nuestro %oftware. %in embargo# incluso aunque el p+blico objetivo de nuestros desarrollos sean profesionales de los sectores -2# toda instrucci$n# directiva o sugerencia que requiera ser ejecutada post'instalaci$n# suele ser ignorada# sobre todo# si la misma necesita ser llevada a cabo en ms de una oportunidad. "anto De ian )omo sus distros derivadas8 son )apa)es de e<e)utar tareas espe)+2i)as de 2orma peri/di)a# que van m4s all4 de la programaci$n de tareas mediante cronta2. 3ichas tareas son ejecutadas por el propio %istema @perativo# cada hora# diaria# semanal o mensualmente y las mimas# se encuentran especificadas en guiones de shell e<e)uta les# alojados en los directorios -etc-cron.hourly# -etc-cron.daily# -etc-cron.'eeFly y -etc-cron.monthly. 3e all" que# por ejemplo# tareas de limpieza# depuraci$n y mantenimiento de la base de datos de una aplicaci$n (como la que vimos en el artculo de emulacin de tokens temporales 1 en la edicin pasada)# tranquilamente podr"an efectuarse mediante un cron.daily ' agregado al paquete .deb '# liberando as" al usuario de tener que programar dicha tarea manualmente.

&rt"culo 9Emula)i/n de to=ens de seguridad temporales para el registro de usuarios: /2he @riginal .acHer JO :0, http,LLlibrary.originalhacHer.orgLbibliotecaLarticuloLverL::8

2013 Eugenia Bahit www.eugeniabahit.com Bajo Licencia Creative Commons BY-NC-SA

The Original Hacker www.originalhacker.org

19

LOS ARCHIVOS CRON.* Y SU FORMATO


Los archivos cron.9# como coment* unos prrafos ms arriba# son guiones de shell ejecutables. )stos archivos se alojan en las diversas carpetas -etc-cron.9 bajo el nombre de la aplicaci$n. )s as"# que por ejemplo# en la carpeta -etc-cron.daily encontraremos archivos cuyos nombres sern apache20 dpFg0 sendmail o apt# entre otros. =ada carpeta cron.9 est destinada a almacenar guiones que se ejecutarn bajo un mismo per"odo de tiempo. 4uy intuitivamente# la relaci$n carpeta'per"odo es la siguiente,

-etc-cron.hourly -etc-cron.daily -etc-cron.'eeFly -etc-cron.monthly

cada hora diariamente semanalmente mensualmente

.aciendo un cat a cualquiera de los archivos alojados dentro de alguna de estas carpetas cron.9# podremos comprobar que efectivamente se trata de guiones de shell,

eugeniaGcococha8gnucita/3etc3cron."aily4 cat passw" #!/bin/sh cd -var-bacFups HH exit 4 for ;I$ in pass'd group shado' gshado'J do test 8f -etc-K;I$ HH continue cmp 8s K;I$ .baF -etc-K;I$ LL continue cp 8p -etc-K;I$ K;I$ .baF LL chmod ?44 K;I$ .baF

done eugeniaGcococha8gnucita/-etc-cron.dailyK

!ualquier guin de s ell es v"lido para ser agregado como arc ivo cron#$

EXCEPCIONES CRON.D
La +nica e-)ep)i/n a todo lo anterior# son los archivos cuyo destino ser el directorio 3etc3cron.". Los archivos alojados en este directorio# tendrn un formato diferente y adems# solo se deben utilizar cuando el per"odo de ejecuci$n difiera de cualquiera de los anteriores. 5n claro e<emplo de uso )orre)to de cron."8 es el ar)hivo php7 en)argado de eliminar las sesiones ina)tivas. E& que no te lo esperabasF %in buscarlo# de pronto encuentras la respuesta a &)/mo ha)e $>$ para eliminar las sesiones ina)tivas tras un per+odo de tiempo determinado, . 9 la respuesta

2013 Eugenia Bahit www.eugeniabahit.com Bajo Licencia Creative Commons BY-NC-SA

The Original Hacker www.originalhacker.org

20

justamente# es que $>$ agrega un ar)hivo php* a 3etc3cron." indicando como per"odo de ejecuci$n /formato crontab. el indicado en la directiva session.gc(maxlifetime del archivo php.ini y procediendo a ejecutar la instrucci$n encargada de destruir toda sesi$n cuyo per"odo de inactividad# supere el mencionado.

eugeniaGcococha8gnucita/3etc3cron."4 cat php* # /etc/cron.d/php7: cront b fr g*ent for php7 # Ahis purges session files older th n @3 (here @ is defined in seconds # s the l rgest v lue of session.gc-* xlifeti*e fro* ll your php.ini # files3 or 46 *inutes if not defined. See /usr/lib/php7/* xlifeti*e # .ooG for nd purge old sessions every 5, *inutes 4A0<A 9 9 9 9 root [ 8x -usr-lib-php>-maxlifetime ] LL [ 8d -var-lib-php> ] LL find -var-lib-php>- 8depth 8mindepth 3 8maxdepth 3 8type f 8cmin MK )-usr-lib-php>-maxlifetime. 7 8execdir fuser 8s NO 2P-dev-null QJ 8delete

Los arc ivos cron.d deben tener el formato requerido por crontab para poder ser ejecutados por el sistema de forma satisfactoria

ESPECIFICACIONES DEBIAN
=omo especificaciones puntuales para los paquetes 3ebian / .deb0# se deben tener en cuenta sus normas. Los archivos cuyo destino sean las carpetas -etc-cron.9 seguirn estas pautas, )l 2ormato del ar)hivo debe ser un gui$n de shell para todos los casos e(cepto para cron.d en el que debe tener el formato sugerido por crontab1 Los archivos deben tener permisos de e<e)u)i/n /se debe hacer un chmod Mx a cada archivo .cron.901 Los archivos de en guardarse en la )arpeta DEB*AN del paquete1 )l nom re de ar)hivo debe tener el formato, no*bre-del-p Fuete.cron.9 d$nde, nom2re#"el#pa5!ete ser el de la aplicaci$n. 7or ejemplo# apache2 6 ser hourly# daily# 'eeFly0 monthly o d seg+n corresponda. 7or ejemplo# un archivo 789:$;3apache'.cron."aily se alojar en -etc-cron.daily-apache2 y ser ejecutado diariamente.

2013 Eugenia Bahit www.eugeniabahit.com Bajo Licencia Creative Commons BY-NC-SA

The Original Hacker www.originalhacker.org

21

CMO ABM

EUROPIO ENGINE LAB:

SE HICIERON LOS DE LA WEB THE ORIGINAL HACKER LIBRARY?

EN

LA EDICIN ANTERIOR, VIMOS QUE CREAR FORMULARIOS Y LISTADOS CON EUROPIO ENGINE, ERA SUMAMENTE RPIDO Y SENCILLO SI SE UTILIZABAN LOS COMPLEMENTOS DISPONIBLES PARA ESTOS FINES. EN ESTA ENTREGA, VAMOS A COMPLETAR EL LABORATORIO VIENDO COMO CREAR UN ABM, PUEDE CONVERTIRSE EN UNA TAREA QUE SE PUEDA EJECUTAR CON LOS OJOS CERRADOS.

uando lanc* la Keb "he ?riginal >a)=er @i rar.2# uno de los comentarios que ms recib"# fue referido a la gran cantidad de trabajo que el desarrollo de la plataforma me deb"a haber consumido. %in embargo# solo tuve 'ue invertir unos )uantos minutos. 7ero el poco trabajo# no fue producto de las magias! de una herramienta# sino de algo tan sencillo como tener un core /n+cleo0 bien resuelto.

Mientras que el ncleo de una aplicacin sea lo suficientemente genrico para adaptarse a cualquier requerimiento % lo necesariamente flexible para que lo genrico no se transforme en m"gico, toda la ciencia de un ABM es desmitificada por la propia arquitectura de la aplicacin % el dise&o del 'istema#
7ara e(plicar como crear un sencillo &B4# tomar* como ejemplo de objeto a 2evista# por ser un objeto muy completo, se compone de una colecci$n de objetos Articulo que a la vez# se componen de un objeto Autor. 7asemos a e(plicarlo.

http,LLlibrary.originalhacHer.org

2013 Eugenia Bahit www.eugeniabahit.com Bajo Licencia Creative Commons BY-NC-SA

The Original Hacker www.originalhacker.org

22

DE LAS HISTORIAS DE USUARIO A LOS OBJETOS, SUS RELACIONES Y DATOS ANEXOS...


Como administradora puedo agregar una nueva revista Como administradora puedo agregar artculos a una revista

3e los criterios de aceptaci$n de las .istorias de 5suario# surgieron todos los objetos /aparecen subrayados y en letra cursiva0, Como administradora puedo agregar art+)ulos a una revista P. 5n mismo artculo no puede agregarse a ms de una revista =ada art"culo puede contener un solo autor P.

)l anlisis de la rela)i/n entre los o <etos# fue sumamente simple, La revista tiene una colecci$n de art"culos )l art"culo tiene un autor

=on una relaci$n de objetos pura# ya estaba en condiciones de armar mi diagrama de clases y de paso# pensar en qu* datos /ms all de las propiedades de cada objeto0# podr"a necesitar. 9 as"# surgi$ el siguiente h"brido objetos'datos,

Diagrama !A@ realizado con Dia https,LLprojects.gnome.orgLdiaL /%oftware Libre0

StandardObject y ComposerObject son dos objetos provistos por Europio Engine

!tandardRb1ect# como su nombre lo indica# es un objeto estndar del cual heredarn la mayor"a de los objetos a no ser que tengan caracter"sticas especiales como es el caso de los objetos de pertenencia /o compositores e(clusivos0# que deben heredar de ComposerRb1ect.

2013 Eugenia Bahit www.eugeniabahit.com Bajo Licencia Creative Commons BY-NC-SA

The Original Hacker www.originalhacker.org

23

&D/nde o tener ma.or in2orma)i/n so re Stan"ar"<2=ect . Composer<2=ect, 7ara mayor informaci$n de Stan"ar"<2=ect puedes leer la documentaci$n oficial en www.europio.orgLdocsLstandardobject. Lo relativo a Composer<2=ect# puedes encontrarlo en www.europio.orgLdocsLcomposerobject y www.europio.orgLdocsLmanyCone. %i necesitas obtener in2orma)i/n te/ri)o-)on)eptual sobre los objetos estndar y compositor# en el libro "eor+a sint4)ti)o-gramati)al de o <etos# doy una e(plicaci$n detallada con ejemplos tanto en 7.7 como en 7ython. 7ara obtener el libro# puedes ingresar en http,LLwww.buboH.esLlibrosLC:QCRRL2eoria'sintacticogramatical'de'objetos.

CREACIN DE ARCHIVOS PARA LOS MODELOS, LAS VISTAS Y LOS


CONTROLADORES
& fin de evitar los t"picos errores humanos# cre* estos archivos con la =L- (Command Line Inter ace) de )uropio )ngine. 7ara ello# navegu* hasta la carpeta core-cli y cre* primero# las carpetas para el m$dulo al cul llam* biblioteca,

eugeniaGcococha8gnucita/S-'ebpro1ects-library-core-cliK .3e!ropio >c 2i2lioteca' M%dulo biblioteca creado con Txito eugeniaGcococha8gnucita/S-'ebpro1ects-library-core-cliK

9 luego s"# ejecut* el comando para crear cada uno de los archivos# pasando como argumento el nombre de cada =lase principal del modelo /adems del nombre del m$dulo0,

eugeniaGcococha8gnucita/S-'ebpro1ects-library-core-cliK .3e!ropio >f 2i2lioteca $!tor $isto7 eugeniaGcococha8gnucita/S-'ebpro1ects-library-core-cliK .3e!ropio >f 2i2lioteca Revista $isto7 eugeniaGcococha8gnucita/S-'ebpro1ects-library-core-cliK .3e!ropio >f 2i2lioteca $rt?c!lo $isto7

LOS MODELOS
%in dudas# un paso sencillo ya que previamente hab"a armado el diagrama de clases. %olo era necesario agregar las propiedades y los m*todos de agregaci$n en los casos que correspondiese,

# Archivo:

pp*odules/bibliotec /*odels/ utor.php

class Autor extends !tandardRb1ect N public function ((construct). N Kthis8Pautor(id = 4J

2013 Eugenia Bahit www.eugeniabahit.com Bajo Licencia Creative Commons BY-NC-SA

The Original Hacker www.originalhacker.org

24

Kthis8Pnombre = ##J O O # Archivo: pp*odules/bibliotec /*odels/ rticulo.php

import)#appmodules.biblioteca.models.autor#.J class Articulo extends ComposerRb1ect N public function ((construct)Autor Kautor=CU$$. N Kthis8Particulo(id = 4J Kthis8Ptitulo = ##J Kthis8Pautor = KautorJ Kthis8Pseccion = ##J Kthis8Prevista = 4J O O # Archivo: pp*odules/bibliotec /*odels/revist .php

import)#appmodules.biblioteca.models.articulo#.J class 2evista extends !tandardRb1ect N public function ((construct). N Kthis8Prevista(id = 4J Kthis8Pfecha = ##J 6 date Kthis8Pnumero = 4J Kthis8Particulo(collection = array).J O public function add(articulo)Articulo Karticulo. N Kthis8Particulo(collection[] = KarticuloJ O O

5na vez completos estos archivos# para concluir este paso solo restaba, 4apear los modelos creados1 ?enerar las tablas en la base de datos1

)n el caso particular de estos objetos# no ser"a necesario recurrir a )uropio =L- para crear tablas# ya que ning+n conector l$gico intervendr"a en la relaci$n. &s" que el resultado del mapeo manual fue verdaderamente simple,

-- Archivo: bibliotec .sFl U! database(nameJ

-- t bl utor p r persistenci de ob$etos Autor C2 AD DA5$ autor ) autor(id ICD)33. CRD CU$$ AUDR(ICC2 M CD P2IMA2, V ,

2013 Eugenia Bahit www.eugeniabahit.com Bajo Licencia Creative Commons BY-NC-SA

The Original Hacker www.originalhacker.org

25

0 nombre BA2CWA2):4. CXIC =Inno"5J

-- t bl revist p r persistenci de ob$etos 'evist C2 AD DA5$ revista ) revista(id ICD)33. CRD CU$$ AUDR(ICC2 M CD P2IMA2, V , 0 fecha "AD 0 numero ICD)<. . CXIC =Inno"5J -- t bl rticulo p r persistenci de ob$etos Articulo C2 AD DA5$ articulo ) articulo(id ICD)33. CRD CU$$ AUDR(ICC2 M CD P2IMA2, V , 0 titulo BA2CWA2)344. 0 seccion BA2CWA2)>4. 0 revista ICD)33. CRD CU$$ 0 ;R2 IXC V , )revista. 2 ; 2 CC ! revista )revista(id. RC " $ D CA!CA" 0 IC" Y )revista. 0 autor ICD)33. 0 ;R2 IXC V , )autor. 2 ; 2 CC ! autor )autor(id. RC " $ D ! D CU$$ 0 IC" Y )autor. . CXIC =Inno"5J

6inalmente# import* el archivo para crear las tablas,

eugeniaGcococha8gnucita/S-'ebpro1ects-libraryK mys5l >! usuario >p @ 2i2lioteca.s5l

COMPLETANDO RECURSOS: AGREGAR


&l fin le lleg$ el momento a las vistas y a los controladores. Lo primero que hice# fue crear los recursos agregar de cada uno de los modelos# para lo cual utilic* el plug'in Zeb;orm en cada una de las vistas,

# "rc ivo$ appmodules'(i(lioteca'vie)s'autor*p p # 'ee*pl &o del *Dtodo greg r1; de l vist de Autor=ie( public function agregar). N Kform = ne' Zeb;orm)#-biblioteca-autor-guardar#.J Kform8Padd(text)#nombre#.J Kform8Padd(submit).J print Demplate)#Agregar Autor#.8Psho')Kform8Psho')..J O # "rc ivo$ appmodules'(i(lioteca'vie)s'revista*p p # 'ee*pl &o del *Dtodo greg r1; de l vist de 'evist =ie( public function agregar). N Kform = ne' Zeb;orm)#-biblioteca-revista-guardar#.J Kform8Padd(text)#fecha#0 #;echa de publicaci%n#.J Kform8Padd(text)#numero#.J

2013 Eugenia Bahit www.eugeniabahit.com Bajo Licencia Creative Commons BY-NC-SA

The Original Hacker www.originalhacker.org

26

Kform8Padd(submit).J print Demplate)#Agregar 2evista#.8Psho')Kform8Psho')..J O

7ara el caso de ArticuloBie'# modifiqu* adems el recurso agregar del controlador# a fin de que *ste# le entregara a la vista las colecciones de Autor y 2evista para que pudiesen mostrarse en dos listas desplegables,

# "rc ivo$ appmodules'(i(lioteca'controllers'articulo*p p # 'ee*pl &o del *Dtodo greg r1; de l vist de Articulo#ontroller public function agregar). N Kautor(collector = Collector<2=ect::get('$!tor')A Kautores = Kautor(collector8PcollectionJ Krevista(collector = Collector<2=ect::get('Revista')A Krevistas = Krevista(collector8PcollectionJ 4this>Bview>Bagregar(4a!tores% 4revistas)A C # "rc ivo$ appmodules'(i(lioteca'vie)s'articulo*p p # 'ee*pl &o del *Dtodo greg r1; de l vist de Articulo=ie( public function agregar)Kautores0 Krevistas. N 4this>Bprepare#collection(4a!tores% 'nom2re')A 4this>Bprepare#collection(4revistas% 'n!mero')A Kform = ne' Zeb;orm)#-biblioteca-articulo-guardar#.J Kform8Padd(text)#titulo#.J Kform8Padd(text)#seccion#.J Kform8Padd(select)#autor#0 Kautores.J Kform8Padd(select)#revista#0 Krevistas.J Kform8Padd(submit).J print Demplate)#Agregar Art[culo#.8Psho')Kform8Psho')..J O private f!nction prepare#collection(D4coleccion% 4text) E Kidproperty = strtolo'er)get(class)Kcoleccion[4].. . \(id\J foreach)Kcoleccion as LKob1. N Kob18Pvalue = Kob18PKidpropertyJ Kob18Ptext = Kob18PKtextJ O O

)l m*todo privado prepare(collection). en realidad solo lo cre* para no tener que estar escribiendo c$digo redundante y as"# evitar ensuciar el m*todo agregar. )ste m*todo# como se puede ver# modi2i)a por re2eren)ia la colecci$n de objetos que se le pasa por parmetro# agregando dos propiedades / text y value0 que son las que Zeb;orm//add(select utilizar como text y value de los option respectivamente. Male aclarar que lo correcto si se quisiera ser estricto# hubiese sido convertir los objetos a arra!s mediante settype). y agregar text y value como claves en vez de hacerlo como propiedades# ya que por un lado# en realidad son solo datos y por el otro# Zeb;orm//add(select). est preparado tanto para renderi"ar objetos como arra!s asociativos.

2013 Eugenia Bahit www.eugeniabahit.com Bajo Licencia Creative Commons BY-NC-SA

The Original Hacker www.originalhacker.org

27

)l segundo parmetro que recibe este m*todo# es el nombre de la propiedad que se utilizar para el valor del te(to de cada una de las opciones de la lista desplegable.

EL RECURSO GUARDAR
Le toca el turno a los recursos guardar de cada uno de los modelos. Basndome en los campos de formulario que gener* en los m*todos anteriores# simplemente modifiqu* las propiedades de cada objeto de forma directa# con lo recibido desde los formularios.

Por favor, notar que ningn input ha sido filtrado y/o verificado en el cdigo fuente de los controladores, ya que implement un plug-in en fase experimental, que filtra el array $_POST de forma automtica. Para mayor informacin, leer el artculo sobre Seguridad Informtica de esta edicin.

%olo se completaron los recursos guardar). en los controladores de Articulo0 Autor y 2evista0 sin ser necesario modificar ning+n otro archivo. Los recursos guardar0 finalmente# quedaron como los que siguen,

# "rc ivo$ appmodules'(i(lioteca'controllers'autor*p p public function guardar). N Kid = )isset)K(PR!D[#id#].. + K(PR!D[#id#] / 4J Kthis8Pmodel8Pautor(id = KidJ Kthis8Pmodel8Pnombre = K(PR!D[#nombre#]J Kthis8Pmodel8Psave).J WDDPWelper//go)\-biblioteca-autor-listar\.J O # "rc ivo$ appmodules'(i(lioteca'controllers'revista*p p public function guardar). N Kid = )isset)K(PR!D[#id#].. + K(PR!D[#id#] / 4J Kthis8Pmodel8Prevista(id = KidJ Kthis8Pmodel8Pfecha = K(PR!D[#fecha#]J Kthis8Pmodel8Pnumero = )int.K(PR!D[#numero#]J Kthis8Pmodel8Psave).J WDDPWelper//go)\-biblioteca-revista-listar\.J O # "rc ivo$ appmodules'(i(lioteca'controllers'articulo*p p public function guardar). N /* " ttern es un cl se provist por )uropio )ngine cuy fin lid d es l de proveer *Dtodos est/ticos Fue i*ple*enten diversos p trones de diseIo3 entre ellos3 f ctory3 Fuien cre r/ un ob$eto del tipo especific do co*o pri*er p r/*etro y cuy ?J coincid con el v lor envi do co*o segundo rgu*ento. " r * yor infor* ci!n3 se puede cceder l docu*ent ci!n ofici l ingres ndo en http://europio.org/docs/p ttern */ Kid = )isset)K(PR!D[#id#].. + K(PR!D[#id#] / 4J Kthis8Pmodel8Particulo(id = KidJ Kthis8Pmodel8Ptitulo = K(PR!D[#titulo#]J # Si es ,3 greg un nuevo ob$eto # sino edit el ob$eto con dich id

# Helper de )uropio p r

redirecciones

2013 Eugenia Bahit www.eugeniabahit.com Bajo Licencia Creative Commons BY-NC-SA

The Original Hacker www.originalhacker.org

28

Kthis8Pmodel8Pseccion = K(PR!D[#seccion#]J Kthis8Pmodel8Pautor = Pattern//factory)#Autor#0 K(PR!D[#autor#].J Kthis8Pmodel8Prevista = )int.K(PR!D[#revista#]J Kthis8Pmodel8Psave).J WDDPWelper//go)\-biblioteca-articulo-listar\.J O

EL MTODO LISTAR
5no de los recursos ms simples de todos es listar# el cual es solicitado por la redirecci$n de los m*todos guardar).. )l recurso listar /en el controlador0# ya fue creado por )uropio =L- y no hizo falta modificar absolutamente nada. %olo fue necesario adaptar los m*todos en las vistas# para lo cual# los sustitu" vali*ndome del plug'in CollectorBie'er /del que habl* en la edici$n anterior0 y el resultado fue el siguiente,

# Archivo: appmodules'(i(lioteca'vie)s'autor*p p public function listar)Kcoleccion=array).. N # Solo si es d*inistr dor3 *uestr los botones edit r y eli*in r Kboton = )K(! !!IRC[#level#] == 3. + Drue / ;alseJ Ktabla = CollectorBie'er)Kcoleccion0 #biblioteca#0 #autor#0 Drue0 Kboton0 Kboton.8Pget(table).J print Demplate)#Autores#.8Psho')Ktabla.J O # Archivo: appmodules'(i(lioteca'vie)s'revista*p p public function listar)Kcoleccion=array).. N foreach)Kcoleccion as LKob1. N unset)Kob18Particulo(collection.J # )li*ino lo Fue no deseo *ostr r Krevista = \Dhe Rriginal WacFer\J unset)Kob18Pnumero.J # )li*ino lo Fue no deseo *ostr r O Kboton = )K(! !!IRC[#level#] == 3. + Drue / ;alseJ Ktabla = CollectorBie'er)Kcoleccion0 #biblioteca#0 #revista#0 Drue0 Kboton0 Kboton.8Pget(table).J print Demplate)\Colecci%n de 2evistas\.8Psho')Ktabla.J O # Archivo: appmodules'(i(lioteca'vie)s'articulo*p p public function listar)Kcoleccion=array).. N Kboton = )K(! !!IRC[#level#] == 3. + Drue / ;alseJ Ktabla = CollectorBie'er)Kcoleccion0 #biblioteca#0 #articulo#0 Drue0 Kboton0 Kboton.8Pget(table).J print Demplate)Ktitulo.8Psho')Ktabla.J O

RECURSOS FINALES: EDITAR Y ELIMINAR


Llegamos al final del &B4. )n el caso particular del recurso eliminar no tendremos que hacer nada# ya que se encuentra creado en los controladores de cada modelo /de ello se encarg$ la =L- de )uropio )ngine al momento de crear los archivos0. Guien nos dar un poco ms de trabajo es el recurso editar). el cul nos

2013 Eugenia Bahit www.eugeniabahit.com Bajo Licencia Creative Commons BY-NC-SA

The Original Hacker www.originalhacker.org

29

demandar# en algunos casos# hacer pequeas modificaciones en los controladores y# sin e(cepci$n alguna# sustituir todos los m*todos hom$nimos en las vistas. & continuaci$n# colocar* los c$digos organizados por pares de controladorLvista para cada modelo.

# Archivo: appmodules'(i(lioteca'vie)s'autor*p p # Autor no reFuiere c *bios en el control dor public function editar)Kob1=array).. N # )l ob$eto nos lo envE el control dor Kform = ne' Zeb;orm)#-biblioteca-autor-guardar#.J Kform8Padd(hidden)#id#0 Kob18Pautor(id.J # >ecesit *os l ?J en el for*ul rio Kform8Padd(text)#nombre#0 null0 Kob18Pnombre.J Kform8Padd(submit).J print Demplate)# ditar Autor#.8Psho')Kform8Psho')..J O # Archivo: appmodules'(i(lioteca'vie)s'revista*p p # 'evist no reFuiere c *bios en el control dor public function editar)Kob1=array).. N Kform = ne' Zeb;orm)#-biblioteca-revista-guardar#.J Kform8Padd(hidden)#id#0 Kob18Prevista(id.J Kform8Padd(text)#fecha#0 #;echa de publicaci%n#0 Kob18Pfecha.J Kform8Padd(text)#numero#0 #C&mero de edici%n#0 Kob18Pnumero.J Kform8Padd(submit).J print Demplate)# ditar 2evista#.8Psho')Kform8Psho')..J O # Archivo: appmodules'(i(lioteca'controllers'articulo*p p public function editar)Kid=4. N Kthis8Pmodel8Particulo(id = KidJ Kthis8Pmodel8Pget).J # Ar er colecci!n de utores Kcoleccion = CollectorRb1ect//get)#Autor#.J Kautores = Kcoleccion8PcollectionJ # Ar er colecci!n de revist s Kcoleccion = CollectorRb1ect//get)#2evista#.J Krevistas = Kcoleccion8PcollectionJ Kthis8Pvie'8Peditar)Kthis8Pmodel0 Kautores0 Krevistas.J O

&ntes de pasar a la vista de art"culo es necesario mencionar un pequeo hack que se me ocurri$ implementar para que al mostrar el select de autores y revistas# aparezca seleccionado por defecto el autor y revista asignado al art"culo que se est* editando. &nteriormente# se cre$ un m*todo privado llamado prepare(collection al que se le enviaba una colecci$n de objetos ms el nombre de la propiedad de la cual se e(traer"a el valor a mostrar en las opciones / option0 de la lista de desplegable /select0. &provech* este m*todo para incorporar la verificaci$n de la -3 del objeto contrastndola con cada una de las -3 de la colecci$n y decidir si la propiedad extras! tendr"a un valor vac"o /para no seleccionar nada0 o S selected# si se trataba de -ds coincidentes. )l resultado de dicha modificaci$n fue el siguiente /remarco los cambios en negritas a fin de que sea ms fcil implementarlos0,

2013 Eugenia Bahit www.eugeniabahit.com Bajo Licencia Creative Commons BY-NC-SA

The Original Hacker www.originalhacker.org

30

# "rc ivo$ appmodules'(i(lioteca'vie)s'articulo*p p # Kodific ci!n del *Dtodo priv do prep re-collection private function prepare(collection)LKcoleccion0 Ktext% 4i"=/. N Kidproperty = strtolo'er)get(class)Kcoleccion[4].. . \(id\J foreach)Kcoleccion as LKob1. N Kob18Pvalue = Kob18PKidpropertyJ Kob18Ptext = Kob18PKtextJ 4o2=>Bextras = (4o2=>B4i"property == 4i") F ' selecte"' : ''A O O
7or favor# notar que al tercer argumento /Kid0 le agregu* un valor por omisi$n /cero0 a fin de que no sea necesario realizar cambios a las llamadas previas a esta modificaci$n# dado que un valor de I" solo es requerido para los m*todos de edici$n pero no# para los recursos agregar.

6inalmente# el m*todo editar de la vista ArticuloBie'0 qued$ as",

# Archivo: appmodules'(i(lioteca'vie)s'articulo*p p public function editar)Kob10 Kautores0 Krevistas. N Kthis8Pprepare(collection)Kautores0 #nombre#0 Kob18Pautor8Pautor(id.J Kthis8Pprepare(collection)Krevistas0 #numero#0 Kob18Prevista.J Kform = ne' Zeb;orm)#-biblioteca-articulo-guardar#.J Kform8Padd(hidden)#id#0 Kob18Particulo(id.J Kform8Padd(text)#titulo#0 null0 Kob18Ptitulo.J Kform8Padd(text)#seccion#0 null0 Kob18Pseccion.J Kform8Padd(select)#autor#0 Kautores.J Kform8Padd(select)#revista#0 Krevistas.J Kform8Padd(submit).J print Demplate)# ditar Articulo#.8Psho')Kform8Psho')..J O

2013 Eugenia Bahit www.eugeniabahit.com Bajo Licencia Creative Commons BY-NC-SA

The Original Hacker www.originalhacker.org

31

SEGURIDAD INFORMTICA: CAPAS DE SEGURIDAD INTELIGENTES EN PHP SANEAMIENTO DEL ARRAY SUPERGLOBAL $_POST
LA
SIGUIENTE PUBLICACIN, CORRESPONDE A LOS RESULTADOS OBTENIDOS HASTA EL MOMENTO, SOBRE UNA INVESTIGACIN QUE ME ENCUENTRO REALIZANDO ACTUALMENTE, CUYO OBJETIVO ES HALLAR UNA FORMA INEQUVOCA DE SANEAR, FILTRAR Y LIMPIAR DATOS ENVIADOS POR HTTP POST, MEDIANTE UNA CAPA DE SEGURIDAD DE ACTIVACIN AUTOMTICA.

)
deben

n varias ediciones de la revista .acHers T 3evelopers 4agazine# he dado sugerencias alternativas para el saneamiento de los datos recibidos desde formularios. )n http,LLlibrary.originalhacHer.org se puede acceder a cada uno de los art"culos sobre el tema y descargarlos en formato 736. 7ero lo que hoy quiero mostrarles# no es en referencia a qu* datos filtrarse# qu* riesgos corremos a causa de cules vulnerabilidades conocidas ni qu* herramientas e(isten para prevenir estos problemas. .oy# quiero hablarles sobre una investiga)i/n 'ue vengo llevando a )a o en los ;ltimos meses# mediante la cual# vali(ndome de una )ara)ter+sti)a de $>$ que personalmente no logra convencerme . de las ra+)es m4s 4si)as de la inteligen)ia arti2i)ial# es posible )rear )apas de seguridad en nuestras aplicaciones# 'ue se a)tiven de 2orma autom4ti)a y 'ue sean )apa)es de re)ono)er el tipo de in2orma)i/n que el programador espera y sobre ese anlisis# procedan a limpiar! el arra! superglo#al K(PR!D de forma tal que al ser accedido por el programador# ya haya atravesado toda acci$n de saneamiento.

MUTABILIDAD DEL ARRAY $_POST


)n el prrafo anterior comentaba acerca de una caracter"stica de 7.7 que a+n no lograba convencerme. %in embargo# al final de este documento# probablemente termine reconociendo lo contrario 'o no'. %e trata de la )apa)idad muta le del array superglobal 4#P<SG.

2013 Eugenia Bahit www.eugeniabahit.com Bajo Licencia Creative Commons BY-NC-SA

The Original Hacker www.originalhacker.org

32

5no podr"a esperar que se tratase de una variable de solo lectura# pero no lo es. 3e hecho# 4#P<SG no alma)ena los datos en )rudo enviados mediante >""$ $?S" # sino que lo hace habi*ndolos tratado previamente. !n )laro e<emplo de esto8 es lo 'ue antiguamente su)ed+a )on los datos )uando las 2amosas )omillas m4gi)as se en)ontra an a)tivadas1 3e forma automtica# los datos enviados mediante .227 7@%2 llegaban al arra! superglo#al K(PR!D con las comillas dobles# simples# barras invertidas y valores nulos ya escapados con su barra invertida correspondiente. Netomando el caso de mutabilidad de este arra!# la misma nos permite# por ejemplo# agregar nuevas claves al arra!# como se muestra a continuaci$n,

K(PR!D[#esto(no(era(un(campo(del(form#] = #foo#J

9 como era de esperarse# tambi*n nos permite modificar un valor e(istente,

K(PR!D[#campo(del(form#] = htmlentities)K(PR!D[#campo(del(form#].J

)sta +ltima caracter"stica# es la que ms nos interesa. ?racias a esta falta de inmutabilidad del arra!# podremos hacer que est* disponible con los datos ya saneados.

AUTOMATIZACIN
7ara que el proceso de saneamiento que se lleve a cabo se active de forma automtica# *ste deber"a ser invocado desde un archivo com+n a toda la aplicaci$n# que siempre se encuentre disponible y que tenga relaci$n directa con esta capa. 7or ejemplo# una clase Demplate siempre podr"a estar disponible y sin embargo# no tendr"a ninguna relaci$n con una capa de seguridad. 3espu*s de mucho pensar# conclu" en que deb"a ser la propia capa de seguridad quien se active a s" misma. 3e esta forma# al momento de ser importada /por ejemplo# desde un settings0# ya estar"a actuando de forma natural. Jo obstante# tambi*n not* la necesidad de poder decidir la desactivaci$n de esta capa si fuese requerido sin tener que estar comentando o eliminando la l"nea de importanci$n. &s" fue que lo ms coherente# me pareci$ que ser"a definir una constante #ooleana en un archivo settings y dependiendo de su valor# se activara o no la capa.

DISPONIBILIDAD DE LOS DATOS ORIGINALES


La inteligencia artificial y la l$gica de negocio de una aplicaci$n# deben siempre estar al servicio de las personas y jams deber"a darse el caso contrario /aunque lamentablemente# se da en ms del R;< de las aplicaciones# pero eso# ya no es tema de debate en este art"culo0.

2013 Eugenia Bahit www.eugeniabahit.com Bajo Licencia Creative Commons BY-NC-SA

The Original Hacker www.originalhacker.org

33

3espu*s de probar m+ltiples alternativas# analizarlas una a una y descubrir que ninguna me terminaba de convencer# decid" recorrer la documentaci$n de 7.7 de punta a punta. 9a hab"a descartado el uso de la variable KWDDP(2AZ(PR!D("ADA puesto que depend"a del valor de la directiva al'ays(populate(ra'(post(data del archivo php.ini y realmente# me resultaba poco l$gico e inviable# tener que modificar esto para poder disponer de los datos .227 7@%2 puros. Leyendo sobre esta directiva# fue que la soluci$n lleg$ a mis manos, php:33inp!t# una envoltura de 2lu<o de solo le)tura. %in embargo# cabe destacar que php/--input cuenta con algunas restricciones interesantes# como por ejemplo# su no disponibilidad cuando el tipo de codificaci$n del formulario es declarado como multipart-form8data.

php://input NO FUNCIONA con enctype=multipart/form-data

7or favor# recordemos que el tipo de contenido multipart-form8data# es el que nos permite en un formulario# enviar grandes cantidades de datos sobre todo binarios y con codificaci$n diferente a &%=--. 7ara mayor informaci$n sobre este tema# recomiendo dirigirse a http,LLwww.wD.orgL2NLhtml>;:LinteractLforms.htmlUdid('multipartform'data y http,LLwww.ietf.orgLrfcLrfcCDRR.t(t. & pesar de todo lo anterior# esta soluci$n resulta la ms acertada posible. =uando php/--input no se encuentre disponible# habr"a que pensar entonces# en recurrir como +ltima alternativa# a la variable KWDDP(2AZ(PR!D("AD que podr"a tambi*n no estar disponible si la directiva al'ays(populate(ra'(post(data del archivo php.ini fuese ;alse.

(ara ser onesta, en ()( no e*iste una forma inequvoca % e*acta de poder recuperar los datos enviados a travs de )++( (,'+ sin previo tratamiento#
%i se quisiera trabajar con php/--input# deber"a hacerse mediante fopen y fgets como se muestra en el siguiente ejemplo,

Kfp = fopen)#php/--input#0 #r#.J 4"ata = fgets(4fp)A fclose)Kfp.J # Jonde l v ri ble Ld t 3 podrE foo=WolaMmundoE23Lbar=4.?> retorn r lgo co*o:

# )Fuiv lente h ber envi do por "BSA: foo = Wola mundo7 bar = 4.?>

2013 Eugenia Bahit www.eugeniabahit.com Bajo Licencia Creative Commons BY-NC-SA

The Original Hacker www.originalhacker.org

34

INTELIGENCIA ARTIFICIAL
7ara saber c$mo se deber"a filtrar cada uno de los campos y qu* filtros aplicar# podemos recurrir a las ra"ces ms bsicas de la inteligencia artificial, los diccionarios de nombres. 3e esta forma# podemos deducir que un campo que solicite un e'mail al usuario# podr"a tener como parte del nombre# la cadena mail!. &s"# campos llamados email!# mailVaddress! o repeatVemail! coincidir"an con la cadena mail!. La misma l$gica# podr"a aplicarse a otros tipos de campo,

IP U2$ Combre de usuario Contrase]a etc.

ip url0 uri0 site0 'eb uname0 username0 user0 usuario pass )coincidir[a adem^s con pass'd y pass'ord.0 p'd0 clave

=laro que esta l$gica no debe ser demasiado minuciosa. )s decir# la mayor"a de los campos sern campos de te(to /strings0 que no van a necesitar de comprobaciones de formatos especiales. 3e esta forma# creando diccionarios y aplicando a cada caso los filtros correspondientes# se podr"a abarcar un gran n+mero de posibilidades que podr"an sanear de forma predeterminada a decenas de miles de aplicaciones. *mplementa)i/n de la *A 9a en muchos documentos anteriores me dediqu* a hablar de los filtros que se deben aplicar en cada caso y en cada tipo de campo# as" que aqu" solo me concentrar* en poner en c$digo todo lo que e(pliqu* anteriormente referido a la -&. 3ado un diccionario como el siguiente,

Kdiccionarios = array) #e8mail# =P array)#mail#.0 #contrase]a# =P array)#pass#0 #clave#. .J

9 suponiendo un formulario con los siguientes campos y valores,

K(PR!D = array) #email(address# =P #fooGbar#0 #pass'd# =P #32<=>?#0 #pass'd2# =P #32<=>?# .J

)l siguiente algoritmo podr"a utilizarse para detectar a qu* tipo de dato se corresponder"a cada uno de los campos,

2013 Eugenia Bahit www.eugeniabahit.com Bajo Licencia Creative Commons BY-NC-SA

The Original Hacker www.originalhacker.org

35

foreach)K(PR!D as KFey=PKvalue. N foreach)Kdiccionarios as Ktipo=PKdiccionario. N foreach)Kdiccionario as Kentrada. N if)strpos)KFey0 Kentrada. 7== ;alse. N print \ l campo NKFeyO es de tipo NKtipoO\ . chr)34.J O O O O

@bteniendo un resultado como el siguiente,

l campo email(address es de tipo e8mail l campo pass'd es de tipo contrase]a l campo pass'd2 es de tipo contrase]a

Luego# basados en el tipo de campo# solo es cuesti$n de aplicar los filtros que correspondan en cada caso.

MS INFORMACIN
7ara conocer ms sobre filtros en 7.7# recomiendo leer las siguientes pginas del manual,
;unci%n filter(input/ http/--us<.php.net-manual-es-function.filter8input.php ;iltros disponibles/ http/--us<.php.net-manual-es-filter.filters.php ;unci%n strip(tags/ http/--us<.php.net-manual-es-function.strip8tags.php ;unci%n htmlentities/ http/--us<.php.net-manual-es-function.htmlentities.php ;unci%n htmlspecialchars/ http/--php.net-manual-es-function.htmlspecialchars.php

2
1311309459833
1311309459833

1 311309

459833

También podría gustarte