API privadas de iOS

Estoy interesado en algunos de los detalles técnicos detrás de las API privadas de Apple en iOS. Parece que no puedo encontrar un buen artículo sobre algunos de estos detalles (más allá de cómo llamar a las funciones privadas de la API), aunque sería genial si alguien pudiera publicar un enlace si existe un artículo.

Específicamente, tengo algunas preguntas aleatorias:

  1. ¿Por qué Apple simplemente no elimina los símbolos de API privados de sus bibliotecas para que las aplicaciones de terceros no puedan acceder a ellos? ¿Esto se debe a que las funciones de la API pública llaman directamente a las funciones de la API privada?

  2. Este enlace menciona que Uber supuestamente usó una API privada (IOKit) para acceder a los números de serie del dispositivo desde su aplicación. ¿Por qué su aplicación tenía acceso a esta información en primer lugar, incluso si llamaron a una función de espacio de usuario privado? ¿La función privada en IOKit a su vez leyó el número de serie de una llamada al sistema no documentada y desprotegida (o alguna otra interacción con el kernel)?

  3. Leí que Apple escanea los accesos a las API privadas durante su proceso de revisión de la aplicación, pero ¿no sería bastante trivial derrotar este escaneo automatizado? ¿Tiene Apple alguna esperanza de resolver el "problema" de los accesos privados a la API desde aplicaciones de terceros?

Respuestas (2)

  1. Las propias aplicaciones de Apple que usan la API privada tampoco podrían usarlas si se eliminaran los símbolos. Después de todo, el enlazador dinámico no conoce la API "privada" o "pública". No es que los símbolos estén marcados individualmente; es solo que se publican encabezados/documentación para la API "pública".

  2. Hay varios repositorios con encabezados generados para todos los símbolos de los marcos de Apple. Busque "encabezados de tiempo de ejecución de iOS", "encabezados de tiempo de ejecución de macOS" y términos de búsqueda similares. En el caso de IOKit, los marcos son públicos en macOS pero se consideran privados en iOS. Por lo general, los marcos compartidos entre diferentes sistemas operativos de Apple son en su mayoría los mismos (hay excepciones, como las API de llavero y seguridad, pero no son muy diferentes ).diferente). No sé los detalles de cómo Uber estaba usando IOKit o qué información pudo extraer, pero supongo que pudieron extraer las direcciones MAC de las interfaces de red con él, lo que Apple intentó evitar en otras API. Nosotros (los desarrolladores) usábamos las direcciones MAC para identificar un dispositivo específico y cuando Apple intentó evitar esto, muchos de nosotros buscábamos formas de obtenerlo (o un identificador único de dispositivo similar) porque el enfoque de Apple más centrado en la privacidad interfería. con el deseo de las empresas de poder obtener esta información. Piense en licencias vinculadas a dispositivos, pero también en marketing.

  3. La selección de Apple para el uso de API privadas no es perfecta y hay varias formas en que los desarrolladores pueden obtener acceso a las API privadas sin que Apple se dé cuenta, siempre que no haya un problema de permiso real (archivo/IPC) que impida el acceso. Debido a la ofuscación, la naturaleza dinámica de Objective-C y cómo funciona el enlazador dinámico, Apple está teniendo dificultades para detectar todo el uso privado de API si un desarrollador lo hace (y lo oculta) intencionalmente. Su proyección en su mayoría capta el uso obvio. Una de las razones es que algunas API privadas pueden ser llamadas por público.Las API de Apple, por lo que no es fácil detectar si el desarrollador realizó directamente la llamada a una API privada o si sucedió indirectamente a través de las API públicas. Dudo que alguna vez resuelvan esto y también dudo que valga la pena invertir muchos recursos en este problema.

Para tener el contexto correcto para las respuestas más específicas a su pregunta, es importante comprender cuál es realmente el propósito de las "API privadas":

Para entenderlo debemos saber qué es una API (Interfaz de Programación de Aplicaciones): Una API es algo que le permite al desarrollador de aplicaciones invocar una funcionalidad implementada por otra persona. Históricamente, tenía programadores de sistemas que creaban el sistema operativo y las bibliotecas del sistema, y ​​tenía programadores de aplicaciones que creaban la aplicación que usarían los usuarios finales. El enlace entre ellos sería la API.

Hoy en día, las API existen en muchas formas diferentes que sirven para diferentes propósitos:

  • API del sistema operativo: por ejemplo, el uso de "llamadas al sistema" que permiten a los programadores que no son del sistema operativo (es decir, programas de espacio de usuario) invocar la funcionalidad dentro del kernel del sistema operativo. En la mayoría de los sistemas operativos comunes, esto también es un límite de seguridad (es decir, este es el lugar donde se realizan las comprobaciones y los controles para garantizar que solo se invoque la funcionalidad permitida)

  • Biblioteca del sistema/API del marco: por ejemplo, el proveedor del sistema proporciona un marco para crear interfaces de usuario para que todo el sistema pueda tener un conjunto de widgets reconocibles (como botones, listas, etc.) que se dibujan de la misma manera en todas las aplicaciones. Por lo general, no hay límite de seguridad aquí.

  • API internas de la aplicación: algunas aplicaciones se dividen internamente en bibliotecas/marcos y cuentan con sus propias API. Podría ser, por ejemplo, una aplicación desarrollada por varios equipos que dividen sus áreas de responsabilidad a través de bibliotecas/marcos, o podría ser que una biblioteca se crea una vez y se usa para muchas aplicaciones diferentes, mientras que el desarrollador desea que el código permanezca separado para el resto. en aras de la mantenibilidad. La biblioteca puede ser desarrollada internamente o podría ser una biblioteca de código abierto compartida por miles. Por lo general, no hay límite de seguridad aquí.

  • Red / API web: algunos sistemas exponen las API a través de redes, o más específicamente a través de la web. Por ejemplo, Amazon expone una API que permite a los desarrolladores enviar una foto desde su aplicación a los servidores de Amazon y recibir una versión OCR (es decir, texto extraído de la foto). Por lo general, aquí hay un límite de seguridad, ya que estas API web suelen requerir algún tipo de autenticación para garantizar el pago o proteger la información privada.

Ahora que tenemos los conceptos básicos de las API, lo siguiente es lo que significa una "API privada":

De hecho, Apple no se refiere a las "API privadas" como tales. En su lugar, publican documentación para desarrolladores que incluye referencias de API y archivos de encabezado, y luego recomiendan que los desarrolladores solo usen esas API documentadas públicamente. Las llamadas "API privadas" son lo que Apple llama en realidad "API no públicas".

No es un invento de Apple, sino que las API privadas/públicas se han utilizado en la industria durante décadas. Por ejemplo, históricamente, Microsoft publicaba una extensa documentación para desarrolladores sobre cómo usar su API de USUARIO de Windows para crear una interfaz gráfica de usuario con varios controles, pero su producto de Office tenía controles privados que solo estaban disponibles en Office, aunque existían en una API de terceros. los desarrolladores del partido técnicamente podrían haber usado.

Y ahora llegamos al propósito de las "API privadas":

Tradicionalmente, las API públicas vienen con una promesa (a veces implícita, a veces explícita) de que estas API no desaparecerán ni cambiarán debajo de los desarrolladores de aplicaciones durante mucho tiempo. Un desarrollador podría usar una API pública y esperar que funcione según lo documentado, y seguir haciéndolo cuando el proveedor publique actualizaciones menores y mayores. Por lo general, el desarrollador también podría esperar recibir una advertencia (el llamado aviso de desaprobación) cuando la API pública que estaba usando cambiaría o desaparecería en los años siguientes. Del mismo modo, los desarrolladores esperarían poder informar errores en estas API al proveedor.

Las API privadas, por otro lado, no disfrutaron de estas sutilezas. Una API privada podría desaparecer en una actualización del sistema, podría comenzar a funcionar repentinamente de manera diferente (o no funcionar en absoluto), y los desarrolladores no podrían quejarse al proveedor sobre errores o funciones faltantes.

Así es también como funcionaban las API públicas/privadas en el iPhone al principio. La razón por la que muchos piensan en iOS cuando mencionas "API privadas" es que Apple introdujo más tarde un nuevo requisito para publicar una aplicación en su App Store, es decir, que la aplicación solo debe usar API públicas. De esta forma, Apple puede asegurarse de que una aplicación que funcionó el año pasado seguirá funcionando el próximo año para los clientes que la compraron en la App Store.

Puede suponer que la distinción entre API "públicas" y "privadas" tiene algo que ver con la seguridad del sistema. Eso casi nunca es el caso. En muchos casos, las API tienen la forma de ejecutables ubicados en un archivo de biblioteca/marco en el sistema. Técnicamente, no hay nada que impida que el desarrollador simplemente copie el código de la biblioteca "privada" en su propia aplicación, lo que lo convierte en parte de su aplicación y, por lo tanto, ya no es una API. Dependiendo de cuánto código se copie, el desarrollador estaría infringiendo los derechos de copia y posiblemente un acuerdo de licencia entre ellos y el proveedor.

En realidad, las API privadas a menudo se hacen privadas porque todavía están cambiando. Por ejemplo, Apple podría tener una API privada para una nueva pieza de hardware o un nuevo conjunto de funciones en su dispositivo. Con cada lanzamiento, esa API cambia un poco a medida que los desarrolladores de Apple aprenden de los errores y descubren la forma en que los usuarios interactúan con sus propias aplicaciones que usan estas funcionalidades. Más tarde, cuando la API ha dejado de cambiar (tanto), Apple hace pública esa misma API, ya que ahora creen que está lista para el consumo de desarrolladores externos.

Ahora llegamos a sus preguntas más específicas:

  1. Parte de la razón por la que Apple (y otros proveedores) no eliminan los símbolos de API privada de sus bibliotecas es principalmente que ellos mismos, o los socios a los que han permitido usar API privadas, tampoco podrían usar fácilmente estas API en sus aplicaciones Luego, Apple tendría que duplicar todas las bibliotecas, tener una versión para ellos y otra para los que no son socios, y asegurarse de que la versión correcta esté disponible en cada caso.

    Una forma más lógica para que Apple restrinja el uso de API privadas sería cambiar el vinculador dinámico y el sistema de mensajería entre los objetos utilizados en Objective-C y Swift para garantizar que las aplicaciones no autorizadas no puedan llamar a las API privadas. Sin embargo, además de agregar mucha complejidad realmente innecesaria, vendría con una penalización de rendimiento no trivial.

    De hecho, es probable que a Apple no le preocupe tanto que un desarrollador use una API privada y, por lo tanto, se limitan a tener simplemente una guía, tratando de detectar los usos más obvios para educar a los desarrolladores, y luego solo hacen algo al respecto si se hace público. sabe que se ha utilizado una API privada.

    En casi todos los casos, el desarrollador de la aplicación podría haber reemplazado el uso de una API privada simplemente copiando el código ejecutable de la biblioteca en su propia aplicación, lo que hace que todo el punto de la disputa sea discutible. La razón por la que los desarrolladores usan API privadas es a menudo para acceder a la funcionalidad que Apple creó y que no tienen tiempo para recrear ellos mismos, o para acceder a la funcionalidad que esperan que sea pública de todos modos pronto. Luego, es responsabilidad del desarrollador asegurarse de que solo use esa API privada para ciertas versiones del sistema que realmente tiene esa API privada, y correría el riesgo de que su aplicación se rompa con las actualizaciones del sistema.

  2. Con respecto al caso de Uber: el verdadero problema aquí no es el uso de API privadas. En realidad, es un error de seguridad en el sistema operativo que la información privada estuvo expuesta a la aplicación. El desarrollador de la aplicación podría haber hecho lo mismo en su código que hizo la API privada y podría haber obtenido acceso a la misma información privada. Eso no es bueno.

  3. Sí, el escaneo automático es un juego de "gato y ratón", en el que generalmente es mucho más fácil para el desarrollador de la aplicación hacer algo que oculte su uso de API privadas, y mucho más difícil para Apple construir un detector. No creo que el uso de API privadas sea realmente un "problema" para Apple.

¡Muchas gracias por este fantástico escrito! Realmente lo aprecio :)