Nota
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Web para Windows 8: integrada
Hace años, pensé que sería una buena idea aprender a jugar golf. Antes de inscribirme para unas lecciones en el campo local, nunca había tomado un palo de golf. En mi primera lección, el instructor me preguntó si había tomado lecciones antes o si había intentado jugar golf. Cuando le dije que no, me contestó "¡Muy bien! No tendremos que quitarle malos hábitos que entorpezcan su swing".
Los desarrolladores web que hacen una transición de aplicaciones desde el explorador hasta Windows Store traen consigo ciertos hábitos. Si bien los desarrolladores web pueden recurrir a su conocimiento previo de JavaScript, algunas capacidades son nuevas y exigen un cambio de actitud. La seguridad es uno de esas diferencias fundamentales. Muchos desarrolladores web tienen el hábito de delegar las aplicaciones de seguridad fuera del servidor debido a razones tales como "¿Para qué molestarse? Es fácil vulnerar JavaScript". En el lado del cliente web, las características de seguridad se consideran como una mejora en el uso que no agrega valor a la seguridad general de la aplicación web.
Con Windows 8, JavaScript juega un rol importante en la seguridad general de su aplicación al proporcionar las herramientas necesarias para asegurar datos, validar entradas y separar contenido potencialmente malintencionado. En este artículo, mostraré cómo se puede ajustar algunos de los hábitos del desarrollo web de manera que pueda producir aplicaciones de la Tienda Windows más seguras usando HTML5, JavaScript y las características de seguridad de Windows en tiempo de ejecución.
Validación de la entrada
El desarrollador web dice: la validación de JavaScript es para mejorar su uso, no contribuye a la seguridad de la aplicación.
El desarrollador de Windows 8 dice: la validación con HTML5 y JavaScript es la primera línea de defensa contra contenido malintencionado que intente introducirse en su aplicación.
Para aplicaciones web tradicionales, JavaScript frecuentemente es solo una puerta de enlace al servidor. Todas las acciones importantes con los datos, como la validación de entrada y el almacenamiento, ocurren en el servidor. Los atacantes malintencionados pueden deshabilitar JavaScript en sus exploradores o de forma directa al enviar solicitudes HTTP hechas a mano para omitir cualquier protección del lado del cliente. En una aplicación de la Tienda de Windows, el desarrollador no puede respaldarse en una entrada de usuario limpia antes de actuar sobre los datos, pues no hay servidor. En lo referente a la validación de entrada, JavaScript y HTML5 van por su cuenta.
En el ámbito de la seguridad de software, la validación de entrada es un componente crítico para la integridad de datos. Sin ella, los atacantes pueden usar cualquier campo de entrada como un posible vector de ataque dentro de la aplicación Tienda de Windows. En la segunda edición de "Writing Secure Code" (Microsoft Press, 2003), los autores Michael Howard y Steve Lipner proporcionan lo que hoy es un mantra en la administración de entrada: "Toda entrada es malévola hasta que se compruebe lo contrario".
No debe confiar en los datos hasta que se compruebe que corresponden a datos de "origen conocido". Al crear una aplicación, el desarrollador conoce la apariencia que debiesen tener los datos de un campo específico (es decir, una lista de elementos permitidos) o, por lo menos, lo que no debiese tener (es decir, una lista de elementos denegados). En el mundo de la validación de entradas, siempre use una lista de permitidos cuando sea posible para restringir la entrada a datos correctos con pruebas. Al permitir solo datos que sabe que son buenos, reduce la posibilidad de perder algunos nuevos o de encontrarse maneras desconocidas de representar datos incorrectos.
Limitar, rechazar y sanitizar
¿Cómo es que los desarrolladores reducen los riesgos de sus usuarios al limitar la entrada a datos correctos conocidos? Usan las tres etapas de validación de entrada que se muestran en la Figura 1 para reducir el riesgo de que se introduzca contenido malintencionado en su aplicación.
Figura 1 Validación de entrada (imagen basada en la Figura 4.4 del capítulo 4, "Directrices de diseño para aplicaciones web seguras" de "Mejora de seguridad de aplicación web: amenazas y medidas" enbit.ly/emYI5A)
La validación de entrada comienza al limitar los datos a los "correctos conocidos". Los desarrolladores web familiarizados con HTML5 pueden usar su conocimiento existente de sus nuevos tipos de entrada y de atributos para limitar los datos que proceden de las aplicaciones de Windows Store. La diferencia fundamental entre la web y Windows 8 es que la aplicación de Tienda de Windows no tiene un servidor detrás del escenario que revise la entrada. La limitación de datos debe ocurrir en HTML5 o en JavaScript.
Mediante HTML5, cada campo se puede limitar a datos correctos conocidos. Para ilustrar ejemplos en este artículo, usaré la aplicación ficticia Contoso Health, la cual almacena información de salud personal para los usuarios. La página Perfil de esta aplicación captura el nombre de usuario, dirección de correo electrónico, peso y estatura y proporciona un campo de notas de información general. Como desarrollador, yo sé (en general) qué aspecto debiesen tener los datos correctos para cada uno de estos campos:
- Nombre: Caracteres alfabéticos con unos pocos caracteres especiales que no deben superar los 45 caracteres en total. El criterio de los nombres se estructura en base del mercado objetivo de la aplicación, el mercado estadounidense.
- Dirección de correo electrónico: La entrada debe ser una dirección de correo electrónico en un formato válido.
- Peso y estatura: nombres con etiquetas asociadas para mostrar datos que están en pies y pulgadas y en libras.
- Notas: Contenido HTML que usa el editor estándar Contoso HTML.
Para el elemento de entrada Nombre, debo limitar los caracteres que son válidos para el campo, además de la extensión máxima del valor. Puedo hacer esto usando dos nuevos atributos en la etiqueta de entrada: patrón y título.
Un patrón es una expresión regular a la cual los datos deben ajustarse. MSHTML (el motor de representación usado para aplicaciones HTML5 en Windows 8) comprueba que los datos introducidos en los campos coincidan con la expresión regular. Si el usuario introduce datos que no se ajustan al patrón de expresión regular, habrá un error en el envío del formulario y el usuario será conducido a corregir el campo no válido. Por ejemplo, el campo Nombre se puede componer de caracteres alfa y espacios y debe tener entre tres a 45 caracteres de largo. El siguiente valor de patrón es compatible con esto:
<input type="text" id="txtName" name="txtName"
pattern="^[A-Za-z ]{3,45}$" title="" />
El título se usa para informar al usuario qué está esperando el sistema. En este caso, algo como "El nombre debe tener entre tres a 45 caracteres y usar caracteres alfabéticos o espacios" explicaría el patrón esperado. Nada es más frustrante para los usuarios que toparse con una entrada no válida sin saber cuáles son los requisitos para una entrada válida. Sea amable con sus usuarios y permítales saber qué está permitido. El atributo título hace exactamente eso, es el mensaje explicativo que muestra lo esperado en el campo.
Los patrones de los campos de datos, lo cual incluye caracteres aceptables y largo, puede ser difícil de determinar. Puede encontrar expresiones regulares de muestra en muchos fantásticos recursos en línea, pero siempre consulte al equipo de seguridad de su organización para ver si hay un estándar al cual debe adecuarse. Si no tiene un equipo de seguridad o si su equipo de seguridad no tiene estándares, los recursos tales como RegExLib.com proporcionan una excelente biblioteca de expresiones regulares que puede usar para sus validaciones de datos.
Algunos campos son tipos de datos específicos, como números, fechas y direcciones de correo electrónico. HTML5 llega al rescate de nuevo con un ejército de nuevos tipos de entrada, como correo electrónico, teléfono, fecha, número y muchos más. Usando esos tipos de entrada de datos, MSHTML comprueba si el usuario escribió datos válidos, sin necesidad de ninguna expresión regular o código de JavaScript. El tipo de atributo del elemento de entrada controla los nuevos tipos de datos. (Puede encontrar más tipos de información y sus usos en bit.ly/OH1xFf). Por ejemplo, para capturar una dirección de correo electrónico de la página Perfil, configuraría el tipo de atributo como correo electrónico, como se indica en el siguiente ejemplo:
<input type="email" id="txtEmail" name="txtEmail" />
Este campo acepta un valor solamente si se ajusta al formato de una dirección de correo electrónico válido. Si MSHTML no reconoce la entrada como una dirección de correo electrónico válido, se mostrará un error de validación en el campo cuando el usuario intente enviar el formulario. Usando los nuevos tipos de entrada de HTML5 se limitan los datos a lo que está esperando sin tener que hacerse cargo del lío de la validación compleja de JavaScript.
Algunos de los nuevos tipos de entrada también permiten restricciones de intervalo usando los atributos nuevos min y max. Como un ejemplo, a causa de las reglas comerciales, la gente de nuestra aplicación debe tener una alto entre 3 y 8 pies. Se puede usar la siguiente restricción de intervalo en el campo alto:
<input type="number" id="txtHeight" name="txtHeight" min="3" max="8" />
Los ejemplos proporcionados usan las cuatro técnicas para limitar los datos con la etiqueta de entrada HTML5. Al validar el largo (usar un patrón), formato (nuevamente, usando un patrón), tipo de datos (usando los nuevos tipos de entrada) y alcance (usando min/max) puede limitar los datos solo a datos correctos conocidos. No todos los atributos y tipos le solicitan corregirlos previamente al envío. Asegúrese de validar los contenidos de su formulario con el método checkValidity (bit.ly/SgNgnA), tal como lo haría con Page.IsValid en ASP.NET. Puede que se esté preguntando si se puede limitar datos de esta manera solo usando JavaScript. Sí, se puede, pero al usar los atributos de HTML5 se reduce el código general que el desarrollador necesita administrar para controlar todo el trabajo que debe hacerse sobre el motor MSHTML.
Rechazar implica denegar las entradas conocidas incorrectas (es decir, es una lista de denegación). Un buen ejemplo de rechazo es crear una lista de denegación de direcciones IP que no se pueden conectar a su aplicación web. Las listas de denegación son útiles cuando tiene un alcance más bien delimitado de lo que desea bloquear. Como ejemplo, considere enviar correos electrónicos a un grupo, como a su equipo de desarrollo y después eliminar a individuos específicos de la lista de correo electrónico del equipo de desarrollo. En este caso, usted sabe cuales direcciones de correo electrónico desea denegar en la lista del equipo de desarrollo. Por razones de software, deseará enfocarse en delimitar (una lista de aceptación) en lugar de rechazar (una lista de denegación). Siempre tenga en cuenta que los datos incorrectos conocidos cambian de forma constante a medida que los atacantes se vuelven más y más creativos para evadir las defensas de software. En el ejemplo anterior, imagine que se unen nuevos desarrolladores al equipo de desarrollo y necesita investigar si se deben incluir en un correo electrónico. Las limitaciones son mucho más sencillas de administrar a la larga y proporcionan una lista que se puede mantener mejor, en oposición a los miles de elementos presentes en una lista de denegación.
Algunas veces, los datos contienen datos buenos conocidos y malos conocidos. Un ejemplo de esto es el contenido HTML. Algunas de las etiquetas están aprobadas, de manera que se mostrarán, mientras que otras no lo harán. El proceso de filtración o de deshabilitación de los datos incorrectos conocidos y de aceptación de datos aprobados se conoce como sanitizar la entrada. El campo notas en la aplicación Contoso Health es un excelente ejemplo de esto. Los usuarios pueden escribir etiquetas HTML a través de un editor HTML, pero solo ciertas etiquetas HTML se representan cuando la entrada se muestra en la aplicación. La sanitización de entrada toma datos que pudiesen ser malintencionados y los hace seguros al despojarlos de contenidos no seguros y al hacer que quede inerte lo que no se aprobó explícitamente. Las aplicaciones de la Tienda Windows pueden hacer esto si establece el valor de un elemento HTML usando innerText (en lugar de innerHTML), el cual representa el contenido HTML como texto en lugar de interpretarlo como HTML. (Observe que si la aplicación establece el innerText de una etiqueta de script para JavaScript, se genera un script ejecutable). JavaScript también proporciona otra herramienta útil de sanitización: toStaticHTML.
Este es un ejemplo de código del controlador btnSave_Click, de la página de Perfil:
function btnSave_Click(args) {
var taintedNotes = document.getElementById("txtNotes").value;
var sanitizedNotes = window.toStaticHTML(taintedNotes);
document.getElementById("output").innerHTML = sanitizedNotes;
}
Si el usuario introduce el subproceso
<strong>testing!</strong><script>alert("123! ");</script>
a txtNotes, el método window.toStaticHTML lo despojará de la etiqueta de script y dejará solo la etiqueta strong (negrita) aprobada. Usar toStaticHTML retira cualquier etiqueta que no esté en la lista segura de aprobados (otro ejemplo de usar una lista de aceptación), además de cualquier atributo desconocido. Solo los datos correctos conocidos se mantienen en la salida del método toStaticHTML. Puede encontrar una lista completa de etiquetas, atributos, reglas CSS y propiedades aprobados en bit.ly/KNnjpF.
La validación de entrada reduce el riesgo de que entre contenido malintencionado al sistema. Al usar HTML5 y toStaticHTML, la aplicación puede restringir la entrada a datos correctos conocidos y eliminar o deshabilitar contenido posiblemente malintencionado sin intervención del servidor.
Ahora que Contoso Health recibe datos válidos, ¿qué vamos a hacer con datos confidenciales como información médica o financiera?
Almacenamiento de datos confidenciales
El desarrollador web dice: nunca almacene datos confidenciales en el cliente, puesto que no hay almacenamiento seguro disponible.
El desarrollador de Windows 8 dice: los datos confidenciales se pueden cifrar y almacenar de forma segura a través del tiempo de ejecución de Windows en tiempo de ejecución.
En la sección pasada, la aplicación Contoso Health recuperó información de perfil general. A medida que el desarrollo continúa, el patrocinador comercial solicita un formulario de historia clínica. Este formulario recopila los eventos médicos que ocurrieron a lo largo de la vida de un usuario, tales como la visita al médico más reciente. Las reglas antiguas de desarrollo web indican que almacenar información sensible, tal como un historial clínico de un usuario en el lado del cliente, es una mala idea, debido a la posibilidad de exposición de los datos. En el desarrollo de aplicaciones de la Tienda de Windows, los datos sensibles se pueden almacenar localmente usando las características de seguridad de Windows en tiempo de ejecución.
Para proteger el historial clínico del usuario, Contoso Health usa la API de protección de datos de WinRT. El cifrado no debiera ser la única parte de su estrategia de protección de datos (piense en defensa por profundidad: capas de seguridad en lugar de una sola defensa, tal como usar solo cifrado). No olvide otras prácticas recomendadas relacionadas a datos confidenciales, tales como obtener acceso a los datos solo cuando sea necesario y mantener los datos confidenciales fuera de la memoria caché. Un gran recurso que enumera muchas reflexiones acerca de los datos confidenciales es el artículo de la biblioteca MSDN "Mejora de la seguridad de aplicación web: amenazas y medidas" (bit.ly/NuUe6w). Si bien este documento se enfoca en las prácticas recomendadas de desarrollo, proporciona una base de conocimientos excelente que puede aplicar a cualquier tipo de desarrollo.
La página Historial clínico de la aplicación Contoso Health tiene un botón denominado btnAddItem. Cuando el usuario hace clic en el btnAddItem, la aplicación cifra los datos introducidos en el formulario Historial clínico. Para cifrar la información del historial clínico, la aplicación usa la APU de protección de datos WinRT integrada. Este sencillo sistema de cifrado ayuda a los desarrolladores a cifrar datos rápidamente sin la sobrecarga de la administración de claves. Comience con un controlador de evento vacío para el evento de clic btnAddItem. Después, Contoso Health recopilará la información del formulario y la almacenará en un objeto JSON. Dentro del controlador del evento, agregaré el código para crear rápidamente el objeto JSON:
var healthItem = {
"prop1": window.toStaticHTML(document.getElementById("txt1").value),
"prop2": window.toStaticHTML(document.getElementById("txt2").value)
};
El objeto healthItem representa el registro de historial clínico que el usuario introdujo al formulario. El cifrado de healthItem comienza con la instanciación de DataProtectionProvider:
var dataProtectionProvider =
Windows.Security.Cryptography.DataProtection.DataProtectionProvider(
"LOCAL=user");
El constructor DataProtectionProvider (para cifrado) toma un argumento de subproceso que determina a qué está asociada la protección de datos. En este caso, cifraré el contenido al usuario local. En lugar de configurarlo en el usuario local, podría configurarlo en la máquina, un conjunto de credenciales web, un principio de seguridad de Active Directory o algunas otras opciones. Puede encontrar una lista de opciones de descripción de protección en el tema del centro de desarrollo "Descriptores de protección" (bit.ly/QONGdG). El descriptor de protección que use depende de sus requisitos de aplicación. Hasta este punto, el proveedor de protección de datos está listo para cifrar los datos, pero los datos necesitan un pequeño cambio. Los algoritmos de cifrado funcionan con los búferes, no JSON, de manera que el siguiente paso es utilizar healthItem como búfer:
var buffer =
Windows.Security.Cryptography.CryptographicBuffer.convertStringToBinary(
JSON.stringify(healthItem),
Windows.Security.Cryptography.BinaryStringEncoding.utf8);
CryptographicBuffer tiene muchos objetos y métodos que pueden funcionar con búferes usados en cifrado y descifrado. El primero de estos métodos es convertStringToBinary, el cual toma un subproceso (en este caso, la versión de subproceso del objeto JSON) y lo convierte en un búfer codificado. La codificación usada se establece en el objeto Windows.Security.Cryptography.BinaryStringEncoding. En este ejemplo, uso UTF8 como el cifrado para mis datos. El método convertStringToBinary regresa un búfer en base de los datos del subproceso y la codificación especificada. Con el búfer listo para cifrarlo y la instanciación del proveedor de protección de datos, estoy listo para llamar al método protectAsync para cifrar el búfer:
dataProtectionProvider.protectAsync(buffer).then(
function (encryptedBuffer) {
SaveBufferToFile(encryptedBuffer);
});
El argumento encryptedBuffer es la salida del método protectAsync y contiene la versión cifrada del búfer. En otras palabras, estos son los datos cifrados listos para almacenamiento. Desde aquí, encryptedBuffer se pasa al método SaveBufferToFile, el cual escribe los datos cifrados a un archivo en la carpeta local de la aplicación.
El cifrado de healthItem se reduce a tres líneas de código:
- Instanciar el proveedor de protección de datos.
- Convertir los datos a un búfer.
- Llamar a protectAsync para cifrar los datos.
El cifrado de datos es así de simple. Los únicos cambios son usar un constructor vacío para DataProtectionProvider y usar el método unprotectAsync en lugar del método protectAsync. El método GetBufferFromFile carga la variable encryptedBuffer desde el archivo creado en el método SaveBufferToFile:
function btnLoadItem_Click(args) {
var dataProtectionProvider =
Windows.Security.Cryptography.DataProtection.DataProtectionProvider();
var encryptedBuffer = GetBufferFromFile();
dataProtectionProvider.unprotectAsync(encryptedBuffer).then(
function (decryptedBuffer) {
// TODO: Work with decrypted data
});
}
¿Pueden los desarrolladores usar cifrado con JavaScript que no sea WinRT? Sí, definitivamente. ¿Es tan sencillo como usar tres líneas de código que proporcionan excelente protección de datos? No. Hay varios desafíos para las prácticas recomendadas de cifrado en el explorador, tales como mantener la clave secreta efectivamente secreta, además de administrar el tamaño de archivo de los algoritmos necesarios para tener cifrado de calidad. La API de protección de datos de WinRT, además de otras herramientas de criptografía usadas por en espacio de nombre Windows.Security.Cryptography simplifican la protección de sus datos. Usando las características de seguridad de Windows en tiempo de ejecución, los desarrolladores pueden almacenar datos confidenciales con confianza, al mismo tiempo que hacen que las claves criptográficas sean sencillas de administrar.
Contextos locales contra contextos web
El desarrollador web dice: Las aplicaciones web ejecutan referencias a scripts externos en el mismo origen de la aplicación que llama al script.
El desarrollador de Windows 8 dice: Las aplicaciones de la Tienda Windows separan el paquete de aplicaciones local de las referencias de script externas.
La Web 2.0 condicionó a los desarrolladores a pensar que el contenido puede pasar desde su sitio, desde el sitio de alguien más (mediante mashup) o interacción del usuario. En la web, el contenido está dispuesto libremente al acceso de cualquiera que lo desee en un nivel virtual, donde los desarrolladores consumen referencias de script y datos de API de terceros. Las redes de entrega de contenidos (CDN) y los servicios en línea tales como Bing Maps toman la sobrecarga de la administración de las bibliotecas de código o de los grandes repositorios de datos, lo que permite que las aplicaciones web se conecten fácilmente en funcionalidad. Es bueno tener una sobrecarga baja, pero estos beneficios acarrean ciertos riesgos.
Como ejemplo, imagine que uno de los socios de Contoso en la industria de software de salud es Litware Inc.. Litware está lanzando una nueva API de ejercicios y proporcionó a los desarrolladores de Contoso Health las claves para consumir una fuente de datos de ejercicios diarios. Si Contoso Health fuese una aplicación web, el equipo de desarrollo podría implementar la API de ejercicios usando un script de referencia similar al siguiente:
<script src="https://api.litware.com/devkey/exercise.js"></script>
Los desarrolladores de Contoso confían en Litware en su posición de proveedores de muy buen contenido y saben que se respalda con muy buenas prácticas de seguridad. Desafortunadamente, los servidores de Litware fueron comprometidos por un desarrollador descontento y exercise.js se alteró para que tenga un script inicial que muestra una ventana emergente que dice "Debe efectuar mantenimiento sobre Contoso Health; descargue la siguiente aplicación de mantenimiento". El usuario, creyendo que el mensaje es legítimo, acaba de ser engañado para que descargue malware. Los desarrolladores de Contoso están estupefactos. Litware usa una excelente validación, ¿cómo fue posible que ocurriera esta brecha?
En la web, los scripts referidos en la manera ya descrita se ejecutan con el mismo origen que un script en el mismo sitio. Esto significa que exercise.js (ejecutándose como JavaScript) tiene acceso irrestricto al árbol DOM, además de cualquier objeto de script. Como se ilustró anteriormente, esto puede ser conducente a graves problemas de seguridad. Para mitigar este riesgo, Windows 8 separa los recursos de las aplicaciones en dos contextos, como se ilustra en la Figura 2.
Figura 2 Características de contexto local en oposición a web (mashup de "Características y restricciones por contexto" [bit.ly/NZUyWt] y "desarrollo seguro con HTML5" [bit.ly/JOoMOS])
El contexto local puede obtener acceso a Windows en tiempo de ejecución, además de cualquier recurso incluido en el paquete de aplicaciones (tal como HTML, script, CSS y datos de aplicación almacenados en los directorios de estado de aplicación), pero no puede obtener acceso remoto a HTML, JavaScript o CSS (como en el ejemplo anterior de exercise.js). La aplicación de alto nivel en Windows 8 siempre se ejecuta en el contexto local. En la Figura 2, mes-appx:// se usa para resolver el contenido en el contexto local. Este esquema se usa para hacer referencia al contenido del paquete de aplicación que se ejecuta en el contexto local. Frecuentemente, se agrega una tercera barra diagonal (ms-appx:///) para referir al nombre completo del paquete. Para los desarrolladores web, este enfoque es similar a usar el protocolo file://, donde una tercera barra diagonal hace referencia al sistema de archivos local (presupone file://PC DEL USUARIO FINAL/ en lugar de file://PC REMOTO/).
El contexto web permite a los desarrolladores traer contenido remoto a su aplicación Tienda de Windows a través de un iframe. Tal como ocurre con iframes en un explorador web, el contenido que se ejecuta en el iframe tiene restricciones para obtener acceso a recursos externos a él, como Windows en tiempo de ejecución y algunas características de la biblioteca de Windows para JavaScript. (Encontrará un listado completo en bit.ly/PoQVOj). La finalidad del contexto web es permitir a los desarrolladores hacer referencia a API de terceros, como Bing Maps o extraer una biblioteca desde un CDN a su aplicación.
Al usar http:// o https:// como la fuente de un iframe, se presentan automáticamente los contenidos del iframe en el contexto web. Un iframe puede también ser un recurso del paquete de aplicación cuando usa ms-appx o ms-appx-web. Donde la fuente de un iframe refiere al esquema ms-appx://, el contenido del iframe se ejecuta en el contexto local. Esto permite a los desarrolladores incrustar recursos de paquete de aplicación en un iframe mientras se sigue teniendo acceso a las características del contexto local (como Windows en tiempo de ejecución, la API de JavaScript de Windows, etc.). Otro esquema disponible es ms-appx-web://, la cual permite que el contenido local de un paquete de aplicación se ejecute en el contexto web. Este esquema es útil cuando necesita incrustar contenido remoto en su marcado, como agregar un resultado de búsqueda de Bing (de la API de búsqueda de Bing) de hospitales locales basándose en la ubicación del usuario en la aplicación Contoso Health. Como un nota adicional, siempre que se mencionan las iframes en HTML5, recuerde que puede usar el atributo sandbox como protección adicional para su aplicación al limitar la ejecución del script del contenido interior del iframe. Puede encontrar más información acerca del atributo sandbox en bit.ly/Ppbo1a.
La Figura 3 muestra los varios esquemas que se usaron en los contextos locales y web, junto con ejemplos de su uso.
Figura 3 Esquemas con ejemplos de contexto
Esquema | Ubicación de contenido: | Contexto | Ejemplo | Cuando se usa |
ms-appx:// | Paquete de aplicación | Local | <iframe src="ms-appx:///1.html" ></iframe> |
Cargar contenido en un iframe que necesita tener acceso a Windows en tiempo de ejecución o a toda la api de JavaScript de Windows. |
ms-appx-web:// | Paquete de aplicación | Web | <iframe src="ms-appx-web:///2.html" ></iframe> |
Usar contenido de una fuente remota como parte de su interfaz de aplicación de Tienda de Windows, como mostrar un widget de mapa o resultados de búsqueda. |
http:// | Asistencia | Web | <iframe src="http://host/3.html" ></iframe> |
Contenido de referencia remota como una página web o un archivo de script en otro servidor. |
La pertenencia de un iframe a un contexto determinado se establece en base de cómo se hace referencia al contenido. En otras palabras, el esquema determina el contenido. Puede encontrar más información acerca de los esquemas usados en Windows 8 en bit.ly/SS711o.
¿Recuerda el escenario del hack de Litware con la cual se inició esta sección? La separación de Windows 8 de los contextos ayudará a limitar el ataque de scripts entre sitios al contexto web, donde no tiene acceso ni a Windows en tiempo de ejecución o a los datos de aplicación de Contoso Health. En el contexto web, modificar el contexto local no es una alternativa. Es posible que ocurra comunicación entre contextos, pero tiene que tener controlo sobre el tipo de comunicaciones que ocurre.
Comunicación entre contextos
¿Cómo se comunica el documento de alto nivel con un iframe que se ejecuta en el contexto web? Mediante las características postMessage de HTML5, las aplicaciones de Windows Store pasan datos entre contextos. Esto permite a los desarrolladores estructurar cómo los dos} orígenes se comunican y a permitir solo proveedores correctos conocidos (nuevamente recurrimos a la lista de aceptación) a través del contexto local. Se hace referencia a las página que necesitan ejecutarse en el contexto web usando un iframe con el atributo src establecido como http://, https:// o ms-appx-web://.
Para la aplicación Contoso Health, el sistema extrae consejos deportivos de la API de ejercicio de Litware. El equipo de desarrollo de Contoso Health construyó la página litwareHelper.html, la cual se usa para comunicarse con la API de ejercicio mediante el objeto de jQuery $ajax. Dado al recurso remoto (exercise.js), litwarehelper.html necesita ejecutarse en el contenido web, puesto que significa que necesita ejecutarse en un iframe. configurar el iframe no es distinto de hacerlo con cualquier otra aplicación web, salvo como se hace referencia a las páginas. Dado que la página litwareHelper.html es parte del paquete de aplicación local, pero necesita ejecutarse en contexto web, se carga usando ms-appx-web:
<iframe id="litwareHelperFrame” src="ms-appx-web:///litwareHelper.html"></iframe>
El equipo de desarrollo agrega la siguiente función a la página de contexto local que envía la solicitud de datos a la página de contexto web:
function btnGetFitTips_Click() {
var msg = {
term: document.getElementById("txtExerciseSearchTerm").value,
itemCount: 25 }
var msgData = JSON.stringify(msg);
var domain = "ms-appx-web://" + document.location.host;
try {
var iframe = document.getElementById("litwareHelperFrame");
iframe.contentWindow.postMessage(msgData, domain);
}
catch (ex) {
document.getElementById("output").innerText = "Error has occurred!";
}
}
El método receiveMsg procesa el mensaje del contexto local. El argumento de receiveMsg son los datos proporcionados por el evento postMessage (en este caso la variable msgData), junto con el objetivo del mensaje, el origen del mensaje y otras piezas de información, como se muestra en la Figura 4.
Figura 4 Procesamiento con receiveMsg
function receiveMsg(e) {
if (e.origin === "ms-appx://" + document.location.host) {
var output = null;
var parameters = JSON.parse(e.data);
var url = "https://api.litware-exercise.com/data/"
+ parameters.term +
"/count/" + parameters.itemCount;
var options = {
dataType: "jsonp",
jsonpCallback: "jsonpCallback",
success: function (results) {
output = JSON.stringify(results.items);
window.parent.postMessage(output, "ms-appx://"
+ document.location.host);
},
error: function (ex) {
output = ex;
}
};
$.ajax(url, options);
}
}
El primer paso de receiveMsg comprueba el origen de postMessage. Esta es una comprobación de seguridad crucial para determinar que el mensaje procede de donde se supone que viene. Recuerde que e.origin comprueba el dominio y esquema de quien envió el postMessage, la cual es la razón por la que está buscando ms-appx (la dirección de contexto local). Después de recopilar los datos de JSON de la API de Litware, la aplicación pasará los resultados a window.parent usando un comando postMessage. Observe en receiveMsg que el dominio se configuró como ms-appx. Esta es la dirección "para" de donde irá el mensaje y muestra que los datos se devuelven al contexto local. Los recursos en el contexto local consumen los datos en el iframe. El equipo de desarrollo agrega la función processResult para que consuma los datos del contexto web y los ponga en el context local:
function processResult(e) {
if (e.origin === "ms-appx-web://" + document.location.host) {
document.getElementById("output").innerText = e.data;
}
}
Insisto, siempre compruebe el origen del evento de mensaje, para asegurarse de que se procesen solo los datos de ubicaciones aprobadas (es decir, de localizaciones registradas en la lista de aceptación). Observe que el origen es el esquema de contexto web: ms-appx-web en el método processResult. El cambio entre esquema puede tomar por sorpresa a los desarrolladores y hacer que se pregunten dónde fue a dar su mensaje durante la depuración.
Finalmente, para recibir datos del contexto web de vuelta a la página de contexto local, puede agregar un controlador de evento para el evento de mensaje. En el método app.onactivated, agregue el escucha de evento en el objeto ventana:
window.addEventListener('message', processResult, false);
Separar los contextos locales y web de forma predeterminada reduce el riesgo de ejecutar accidentalmente código desde una fuente externa a la aplicación de la Tienda de Windows. Mediante postMessage, los desarrolladores pueden proporcionar un canal de comunicación entre un script externo y los scripts locales que componen una aplicación.
Web para Windows 8: Nuevas herramientas para viejos hábitos
Los desarrolladores web ahora tienen acceso a herramientas conocidas y nuevas herramientas que pueda usar para crear aplicaciones de la Tienda de Windows seguras. Al usar habilidades existentes, tales como validación de entrada de HTML5, se asegura la integridad de los datos que entran a la aplicación. Las nuevas herramientas, tales como la API de protección de datos (nueva para Windows en tiempo de ejecución) protege los datos confidenciales de los usuarios con un cifrado fuerte que es fácil de implementar. Al usar postMessage se permite que las aplicaciones saquen partido de las miles de bibliotecas de JavaScript y del código heredado en la web mientras se mantiene a los usuarios a salvo de inyecciones de código no intencionado. Todos esos elementos trabajan en conjunto para traer algo importante que habitualmente se descuida en JavaScript: la seguridad.
Windows 8 entrega a los desarrolladores web la posibilidad de reconsiderar algunos de sus viejos hábitos. JavaScript ya no es una pantalla para el servidor, algo que se mira en menos, como una mejora para el uso y nada más. JavaScript, Windows en tiempo de ejecución y MSHTML proporciona las herramientas necesarias para crear características de seguridad en sus aplicaciones de la Tienda de Windows, no se necesita un servidor. Como desarrolladores web, tenemos un amplio conjunto de habilidades a los cuales podemos recurrir, pero necesitamos prestar atención a nuestros hábitos antiguos y transformarlos en oportunidades para aprender del nuevo mundo de Windows 8.
Tim Kulp es el líder del equipo de desarrollo en FrontierMEDEX en Baltimore, Maryland. Puede encontrar a Kulp en su blog en seccode.blogspot.com o seguirlo en Twitter en Twitter.com/seccode, donde habla de código, seguridad y del mundo gourmet de Baltimore.
Gracias al siguiente experto técnico por su ayuda en la revisión de este artículo: Scott Graham