7 KiB
iOS UIActivity Sharing
UIActivity Sharing
Starting on iOS 6 it is possible for third-party apps to share data (items) via specific mechanisms like AirDrop, for example. From a user perspective, this feature is the well-known system-wide share activity sheet that appears after clicking on the "Share" button.
A full list of the available built-in sharing mechanisms can be found in UIActivity.ActivityType. If not considered appropriate for the app, the developers have the possibility to exclude some of these sharing mechanisms.
Sending Items
When testing UIActivity
Sharing you should pay special attention to:
- the data
items
being shared, - the custom activities,
- the excluded activity types.
Data sharing via UIActivity
works by creating a UIActivityViewController
and passing it the desired items URLs, text, a picture
on init(activityItems:applicationActivities:)
.
If having the source code, you should take a look at the UIActivityViewController
:
- Inspect the activities passed to the
init(activityItems:applicationActivities:)
method. - Check if it defines custom activities
also being passed to the previous method
. - Verify the
excludedActivityTypes
, if any.
If you only have the compiled/installed app, try searching for the previous method and property, for example:
$ rabin2 -zq Telegram\ X.app/Telegram\ X | grep -i activityItems
0x1000df034 45 44 initWithActivityItems:applicationActivities:
Receiving Items
When receiving items, you should check:
- if the app declares custom document types ****by looking into Exported/Imported UTIs
"Info" tab of the Xcode project
. The list of all system declared UTIsUniform Type Identifiers
can be found in the archived Apple Developer Documentation. - if the app specifies any document types that it can open by looking into Document Types
"Info" tab of the Xcode project
. If present, they consist of name and one or more UTIs that represent the data typee.g. "public.png" for PNG files
. iOS uses this to determine if the app is eligible to open a given documentspecifying Exported/Imported UTIs is not enough
. - if the app properly verifies the received data by looking into the implementation of
application:openURL:options:
or its deprecated version [`UIApplicationDelegate application:openURL:sourceApplication:annotation:`](https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1623073-application?language=objc)
in the app delegate.
If not having the source code you can still take a look into the Info.plist
file and search for:
UTExportedTypeDeclarations
/UTImportedTypeDeclarations
if the app declares exported/imported custom document types.CFBundleDocumentTypes
to see if the app specifies any document types that it can open.
A very complete explanation about the use of these keys can be found on Stackoverflow but here you have a summary:
UTExportedTypeDeclarations
: Use them to define your own UTIs that your app wants to teach the system it is installed on. An UTI describes a piece of data_not necessarily data located inside a file!_
and requires at least an identifier`com.example.MyCoolDataType`
. Additionally it may have a name`My Cool Data Type`
, one or more file name extensions`.myCoolDataType`
, one or more MIME types`x-application/my-cool-data-type`
, one or more pasteboard typesused when transferring data of that kind using copy&paste
, and one or more legacy OS type. Usually you also want UTIs to conform to existing UTIsE.g. when you say your UTI conforms to `public.data`, any process that can deal with generic data can also deal with your UTI
.- e.g.: You define your own proprietary file data format and you want this data format to be also known to other apps, plugins, extensions, and so on.
UTImportedTypeDeclarations
: You useUTImportedTypeDeclarations
do teach the system about UTIs that you want to be known in the system but that are not your UTIs.- e.g.: Your app is able to read the proprietary data format of another application, yet you don't know if that application is even installed on the system.
CFBundleDocumentTypes
: You useCFBundleDocumentTypes
to tell the system which Document types your app is able to open. Unless you also list your UTIs here, these UTIs are not associated with your app in Finder and your app won't appear in theOpen With >
menu. The only thing you always must set for a document type is the role. The role can be "Viewer"you can display that file type but you cannot edit it
, "Editor"you can display and edit that file type
, "None"it's not specified what you can do with that file
.- e.g.: You want your app do be associated with certain file types, identified either by extension, by MIME type, or by UTI identifier. If you want your app to be associated with an UTI type, the app should either import or export the type, as otherwise the type may not be known to the system and registering to unknown UTI type has simply no effect at all.
Dynamic Testing
For sending activities you can:
- Hook the method we have seen in the static analysis
[`init(activityItems:applicationActivities:)`](https://developer.apple.com/documentation/uikit/uiactivityviewcontroller/1622019-init)
to get theactivityItems
andapplicationActivities
. - Find out the excluded activities by hooking
excludedActivityTypes
property.
For receiving items you can:
- Share a file with the app from another app or send it via AirDrop or e-mail. Choose the file so that it will trigger the "Open with..." dialogue
that is, there is no default app that will open the file, a PDF for example
. - Hook
application:openURL:options:
and any other methods that were identified in a previous static analysis. - Observe the app behavior.
- In addition, you could send specific malformed files and/or use a fuzzing technique.
Read how here.