Joven hacker sonriendo

Hackeamos su software

cero falsos positivos

Inteligencia experta + Tecnología especializada
DXST - SAST - IAST - SCA - DevSecOps
Caja blanca - Caja gris - Caja negra
Atacando Aplicaciones Web, APIs, Apps Móviles,
Cliente Servidor, Servidores, Redes, Dispositivos IoT
IoT SCI: Sistemas de Control Industrial

Definir Character-Set Content-Type en Servlets

Nuestros ethical hackers explican cómo evitar vulnerabilidades de seguridad mediante la programación segura en Java al definir los parámetros Charset y Content-Type. Éstos parámetros permiten definir el conjunto de caracteres utilizados por el navegador y ayudan a prevenir el XSS.

Necesidad

Definir Character-Set y Content-Type explícito en servlets para Java EE.

Contexto

A continuación se describen las circunstancias bajo las cuales la siguiente solución tiene sentido:

  1. Se está desarrollando una aplicación web usando la tecnología de servlets de Java.

  2. Se dispone de un contenedor de servlets.

Solución

La codificación de carácteres, character encoding, o charset es el método que permite convertir un carácter de una lengua natural (español, inglés, francés, italiano, entre otros), en un símbolo de otro sistema de representación (números, secuencia de comandos, lenguaje máquina). Básicamente, definen la forma en la que se codifica un carácter dado en un símbolo en otro sistema de representación [1].

Por su parte, el Content-Type es un encabezado que especifica el tipo de contenido de una petición HTTP. Entonces, el Content-Type sirve para decirle al servidor la manera en que determinada secuencia de carácteres se mostrará en el navegador del cliente.

Aunque el charset no es obligatorio, se debería incluir en cualquier página web para indicar de forma expresa la codificación de carácteres utilizada.

En esta solución se abordará la manera de definir el charset content-type en una página usando servlets.

  1. Para evitar que el navegador web tenga que adivinar el conjunto de caracteres usados, se recomienda especificarlo directamente en especial para archivos que son generados dinámicamente.

  2. Las consecuencias de no usar un Char-set específico pueden resultar en vulnerabilidades tipo XSS [2].

  3. Dentro del directorio para despliegue de las aplicaciones webapps, se debe crear la siguiente estructura de directorios.

    webapps.bash
    1
    2
    3
    4
    5
    6
    7
    8
    9
    % ls -R
    .:
    WEB-INF/
    ./WEB-INF:
    classes/ web.xml
    ./WEB-INF/classes:
    test/
    ./WEB-INF/classes/test:
    TestServlet.java
    
  4. Descriptor de despliegue web.xml. define cuales servlets existen mediante <servlet-name> y que clase lo representa usando <servletclass>.

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    <?xml version="1.0" encoding="UTF-8"?>
      <web-app id="tomcat-demo" version="2.4"
        xmlns="http://java.sun.com/xml/ns/j2ee"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
        http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
      <servlet>
        <servlet-name>TestServlet</servlet-name>
        <servlet-class>test.TestServlet</servlet-class>
      </servlet>
    
  5. Luego se indica ante cuales URLs deberá responder el servlet.

    1
    2
    3
    4
    5
      <servlet-mapping>
        <servlet-name>TestServlet</servlet-name>
        <url-pattern>/test</url-pattern>
      </servlet-mapping>
    </web-app>
    
  6. El código del servlet se escribe en TestServlet.java, donde para asignar el Char-set deseado se usa el método setContentType del objeto response. Se recomienda definir también el tipo de contenido simultáneamente.

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    package test;
    
    import java.io.*;
    import javax.servlet.*;
    import javax.servlet.http.*;
    
    public class TestServlet extends HttpServlet {
      public void doGet(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
          response.setContentType("text/html; charset=ISO-8859-1");
          PrintWriter out = response.getWriter();
          out.println("Prueba");
        }
    }
    
  7. Para compilar el servlet, dado que el API de servlets no es parte del JDK estándar, se debe usar un JAR que contenga los paquetes necesarios. Por ejemplo, el contenedor de servlets tomcat los provee en su carpeta lib, así que para compilar usando ese JAR como parte del classpath se ejecutaría.

    1
    % javac -cp ".:/usr/share/tomcat7/lib/servlet-api.jar" test/TestServlet.java
    
  8. Algunos contenedores de servlets se deben detener e iniciar nuevamente antes de que reconozcan los nuevos servlets, aunque si es solo modificación y recompilación de servlets existentes, no debería ser necesario. En tomcat, por ejemplo, la configuración que lo permite es modificando el archivo conf/context.xml para afectar a todas las aplicaciones, o si es específico para una aplicación, se deberá utilizar el META-INF/context.xml de esta.

    1
    2
    3
    4
    5
    6
    7
    <?xml version='1.0' encoding='utf-8'?>
      <!-- The contents of this file will be loaded for each web application -->
      <Context reloadable="true">
        <!-- Default set of monitored resources -->
        <WatchedResource>WEB-INF/web.xml</WatchedResource>
        <WatchedResource>WEB-INF/classes</WatchedResource>
      </Context>
    
  9. Para detectar errores durante el desarrollo, se recomienda revisar los archivos de logs del contenedor de servlets. En Linux, una forma de ver como cambia dinámicamente el final de un archivo es empleando el comando tail con el parámetro f:

    1
    log/tomcat7 % tail -f catalina.out
    



Haz un comentario

Estado de los servicios - Términos de Uso