Students Save 30%! Learn & create with unlimited courses & creative assets Students Save 30%! Save Now
Advertisement
  1. Code
  2. Security
Code

Codificación Segura en Swift 4

by
Difficulty:IntermediateLength:LongLanguages:

Spanish (Español) translation by James (you can also view the original English article)

De minimizar el puntero ir fuerte tipo comprobación en tiempo de compilación, Swift es una gran lengua para el desarrollo seguro. Pero eso significa que es tentador para olvidarse de la seguridad en conjunto. Existen vulnerabilidades, y Swift también está tentando a nuevos desarrolladores que todavía no han aprendido acerca de la seguridad.

Este tutorial es una guía de codificación segura que abordará cambios en Swift 4, así como las nuevas opciones de herramientas disponibles en Xcode de 9 que te ayudarán a mitigar las vulnerabilidades de seguridad.

Punteros y Desbordamientos

Muchas vulnerabilidades de seguridad han girado alrededor de C y el uso de punteros. Esto es porque los punteros le permiten acceder a posiciones de memoria raw, haciéndolo más fácil de leer y escribir en el área equivocada. Ha sido una manera importante para los atacantes maliciosamente cambiar un programa.

SWIFT en su mayoría hace distancia con punteros, pero todavía le permite interface con C. Muchas API, incluyendo Apple toda base Fundación API, se basan enteramente en C, por lo que es muy fácil de introducir el uso de punteros en Swift.

Afortunadamente, Apple ha nombrado apropiadamente a los tipos de puntero: UnsafePointer<T>, UnsafeRawPointer<T>, UnsafeBufferPointer<T> y UnsafeRawBufferPointer. Vendrá un tiempo cuando la API son interfaces con devolverá estos tipos, y la regla principal cuando utilizarlas es no almacenar o devolver punteros para su uso posterior. Por ejemplo:

Porque accede al puntero fuera de la clausura, no sabemos con certeza si el puntero aún apunta al contenido de la memoria prevista. La manera segura de utilizar el puntero en este ejemplo sería mantener, junto con la instrucción print, en el cierre.

Punteros a cadenas y matrices también tienen límites de control. Esto significa que es fácil de utilizar un puntero de inseguro en una matriz pero accidentalmente el acceso más allá de su límite — un desbordamiento de búfer.

La buena noticia es que Swift 4 intenta chocar la aplicación en lugar de continuar con lo que se llamaría comportamiento indefinido. No sabemos qué buffer [5] puntos a! Sin embargo, Swift no captura todos los casos. Establecer un punto de interrupción después del siguiente código y mirar las variables a y c. Se establecerá a 999.

Esto demuestra un desbordamiento de pila porque sin una asignación explícita, variables generalmente se almacenan en la pila.

En el siguiente ejemplo, hacemos una distribución con una capacidad de sólo un único Int8. Las asignaciones se almacenan en el montón, así que la siguiente línea desbordará el montón. Para este ejemplo, Xcode sólo le advierte con una nota en la consola que no consigue es seguro.

Así que ¿cuál es la mejor manera de evitar desbordamientos? Es muy importante cuando el interfaz con C hacer límites de control en la entrada para asegurarse de que está dentro de rango.

Usted podría estar pensando que es bastante difícil de recordar y encontrar todos los diferentes casos. Así que para ayudarle hacia fuera, Xcode viene con una herramienta muy útil llamada dirección de desinfectante.

Desinfectante de dirección ha sido mejorada en Xcode 9. Es una herramienta que le ayuda a coger el acceso de memoria no válida como los ejemplos que acabamos de ver. Si usted va a trabajar con los tipos de Unsafe*, es una buena idea utilizar la herramienta de dirección desinfectante. No está habilitada de forma predeterminada, la para habilitarlo, Producto > Esquema > Editar Esquema > Diagnóstico y verificar Dirección Desinfectante. En Xcode 9 hay una nueva opción sub, Detectar uso de pila después de vuelta. Esta nueva opción detecta las vulnerabilidades de uso después de alcance y uso después de regresar de nuestro primer ejemplo.

A veces se pasa por alto es el desbordamiento de enteros. Esto es debido a desbordamientos de enteros son agujeros de seguridad sólo cuando se utiliza como un índice o el tamaño de un tampón, o si cambia el valor inesperado del desbordamiento el flujo del código crítico de seguridad. SWIFT 4 capturas más obvio desbordamientos de enteros en tiempo de compilación, como cuando el número es claramente mayor que el valor máximo del entero.

Por ejemplo, la siguiente no se compilará.

Pero muchas veces el número llegará dinámicamente en tiempo de ejecución, como cuando un usuario escribe información en un UITextField. Desinfectante de comportamiento indefinido es una nueva herramienta en Xcode 9 que detecta el desbordamiento de entero con signo y otros errores de coincidencia de tipo. Para habilitarlo, ir al Producto > Esquema > Editar Esquema > Diagnósticos, y encienda Desinfectante Comportamiento Indefinido. Entonces en Construir > Desinfectante de Comportamiento Definido, establezca Habilitar Extra Entero Verifica en Si.

Hay otra cosa vale la pena mencionar sobre comportamiento indefinido. Aunque Swift pura oculta punteros, referencias y copias de los buffers se utilizan detrás de las escenas, así que es posible incurrir en un comportamiento que no se esperar. Por ejemplo, cuando empiezas a iterar sobre los índices de la colección, los índices podrían accidentalmente ser modificados por usted durante la iteración.

Aquí nos a causado la matriz de numbers para que apunte a una nueva matriz dentro del bucle. ¿Entonces lo que numbers punto a? Esto normalmente se llamarían una referencia colgando, pero en este caso Swift crea de forma implícita una referencia a una copia de la memoria intermedia de su arreglo para la duración del bucle. Eso significa que la instrucción print realmente imprimirá 1, 2 y 3 en lugar de 1, 4, 5... ¡Está bueno! SWIFT es ahorro de comportamiento indefinido o un desplome de la aplicación, aunque usted no podría haber esperado que de salida ya sea. Sus desarrolladores par no esperan su colección para ser transformado durante la enumeración, así en general, ser muy cuidadoso durante la enumeración, que no están alterando la colección.

Así, Swift 4 tiene aplicación de gran seguridad en tiempo de compilación para atrapar estas vulnerabilidades de seguridad. Hay muchas situaciones donde la vulnerabilidad no existe hasta que el tiempo cuando hay interacción con el usuario. SWIFT también incluye la comprobación dinámica, que puede coger muchos de los problemas en tiempo de ejecución demasiado, pero demasiado costoso hacerlo a través de hilos de rosca no se realiza para código multiproceso. Comprobación dinámica coger muchas pero no todas las violaciones, por lo que es todavía importante escribir código seguro en primer lugar!

Con eso, volvamos a otra área muy común de vulnerabilidades, ataques de inyección de código.

Inyección y Ataques de Cadena de Formato

Formato cadena ataques suceden cuando una cadena de entrada se analiza en su aplicación como un comando que no tenía intención. Mientras que cadenas Swift puros no son susceptibles a ataques de la cadena de formato, las clases NSString Objective-C y CFString de la Fundación del núcleo son, y están disponibles de Swift. Dos de estas clases tienen métodos como stringWithFormat.

Supongamos que el usuario puede introducir texto arbitrario de un UITextField.

Esto podría ser un agujero de seguridad si la cadena de formato se maneja directamente.

SWIFT 4 intenta manejar argumentos de cadena de formato que falta por devolver 0 o NULL, pero es especialmente una preocupación si la cadena se pasan a Objective-C tiempo de ejecución.

Mientras que la mayoría de las veces la forma incorrecta sólo causará un accidente, un atacante puede elaborar cuidadosamente una cadena de formato para escribir datos en ubicaciones específicas de la memoria en la pila para alterar su comportamiento de la aplicación (como cambiar una variable isAuthenticated).

Otro gran culpable es NSPredicate, que puede aceptar una cadena de formato que se utiliza para especificar qué datos se recuperan de la base de datos. Cláusulas tales como LIKE y CONTAINS permite comodines y deben evitarse o al menos utilizados para las búsquedas. La idea es evitar la enumeración de las cuentas, por ejemplo, donde el atacante entra en «una * "como el nombre de cuenta. Si se cambia la cláusula LIKE a ==, esto significa que la cadena literalmente tiene que coincidir con "a *".

Otros ataques comunes ocurren por terminación de la cadena de entrada temprano con un carácter de comillas simples por lo que se pueden introducir comandos adicionales. For Instance, un inicio de sesión puede evitarse introduciendo ') OR 1=1 OR (password LIKE '* en el UITextField. Esa línea se traduce a "contraseña es como cualquier cosa", que omite la autenticación en conjunto. La solución es escapar completamente cualquier intento de inyección añadiendo tus propio comillas en el código. Así, cualquier cita adicional del usuario se ve como parte de la cadena de entrada en vez de ser un carácter de terminación especial:

Una forma más de proteger contra estos ataques es simplemente buscar y excluir caracteres específicos que podrían ser perjudiciales en la cadena. Ejemplos incluyen citas, o incluso puntos y barras. Por ejemplo, es posible hacer un ataque de salto de directorio cuando de entrada se pasa directamente a la clase FileManager. En este ejemplo, el usuario ingresa "... / "para ver el directorio de la ruta de acceso en lugar del subdirectorio deseado.

Otros caracteres especiales pueden incluir NULL terminar octeto si se acostumbra la cadena como una cadena de C. Punteros a cadenas de C requieren un NULL byte de terminación. Debido a esto, es posible manipular la cadena simplemente introduciendo un byte NULL. El atacante puede terminar la cadena temprano si había una bandera como needs_auth = 1, o cuando el acceso es por defecto y desactivado explícitamente como con is_subscriber = 0.

Analizar cadenas HTML, XML y JSON requiere atención especial. La manera más segura de trabajar con ellos es utilizar bibliotecas nativas de la Fundación que proporcionan los objetos para cada nodo, como la clase NSXMLParser. SWIFT 4 introduce seguridad serialización a formatos externos como JSON. Pero si estás leyendo XML o HTML mediante un sistema personalizado, asegúrese de que los caracteres especiales de la entrada del usuario no pueden utilizarse para indicar al intérprete.

  • < debe convertirse en &lt.
  • > obtener sustituyan con &gt.
  • & debe convertirse en &amp.
  • Dentro de los valores de atributo, cualquier  o ' necesita ser &quot y &apos, respectivamente.

Aquí está un ejemplo de una forma rápida de quitar o reemplazar caracteres específicos:

Un área final para ataques de inyección está dentro de controladores de dirección URL. Verifique que el usuario no utiliza directamente dentro de la URL controladores openURL y didReceiveRemoteNotification. Verifique que la URL es lo que está esperando y que no permite un usuario arbitrariamente entrar información para manipular su lógica. Por ejemplo, en vez de dejar al usuario elegir que pantalla en la pila para acceder al índice, permite sólo específicos pantallas utilizando un identificador opaco, como t = es84jg5urw.

Si utiliza WKWebViews en su aplicación, sería bueno comprobar las direcciones URL que se cargan allí también. Puede reemplazar decidePolicyFor avigationAction, que le permite elegir si desea continuar con la petición de URL.

Algunos trucos conocidos webview incluyen esquemas de URL personalizados el desarrollador no tenía intención, como un app-id de carga: para lanzar una aplicación totalmente diferente o sms: enviar un texto. Tenga en cuenta que webviews incrustados no mostrará una barra con la dirección URL o el estado SSL (el icono de candado), por lo que el usuario no es capaz de determinar si la conexión es de confianza.

Si el webview es pantalla completa, por ejemplo, la URL podría secuestrada con una página web que se parece a la pantalla de inicio de sesión excepto dirigir las credenciales a un dominio que en su lugar. Otros ataques en el pasado han incluido ataques de scripts entre sitios que se han filtrado las cookies y el entero sistema de ficheros.

La mejor prevención de todos los ataques mencionados es tomarse el tiempo para diseñar su interfaz con controles de interfaz de usuario nativos en lugar de simplemente mostrar una versión basada en web dentro de su aplicación.

Hasta ahora, nos hemos estado mirando relativamente sencillo tipo de ataques. Pero vamos a terminar con un ataque más avanzado que puede suceder en el tiempo de ejecución.

Tiempo de Ejecución de Hacking

Igual que Swift se vuelve más vulnerable al interfaz con C, interconexión con Objective-C trae distintas vulnerabilidades a la mesa.

Ya hemos visto los problemas con ataques de cadena NSString y formato. Otro punto es que Objective-C es mucho más dinámico como un lenguaje, permitiendo tipos sueltos y métodos para pasar alrededor. Si tu Swift clase hereda de NSObject, entonces se vuelve abierto a ataques de ejecución de Objective-C.

La vulnerabilidad más común consiste en intercambiar dinámicamente un método de seguridad importante para otro método. Por ejemplo, un método que devuelve si un usuario se valida podría ser intercambiado por otro método que casi siempre devolverá true, como isRetinaDisplay. Minimizando el uso de Objective-C hace su aplicación más robusta contra este tipo de ataque.

En Swift 4, métodos en las clases que heredan de una clase de Objective-C sólo exponen a Objective-C tiempo de ejecución si los métodos o las clases ellos mismos están marcadas con @attribute. La función rápida se llama a menudo en su lugar, incluso si se utiliza el atributo @objc. Esto puede suceder cuando el método tiene un atributo de @objc, pero nunca realmente se llama de Objective-C.

En otras palabras, Swift 4 presenta menos inferencia @objc, por lo que esto limita la superficie de ataque en comparación con versiones anteriores. Todavía, para apoyar las funciones de tiempo de ejecución, objetivo C basado en binarios que retienen mucha de la información de la clase que no puede ser despojado. Esto es suficiente para los ingenieros inversos reconstruir la interfaz de clase para averiguar qué secciones seguridad parches, por ejemplo.

En Swift, hay menos información expuesta en el binario, y los nombres de función son destrozados. Sin embargo, el mangling puede ser deshecho por el Xcode herramientas demangle de swift. De hecho, funciones rápidas tienen un esquema de nombres coherente, que indica si cada uno es una función rápida o no, parte de una clase, el nombre del módulo y la longitud, clase nombre, longitud, nombre del método y longitud, atributos, parámetros y tipo de valor devuelto.

Estos nombres son más cortos en el Swift 4. Si usted está preocupado por ingeniería inversa, asegúrese de que la versión de la aplicación de tiras de símbolos yendo a construir Configuraciones > Despliegue > Tira Swift Símbolos y establecer la opción en Si.

Más allá de la ofuscación de código crítico de seguridad, también puede solicitar que sea en línea. Esto significa que cualquier lugar que la función es llamada en el código, el código se repetirán en ese lugar en vez de existentes sólo en un lugar de binario.

De esta forma, si un atacante logra eludir un control de seguridad particular, no afectará cualquier otras ocurrencias de ese cheque en otros lugares del código. Cada uno tiene parcheado o enganchado, lo que es mucho más difícil de realizar con éxito un crack. Puedes código en línea como esta:

Conclusión

Pensamiento acerca de la seguridad debe ser una parte importante del desarrollo. Simplemente esperando la lengua seguro puede conducir a vulnerabilidades que podrían haberse evitadas. SWIFT es popular para el desarrollo de iOS, pero está disponible para aplicaciones de escritorio de macOS, tvOS, watchOS y Linux (así que podría utilizar para los componentes de servidor donde el potencial de vulnerabilidades de ejecución de código es mucho mayor). Sandboxing de aplicación pueden romperse, como en el caso de jailbreak dispositivos que permiten de código sin firmar, por ello es importante todavía pensar en seguridad y prestar atención a los avisos de Xcode mientras depura.

Un Consejo final es tratar las advertencias del compilador como errores. Usted puede obligar a Xcode para ello, vamos a Construir Ajsutes y Ajuste Tratar Advertencias como Errores a Si. No te olvides de modernizar su configuración de proyecto cuando migrar a Xcode 9 para obtener advertencias mejoradas y el último pero no menos importante, hacer uso de las nuevas características disponibles adoptando Swift 4 hoy!

Aprender Swift

Hemos construido una guía completa para ayudarle a aprender Swift, si te acaba de empezar con lo básico o quieres explorar temas más avanzados.

Para una cartilla en otros aspectos de codificación segura para iOS, revisa algunos de mis otros posts aquí en Envato Tuts+!

Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.