[Java] Buenas prácticas en programación


1.- Evitar la creación innecesaria de objetos, Lazy Initialitation

La creación de objetos en Java es una de las operaciones mas costosas en términos de uso de memoria e impacto en el performance.  Esto es evitable creando o inicializando objetos solo en el momento en que serán requeridos en el código.

Código: Java
  1. public class Paises {
  2.  
  3.     private List paises;
  4.  
  5.     public List getPaises() {
  6.         //se inicializa solo cuando es requerido
  7.         if(null == paises) {
  8.             paises = new ArrayList();
  9.         }
  10.         return paises;
  11.     }
  12. }


2.- Nunca hacer variables de instancia públicas

Hacer una clase publica se puede ocasionar problemas en un programa.  Por ejemplo si tienes una clase MiCalendario. Esta clase contiene un arreglo de cadenas diasDeLaSemana.  Pero es una arreglo público y este puede ser accedido por cualquiera.  Tu asumes que este arreglo contiene siempre los 7 nombres de los días de la semana.  Alguien por error puede cambiar el valor e insertar un error!

Código: Java
  1. public class MiCalendario {
  2.    
  3.     public String[] diasDeLaSemana =
  4.         {"Domingo", "Lunes", "Martes", "Miércoles", "Jueves", "Viernes", "Sábado"};
  5.    
  6.     //mas código
  7.    
  8. }


La mejor práctica es como mucho de ustedes saben, es siempre definir estas variables como privadas y crear los métodos accesores, “setters“ y “getters”

Código: Java
  1. private String[] diasDeLaSemana =
  2.     {"Domingo", "Lunes", "Martes", "Miercoles", "Jueves", "Sabado", "Domingo"};
  3.  
  4. public String[] getDiasDeLaSemana() {
  5.     return diasDeLaSemana;
  6. }


Pero escribir los métodos accesores no resuelve el problema del todo.  El arreglo sigue siendo accesible.  La mejor forma de hacerlo inmodificable es devolviendo un arreglo clonado en lugar del arreglo mismo.  Esto se logra modificando el método get de la siguiente forma.

Código: Java
  1. public String[] getDiasDeLaSemana() {
  2.     return diasDeLaSemana.clone();
  3. }


3.- Tratar siempre de minimizar la Mutabilidad de las clases

Hacer una clase inmutable es hacerla inmodificable.   La información de la clase se preservara durante el tiempo de vida de la clase.  Las clases inmutables son simples y fáciles de manejar.  Son “thread safe”.  Normalmente son los bloques para formar otros objetos mas grandes.

No obstante, crear objetos inmutables pueden golpear significativamente el rendimiento de una aplicación.  Así que elije cuidadosamente si quieres que una clase sea o no inmutable.  Trata siempre de tener clases pequeñas con el menor número de clases inmutables.

Para hacer una clase inmutable puedes definir sus constructor de forma privada y luego crear un método estático para inicializar al objeto y devolverlo.

Código: Java
  1. public class Empleado {
  2.  
  3.     private String primerNombre;
  4.     private String segundoNombre;
  5.    
  6.     // constructor private default
  7.     private Empleado (String primerNombre, String segundoNombre) {
  8.         this. primerNombre = primerNombre;
  9.         this. segundoNombre = segundoNombre;
  10.     }
  11.    
  12.     public static Empleado valueOf (String primerNombre, String segundoNombre) {
  13.         return new Empleado (primerNombre, segundoNombre);
  14.     }
  15. }


4.- Trata de usar mas las Interfaces sobre las Clases Abstractas

No es posible la herencia múltiple en Java, pero definitivamente puedes implementar múltiples interfaces.  Esto hace que cambiar la implementación de una clase existente sea fácil y que puedas implementar una o mas interfaces en lugar de cambiar la jerarquía completa de clases.

Pero si tu estás cien por ciento seguro de que métodos de una interface tendrás, entonces solo implementa esa interfaz.   Es bastante difícil agregar un nuevo método en una interfaz existente sin alterar todo el código que se está implementando.  Por el contrario un nuevo método puede ser fácilmente agregado en una clase abstracta sin alterar la funcionalidad existente.

5.- Limita siempre el alcance de una variable local

Las variables locales son grandiosas.  Pero algunas veces pueden insertar mas bugs durante el copiado y pegado de código viejo. Minimizar el alcance de una variable local hace que el código sea mas legible, menos propenso a errores  y mas mantenible.

Por lo tanto, debemos declarar variables justo antes de ser usadas.

Procura inicializar una variable desde su declaración.  Si eso no es posible asígnale el valor nulo.

6- Trata de usar librerías estándar en lugar de hacer las tuyas desde cero.

Escribir código es divertido.  Pero no reinventes la rueda.  Es bastante recomendable usar librerías estándar que ya han sido probadas, debugeadas y usadas por otros.    Esto no solo mejora la eficiencia de un programador sino que redice las posibilidades de tener errores en el código.  Además, usar una librería estándar  hace al código mas legible y mantenible.

Por ejemplo Google tiene liberada la nueva librería Google Collections que puede ser usada para agregar mas funcionalidad a tu código.

7.- Siempre que sea posible trata de usar tipos primitivos en lugar de las clases Wrapper

Las clases Wrapper son buenas, pero también son lentas.  Los tipos primitivos son como clases, sin embargo las clases wrapper almacenan la información completa acerca de una clase.

Algunas veces un programador puede agregar un error en el código usando una wrapper por un descuido.  Por ejemplo:

Código: Java
  1. int x = 10;
  2. int y = 10;
  3.  
  4. Integer x1 = new Integer(10);
  5. Integer y1 = new Integer(10);
  6.  
  7. System.out.println(x == y);
  8. System.out.println(x1 == y1);


El primer System.out.println imprimirá true mientras que el segundo imprimirá false.  El problema cuando comparas dos clases wrapper es que no se puede usar el operador ==, por que en realidad se están comparando referencias y no sus valores actuales.

Además si estás usando una clase wrapper no debes olvidar inicializarla.  Porque el valor por default de las variables wrapper es null.

Código: Java
  1. Boolean bandera = null;
  2.      
  3.         //mas código
  4.  
  5. if(flag == true) {
  6.     System.out.println("Se establece el valor de bandera ");
  7. } else {
  8.     System.out.println("No se establece el valor de bandera");
  9. }


El código lanzará un NullPointerException cuando se trate de comparar con true y el valor sea nulo si en el código intermedio no fue inicializada.

8.- Usa los Strings con mucho cuidado.

Usa siempre las cadenas con mucho cuidado en tu código.  Una simple concatenación de cadenas puede reducir el rendimiento de tu programa.  Por ejemplo si queremos concatenar cadenas usando el operador “+” en un ciclo for entonces todo el tiempo se estará creando un objeto String.  Esto afecta tanto a la memoria como al rendimiento.

Además en lugar de que instancies una objeto String no uses su constructor, sino que debes instanciarlo directamente. Por ejemplo:

Código: Java
  1. //instanciación lenta
  2. String lenta = new String("solo otro objeto string");
  3.  
  4. //instanciación rápida
  5. String rapida = "solo otro objeto string";


9.- Siempre regresa colecciones vacías en lugar de nulas

No importa que tu método regrese una colección o un arreglo, siempre asegúrate de que cuando sea necesario se regrese vacío y no nulo, en aquellos casos en los que no contendrá elementos porque la lógica de tu programa lo requiera.  Esto te ahorrará un montón de tiempo cuando hagas pruebas para valores nulos.

10.- El copiado defensivo es salvador

El copiado defensivo hace que los objetos creados estén libres de la mutación.  Por ejemplo en el código siguiente tenemos definida la clase Estudiante la cual a su vez tiene una variable con la fecha de nacimiento que es inicializada cuando el objeto es construido.

Código: Java
  1. public class Estudiante {
  2.     private Date fechaNacimiento;
  3.    
  4.     public Estudiante(fechaNacimiento) {
  5.         this. fechaNacimiento = fechaNacimiento;
  6.     }
  7.    
  8.     public Date getFechaNacimiento () {
  9.         return this.fechaNacimiento;
  10.     }
  11. }


Ahora podríamos tener el siguiente código que use al objeto Estudiante.

Código: Java
  1. public static void main(String []arg) {
  2.     Date fechaNacimiento = new Date();    
  3.     Estudiante estudiante = new Student(fechaNacimiento);
  4.     fechaNacimiento.setYear(2019);
  5.     System.out.println(estudiante.getFechaNacimiento ());
  6. }


En el código siguiente creamos tan solo al objeto Estudiante con algunas fechas de nacimiento por default.  Pero entonces cambiamos el valor de el año de nacimiento.  Después imprimimos el año de nacimiento, este año fue cambiado por 2019!

Para evitar estos casos, se puede utilizar el mecanismo defensivo copias. Cambie el constructor de la clase del estudiante a lo siguiente.

Código: Java
  1. public Estudiante(fechaNacimiento) {
  2.     this.fechaNacimiento = new Date(fechaNacimiento);
  3. }


Esto para asegurarnos de tener otra copia de la fecha de nacimiento que usamos en clase Estudiante.

11.-  Nunca dejes salir una excepción de un bloque finally

12.- Nunca lances "Exception" directamente.


Extraido de: viralpatel.net

XSS por POST


Hace unos días reportaron un XSS por POST en el formulario de contacto de Underc0de. Por suerte no era nada riesgoso, pero era una vulnerabilidad que debíamos arreglar.
En esta ocasión usaremos el código de ese formulario de contacto para reproducir la falla y para ver como probar si nuestras aplicaciones son vulnerables a los XSS por POST.

El código del formulario de contacto está acá: www.hospedando.com.mx/descargas/formulario.zip por si alguno desea realizar la prueba.

Además, necesitaremos alguna herramienta que modifique los parámetros que enviemos por POST. Yo usare Tamper Data que es un complemento de Firefox:

https://addons.mozilla.org/es/firefox/addon/tamper-data/

Una vez montado el formulario de contacto se vera algo así:



El primer paso será completar todos sus campos y abrie Tamper Data. Una vez hecho esto, damos en "Comenzar Modificación" (En el tamper data) y enviamos el formulario de contacto.
Seguido a esto, nos aparecerá una alerta en Tamper Data para modificar los datos que estamos enviados.


Damos en modificar, y revisamos los valores que está enviando del lado derecho, que son los que hemos cargado desde el formulario.


Ahora es momento de jugar con estos campos. Este formulario de contacto no filtra sus variables, asique colocaremos algún vector de XSS en sus parámetros.
En este caso, coloqué un simple alert en el campo correo.

<script>alert('XSS')</script>

Al dar en Aceptar, el sitio seguirá cargando con la nueva información suministrada...


Y como podrán apreciar, apareció el Alert con nuestro mensaje.

Espero que les sirva!

Ver el nombre de una red oculta


En este mini tutorial, les voy a enseñar a ver los nombres de las redes ocultas, que siempre es necesario saberlo tanto como para romper su password, como para conectarse.

Lo primero que debemos hacer, es poner nuestra interface en modo monitor. Explicaré brevemente este proceso, ya que lo he explicado varias veces en tutoriales previos.

1.- Identificamos el nombre de nuestra interface:

  1. airmon-ng

2.- La colocamos en modo monitor:

  1. airmon-ng wlan0 start

Lo mas probable, es que una vez hecho esto, su interface en modo monitor pase a llamarse mon0. En mi caso se llama wlan1, asique solo reemplacen el wlan1 por mon0 y listo.

El paso siguiente, es scannear y ver que redes hay disponibles. Para ellos utilizaremos el siguiente comando:

  1. airodump-ng wlan1

Y veremos algo como esto:


Como se ve en la captura, hay una red marcada en rojo llamada <length:    0>. Esta es nuestra red oculta. A su vez, con amarillo está resaltada su BSSID (MAC del Router).
Por otro lado, en la parte inferior, este BSSID vuelve a aparecer, y a su derecha aparece un STATION. Esto quiere decir, que hay un cliente conectado a ese router.
Cabe resaltar que para poder obtener el nombre de la red, debe haber alguien conectado. De lo contrario no se podrá.

Detenemos el scanneo presionando CTRL + C y colocamos el siguiente comando:

  1. airodump-ng -c 1 -w cap --bssid D8:5D:4C:C7:DC:EE wlan1

El parámetro del -c es el numero del canal. En este caso esta red está en el canal 1. Y en --bssid va la MAC del router.

Lo que hará esto, será escuchar solo a esa red incógnita.


Ahora en otra consola, pondremos lo siguiente:

  1. aireplay-ng -0 3 -a D8:5D:4C:C7:DC:EE -c 00:25:D3:4C:1B:84 wlan1

Este comando es el que se suele utilizar para sacar las claves WPA. En el parámetro -a pondremos la MAC del router y en el parámetro -C pondremos la MAC del cliente conectado.
Una vez hecho esto, aparecerá el nombre de la red oculta:


Espero que les sirva!

Wardriving con Android


Según Wikipedia:

Se llama wardriving a la búsqueda de redes inalámbricas Wi-Fi desde un vehículo en movimiento. Implica usar un coche o camioneta y un ordenador equipado con Wi-Fi, como un portátil o una PDA, para detectar las redes.


En este caso, yo les voy a enseñar a como realizar wardriving sin la necesidad de un coche y PC. Es decir, que por medio de un teléfono móvil con Android y caminar algunas cuadras, podremos tener el mismo resultado.
Lo que necesitaremos será instalar una aplicación llamada Wardrive, la cual pueden descargar desde la colección de aplicaciones de Underc0de

 


Una vez instalado, lo abrimos y veremos un mapa, el cual señala en donde estamos parados actualmente.
Lo que debemos hacer ahora, es comenzar a caminar por la calle, o si se prefiere en coche para alcanzar una cobertura aun mayor y la aplicación comenzara a dibujar la ruta que vamos haciendo con todas las redes inalámbricas que detecte. 


Si tocamos en la opción MAP MODE, la aplicación muestra al mapa con un poco más de detalle


Y si hacemos Zoom, podremos ver e identificar bien las casas que tienen Wifi.
Una vez que hayamos recorrido toda la zona, debemos exportar el mapa a KML (Keyhole Markup Language, lenguaje de marcas de Keyhole), KML es un formato de archivo que puede mostrar varios tipos de datos geográficos de nuevas formas. Para exportarlo, presionamos en el móvil el botón de menú y colocamos Exportar.


Y debemos seleccionar la opción KML para Google Earth


Una vez hecho esto, la aplicación guarda el archivo en la raíz del teléfono con el nombre wardrive.kml
Ahora solo debemos subir ese archivo a algún host, en mi caso lo he subido a 


Y lo colocamos en la url de Google Maps de la siguiente forma

 
Como se puede ver, la url llega hasta https://maps.google.com/maps?q= y le he añadido luego del igual la url en donde se encuentra el archivo KML. Esto nos dará como resultado el mapa con todas las redes inalámbricas capturadas.


También podemos hacer que filtre únicamente por las redes abiertas:


Otra de las cosas que se puede hacer, es seleccionar una sola red y ver bien de donde proviene:


En mi caso, esta red que he seleccionado, proviene de una escuela.


Post realizado por ANTRAX. Para saber más sobre Wardriving, haz click acá.



Grampus La herramienta ideal para los Pentesters y Forenses


Después de mucho tiempo de espera, al menos por parte del equipo de desarrollo, Grampus Beta sale a la luz.
Para los que desconozcan el proyecto, Grampus es una herramienta dirigida especialmente a analistas forenses y a pentesters en general.
La herramienta facilita la recopilación de información a traves de la extracción de metadatos de diferentes documentos y tareas de finger/foot printing

Características:
- Extracción de metadatos de documentos e imágenes, formatos soportados : Openoffice/Libreoffice, Office 2007, Office 2003, PDF, jpg, flv y gif.
- Eliminación de metadatos extraidos de diferentes documentos e imágenes.
- Tres tipos de Crawlers, entre los que se encuentra un crawler de documentos (por extensión) usando Google hacking.
- Para la tarea del fingerprinting contamos con un server banner y un escaneo mediante Shodan usando su api

Objetivos:
Como desarrolladores nuestro objetivo sería la implementación de nuevas tareas para la recopilación de información y el mantenimiento de los bugs que vayan saliendo.
Fuera de eso, queremos incentivar el desarrollo colectivo para que esta herramienta pueda ir automanteniendose y autorenovandose gracias a la colaboración de desarrolladores que usen la herramienta y así conseguir el objetivo común de una herramienta multiplataforma, estable y eficiente.

Download:
Acá dejo el enlace de nuestro grupo en bitbucket, donde podreis ir viendo los repositorios de los proyectos que vayamos iniciando:  https://bitbucket.org/grampusteam/
Descarga del Software: https://bitbucket.org/grampusteam/grampus/downloads/Grampus%20Beta.zip
User-guide: https://www.mediafire.com/view/ocz5j3hxex6br41/userguide_grampus.pdf

Este post fue realizado por Sanko en el foro. Para conocer mas sobre el proyecto, hacé click acá