Mostrando entradas con la etiqueta Informática. Mostrar todas las entradas
Mostrando entradas con la etiqueta Informática. Mostrar todas las entradas

martes, 12 de marzo de 2013

Liferay - actionURL, renderURL y resourceURL

Quienes han trabajado con Liferay saben de sobra que, al menos al principio, no es un camino de rosas. Ofrece tantas posibilidades que, en ocasiones, esto hace que uno no sepa cuáles elegir si nadie les guía un poco.

Para quien no sepa qué es Liferay, aquí dejo un enlace que explica, en términos generales, qué nos ofrece esta herramienta. Como la mayoría de la buena documentación, está en inglés, pero, ¿qué mejor explicación y guía que aquellas hechas por los propios creadores?

Probablemente acabe escribiendo una gran cantidad de entradas sobre esta herramienta, pero me parece conveniente comenzar con una aclaración de conceptos sobre tres elementos que podremos utilizar en nuestros ficheros JSP y que nos abrirán un sin fin de posibilidades. Hablamos de actionURL, renderURL y resourceURL.

actionURL

Este tag crea una URL que, al asociarse a un enlace HTML (tag <a>), permite la ejecución de un método definido la clase principal de nuestro portlet (aquella que hereda de la clase MVCPortlet) sin que se recargue la página en el navegador. 

Para hacer uso de esta herramienta, se debe añadir en nuestro código JSP el siguiente tag:

<liferay-portlet:actionURL name="metodoPortlet"></liferay-portlet:actionURL>

Esta URL se enlazará con el tag <a> de la siguiente forma: (esto es igual en los tres casos de los que se habla en esta entrada)

<a href="<%=metodoPortlet.toString()%>" /> Haz click aquí </a>

En la clase principal de nuestro portlet tendrá que encontrarse un método público con el mismo portlet que la URL (en este caso, metodoPortlet), el cual será llamado al hacer uso del enlace.

Es posible crear tantos pares de actionURL y métodos como sean necesarios, permitiendo, por ejemplo, la carga y muestra de datos al hacer click en un botón.

renderURL

Este tag ofrece dos posibilidades en función de si en su interior definimos o no un parámetro llamado "jspPage", cuyo valor debe ser la ruta de un fichero JSP.

Si no lo definimos, esta URL nos permitirá, al hacer click en un enlace, se vuelva a ejecutar el método doView() de nuestro portlet, heredado de la clase MVCPortlet, sin necesidad de recargar la página. Para ello, definiremos la URL de la siguiente manera, pudiendo añadir parámetros que se pasarán en método GET:

<liferay-portlet:renderURL var="testRenderURL">
</liferay-portlet:renderURL>
Si definimos el parámetro "jspPage", el funcionamiento será similar, pero cargará el fichero JSP al igual que el método include(). Se definirá, en este caso, del siguiente modo:

<liferay-portlet:renderURL var="testRenderURL">    <liferay-portlet:param name="jspPage" value="/html/portlet/test/test.jsp"/></liferay-portlet:renderURL> 

resourceURL

El funcionamiento de este tag es bastante similar al anterior, con dos excepcione. La primera es que en lugar de ejecutar el método doView(), ejecuta el método serverResource(), que es el recomendado para, por ejemplo, la carga de documentos PDF para visualizarlos en el navegador, entre muchos otros usos.

La segunda diferencia se debe a que no se recomienda cargar ficheros JSP en el método serverResource(), aunque es posible, por lo que no procesa automáticamente el fichero indicado en el parámetro "jspPage" (o, al menos, yo no he encontrado ningún ejemplo en el que ocurra así).

Este tag se define de la siguiente manera:

<portlet:resourceURL var="someUrl" id="veryImportantResource'" ></portlet:resourceURL>

Espero que tras leer esta entrada, al menos se entienda para qué sirve cada una de estas URLs. El resto ya es cuestión de imaginación. Seguro que con un poco de ingenio podréis sacarle un gran partido a estas tres herramientas con miles de posibilidades.

domingo, 10 de marzo de 2013

PHP - Evitar inyección SQL

Uno de los mayores riesgos que pueden aparecer a la hora de crear una página web que haga uso de Bases de Datos SQL es la inyección SQL. Esto se trata, en resumidas cuentas, de la posibilidad de poder forzar a la base de datos a devolver una respuesta que nos convenga para poder hacer un uso inapropiado del portal web.

Un ejemplo sería un formulario de inicio de sesión. En una página web en la que no controlamos este problema ¿qué ocurriría si en el campo usuario ponemos un nombre de usuario correcto y en la contraseña escribimos "' OR '1'='1'"? La respuesta es sencilla: es muy probable que tengamos acceso a la cuenta de ese usuario sin conocer su contraseña.

Ahora que ha quedado claro la gravedad del asunto, voy a poneros unos cuantos puntos a tener en cuenta a la hora de crear formularios que ataquen a nuestra base de datos que harán que, en casi la totalidad de los casos, sea imposible provocar la inyección SQL. 

Hay que mencionar que estos trucos son válidos para páginas web que hagan uso de PHP para atacar a Bases de Datos SQL. De no ser así, es posible que algunos de ellos no puedan ponerse en práctica.

  • Se debe utilizar siempre comillas simple a la hora de delimitar las variables que se vayan a utilizar directamente sobre la consulta a la Base de Datos. Esto hace que los intentos de inyección SQL que no hagan uso de comillas simples no tengan efecto sobre nuestro sistema. Ejemplo:
SELECT usuario FROM tabla_usuarios WHERE usuario= ' $usuario ';
  • Si en alguno de los campos del formulario esperas un tipo de datos concreto (un número, string, etc...), es recomendable hacer uso de la función de PHP gettype() antes de utilizar el dato que nos indica el usuario, ya que devuelve una ristra indicando su tipo.
  • Existe la posibilidad de comprobar si nuestro servidor cambia automáticamente las ristras pasadas por formulario o por URL para evitar la inyección SQL. Esto se puede averiguar ejecutando el siguiente código:
<?if(!isset($_GET["inyeccion"])){ header("location: ?inyeccion='");} else { echo 'Tu servidor '; if($_GET["inyeccion"] != "'")echo 'no '; echo 'tiene problemas de inyección';}?>

  • En caso de que se haya mostrado el mensaje "Tu servidor tiene problemas de inyección", se debería filtrar cada una de las variables obtenidas por formulario o URL haciendo uso del siguiente código, encargado de, por ejemplo, cambiar los caracteres ' por \':
<?// Se filtran las variables pasadas por URL
foreach($_GET as $var=>$valor){   $_GET[$var] = str_replace("'","\'",$_GET[$var]);}// Se filtran las variables pasadas por formularioforeach($_POST as $var=>$valor){   $_POST[$var] = str_replace("'","\'",$_POST[$var]);}?>

  • Se recomienda no hacer uso del operador * en queries SQL, sino indicar explícitamente aquellos campos que se quieren recuperar en la llamada. De este modo, además de evitar que los usuarios del portal puedan acceder a datos que no deberían conocer, hará que la llamada a la Base de Datos sea más óptima y rápida.
  • Hacer uso del usuario root es muy peligroso y debe hacerse con mucha precaución. Si nuestros usuarios de la página sólo van a tener acceso a la visualización de determinadas tablas de nuestra Base de Datos, es recomendable crearles un usuario en nuestro esquema con los permisos correspondientes.
  • Hay que tener mucho cuidado con controlar los mensajes de error que se muestran en el portal. Por defecto, si ocurre algún error al realizar la llamada a la Base de Datos, se muestran mensajes en la parte superior que pueden contener más información de la que los usuarios deberían obtener, además de evidenciar que algo no va bien en nuestro portal. Es por eso que, cuando se vaya a abrir el portal al público, incluyamos siempre una llamada a la función de PHP error_reporting(0), que evita que aparezcan estos mensajes.
  • Por si todo esto no fuera suficiente, existe otra funcion PHP que evitará la inyección SQL. Se trata de mysql_real_scape_string, una función que se está quedando obsoleta (tengo que informarme sobre las nuevas incluidas en las últimas versiones de PHP), a la cual se le pasa una variable y la formatea para evitar problemas por inyección.
Como se ve, evitar la inyección SQL es bastante sencillo si se sigue una serie de pasos que acabarán convirtiéndose en una rutina cuando programemos.

Espero que os sea útil y recordad, toda duda o comentario constructivo es bien recibido y lo contestaré tan pronto como me sea posible.

El comienzo

Los comienzos nunca son fáciles, y más aún cuando se trata de un amante tan exigente como puede llegar a ser un blog, es por eso que este he decidido tomármelo con calma para no repetir errores pasados.

También es cierto que este blog es de un ámbito bastante distinto a los que he escrito en otras ocasiones, ya que se trata de, como bien su nombre indica, un blog de notas. En mi profesión, la informática, gran parte del tiempo del trabajo se pasa investigando y buscando soluciones para problemas que te encuentras día tras día y es por eso que es habitual tener que tomar cientos de notas para no olvidar los pasos a seguir, por si el mismo problema volviera a aparecer.

¿Y qué ocurre cuando llevas cierto tiempo trabajando de esta forma? Pues muy sencillo: tus notas son un caos tal que no encuentras nada de lo que buscas aunque sabes que está ahí. Y es ese el momento en el que, ordenando tus libretas y post-its, piensas: ¿y si comparto estas cosas con aquél al que le pueda interesar? Probablemente no sean muchos los interesados, pero quizás pueda hacer que alguien se ahorre parte de su tiempo navegando en búsqueda de una solución a algún problema.

Así nace Mi Blog de Notas, como un blog en el que escribiré trucos, tutoriales o pasos a seguir para solucionar algunos problemas con los que me he topado.

Debe quedar claro que en ningún momento mostraré ningún contenido que pueda violar la confidencialidad a la que estoy comprometido por mi trabajo, por lo que, si en alguna ocasión muestro algún fragmento de código o algún documento, no se tratará de datos extraídos de los proyectos en los que trabajo o he trabajado, sino de alguna muestra para aclarar conceptos.

Pues sin más, comenzamos. No duden en escribir si hay cuestiones que no queden claras o si conocen alguna alternativa a mis entradas. Siempre que sean comentarios constructivos, serán más que bien recibidos.