16-May-2016 with the recent release of a Google iOS keyboard, this issue has re-surfaced. I’ve posted some updated thoughts on Medium.
A custom keyboard is only a keyboard. Unless you “Allow Full Trust”, then your shiny new custom keyboard can essentially have the capabilities of a full fledged app.
To be safe, do not enable “Allow Full Trust” for any keyboard.
With the release of iOS 8, users can now install custom keyboards. Yes, Android users we hear you chuckling but let’s ignore that for now and dive into this new feature and the security challenges it presents.
For me, this tweet by Ben Adida brought the potential issues to light.
In a few days, we're going to discuss this: "Apple is committed to privacy & those custom keyboards send all your keystrokes to the cloud."— Ben Adida (@benadida) September 21, 2014
Aral Balkan made a similar comment today:
A free custom keyboard app asking you for network access is like a fox asking for the key to the coop.— Aral Balkan (@aral) September 22, 2014
This is definitely an area that needs more clarity.
iOS 8 allows for the creation of a variety of extensions. These extensions share a common design and restrictions. Custom keyboards are a specific type of App Extension and in order to fully understand their potential risks, we must first understand App Extensions in general.
App Extensions are not directly available in the App Store on iTunes. Each extension is delivered via a containing app. A containing app can contain one or more App Extensions.
This is an important point that we’ll touch on a bit later.
The developer documentation for iOS 8 is now publicly available so we can freely discuss it’s contents. You can read through it yourself if you’d like, for this post I’ve pulled out the relevant information and will provide links back to the source where appropriate.
The restrictions placed on all types of extensions are listed in “Some APIs Are Unavailable to App Extensions”, the key points are:
access to sharedApplication object or any API marked as NS_EXTENSION_UNAVAILABLE is blocked. In other words, there are specific areas of iOS that are blocked from extensions in general
HealthKit & EventKit are completely unavailable. Ditto for the camera & microphone
can’t setup long-running background tasks
extensions cannot receive data via AirDrop
In addition to the general App Extension restrictions, custom keyboards are further restricted. The following applies only to custom keyboards:
most of the settings under Settings > General > Keyboard are unavailable to customer keyboards. Yes “most” is the word used in the official documentation1
secure text input fields are off limits. When you tap a secure text input field (e.g. a properly coded password input) the default iOS keyboard reappears until you tap on a non-security text input field
access to “phone pad” objects are blocked. The numeric-only input field falls under this category
apps can specifically block custom keyboards. This should be implemented for any application dealing with sensitive information
a custom keyboard cannot select text
cannot display key artwork about the top edge of the customer keyboard area. In simpler terms, a custom keyboard is visually restricted to it’s keyboard area (which it can define)
These restrictions are in place regardless of the level of trust the user has granted the custom keyboard. This means we have a solid baseline from which to work.
By default, when a developer creates a new custom keyboard it’s has very limited access because it’s running in a highly restricted sandbox. By default, “a keyboard has no network access and cannot share a container with its containing app”2
That’s the default, the keyboard can request additional permissions that raise the issue of developer trust.
It’s the issue of trust for a keyboard that is a bit complex. Apple has clearly defined the capabilities of a non-networked keyboard (the default) and one with extended permissions that allow access to the network.
This breakdown actually provides clarity on the earlier “most” notation about keyboard settings. The breakdown is listed in the documentation as table 8-1 if you want to dive into the specifics.
To summarize table 11-1, a non-networked keyboard can only act like a keyboard. A network-enabled keyboard is an app.
In addition to the sandbox restrictions, in order to be published in the App Store a custom keyboard must follow some addition rules. Verbatim from section 25. Extensions of the App Store Review Guidelines:
25.1 Apps hosting extensions must comply with the App Extension Programming Guide
25.2 Apps hosting extensions must provide some functionality (help screens, additional settings) or they will be rejected
25.3 Apps hosting extensions that include marketing, advertising, or in-app purchases in their extension view will be rejected
25.4 Keyboard extensions must provide a method for progressing to the next keyboard
25.5 Keyboard extensions must remain functional with no network access or they will be rejected
25.6 Keyboard extensions must provide Number and Decimal keyboard types as described in the App Extension Programming Guide or they will be rejected
25.8 Apps offering Keyboard extensions may only collect user activity to enhance the functionality of their keyboard extension on the iOS device or they may be rejected
While these are pretty broad rules, 25.8 does show that Apple is putting a bit of effort into making sure that developers have a use case for collecting data when the customer keyboard is capable of doing so.
This means that non-networked keyboard poses very little threat. It can’t communicate with it’s host application in any meaningful way beyond inserting & deleting text. In this configuration the keyboard also cannot communicate with it’s containing app.
There is a the possibility that the keyboard can store all of your keystroke data but little-to-no change of sending that data elsewhere. I am currently working on a sample code to explore the boundaries of the non-networked sandbox.
Any attempt to store & process your keystroke data should raise some significant privacy questions but there is very little threat posed by a non-network custom keyboard.
While I applaud the developer documentation from Apple with it’s clear stance on the importance of establishing trust, there is a huge disconnect between the wording in the developer documentation and the terminology used in iOS itself.
For the record, what the developer documentation terms a “network-enabled keyboard” is in fact a keyboard with “Allow Full Trust” enabled.
“Fully Trusted” is a much better adjective than “network-enabled” since the elevation of privilege for the keyboard isn’t limited solely to network access.
The good news is that you—the user—have to explicitly allow a keyboard to be fully trusted.
The bad news is what is now possible once you make that decision.
Once you allow a keyboard to be fully trusted, it can now share a container with it’s containing app (remember that from earlier?).
This means that the keyboard can now feed information back to it’s containing app. From that containing app, your information can go anywhere.
In addition to sharing a container (a/k/a sandbox) with the containing app, the keyboard can now access Location Services & your Address Book (with additional explicit user permission). It can also access the network directly which means your keystroke data can go anywhere the developer wants.
For some odd reason, the keyboard can now access Game Center via the containing app. In-App Purchase is now accessible via the containing app as well which should allow for some interesting business applications.
When you grant full trust to a custom keyboard, you’re opening yourself up to a significantly larger risk that you probably bargained for.
In fact, this configuration is so ripe for abuse, that iOS 8 pops up the following warning. A warning so broad that it begs the question as to why this functionality exists in the first place:
Just so you didn’t have to, I downloaded every keyboard that was currently (24-Sep-2014) available in the Canadian App Store. There will be some that are US only and if you have tried one and can provided the data below, please reach out (@marknca) and I’ll add it to the table.
While all of these keyboards provide some level of functionality without enabling “Allow Full Trust”, I’ve made a note of which keyboards prompt the user to enable full trust. For the screenshots, the “Default Privilege” shows the default keyboard. For “Allow Full Trust” Enabled, I’ve selected a screenshot that shows the keyboards primary functionality.
|App||Prompts for full trust?||Default Privileges||"Allow Full Trust" Enabled|
This is very small sample size but based on the design limitations of the default sandbox, I have a feeling that more and more custom keyboards are going to require full trust.
The question I’ve been asked since the initial post the most is, “So what?” and then the questioner usually presents a use case where they aren’t worried about the information they are typing.
Not to pick on any specific keyboard but I’ll use Riffsy (the animated .gif keyboard) as an example. The casual user sees this as a simple way to spice up their text messages.
And while highlighting your emotional state with the perfect animated .gif is a lot of fun using a custom keyboard to do it poses some issues.
Riffsy conveniently provides a “standard” keyboard as well so you don’t have to switch back and forth between their keyboard and the default one. Of course everything you type into Riffsy can be sent back to their servers for “analysis”.
The counter argument is that you only use the animated .gif keyboard when required and the default keyboard the rest of the time. While clunky, this is a workable solution. Unfortunately it doesn’t address the security & privacy issues.
Any information in an input field that a custom keyboard can use should be considered accessible to the custom keyboard.
There’s no other logical way to approach this risk. That means the majority of the information in your day-to-day apps will be accessible to any custom keyboard you install and “Allow Full Trust”.
It’s rare that after a threat analysis that there is a definitely, broad use recommendation but that’s not the case here. My recommendation is simple:
Do not use any keyboard that requires “Allow Full Trust”.
If a custom keyboard does not require the elevated privilege of “Allow Full Trust” you can use it with a high degree of confidence that your keystroke and other personal data is safe.
Follow me (@marknca) if you enjoyed this post, found it useful, or want to yell at me ;-)
Guided Access is an accessibility feature that works to help you focus on a specific task. When this mode is enabled you can set specific areas on the screen as "off limits".
The interesting point here is that custom keyboards don't seem to respect Guided Access regardless of the level of trust.
During some quick testing, custom keyboards did not respect the disabled areas of the screen at either privilege level. The default iOS keyboard exhibit the desired behaviour. You can selectively disable *part* of the keyboard using Guided Access, custom keyboards don't appear to support this behaviour.
I don't have any data on if this is up to the developer to implement. Nor do I have any data on why you would want to disable only part of the keyboard ;-)