Security/Reviews/Gaia/Keyboard
Contents
App Review Details
- App: Gaia Keyboard App
- Review Date: 8 Feb 2013
- Review Lead: Paul Theriault
Overview
The Gaia keyboard app provides a virtual keyboard mechanism to other Apps. This app is unique in that it is overlaid over the top of other apps, which is not usually permitted. It uses the mozKeyboard API to listen for focus/blur events to show/hide itself, and uses the mozKeyboard.sendKey() method to send corresponding keyEvents to target app.
By the nature of being an integral system component, this app has extended privileges in order to function as a keyboard. If the keyboard was compromised it could: - send malicious key events to an app to control it (potentially modify or read data) - log key events (passwords etc)
For a background on the keyboard API, see https://wiki.mozilla.org/WebAPI/KeboardIME. Note: at the time of writing, this API isn't restricted by permissions, but a patch is in progress to require a permission to use this API (see bug)
Architecture
Components
The Keyboard App is implement as an privileged packaged Web App and is installed to the phone as part of the Gaia repository. The source code for the keyboard can be found here: http://mxr.mozilla.org/gaia/source/apps/keyboard/
The Keyboard is started automatically by the System App upon startup by Keyboard_Manager.js. See http://mxr.mozilla.org/gaia/source/apps/system/js/keyboard_manager.js#13
The keyboard runs inside a frame which has both mozbrowser and mozapp set. At the time of writing, the keyboard does NOT run out of process like other apps (that is, it runs inside the system app process).
Once the keyboard app is started it listens for onfocuschange events using the mozKeyboard API. On focus it appears, and is hidden on blur - this is achieved by changing the url hash, which is monitored by the system app (#show=… for showing, and #hide for hiding the keyboard. When the user taps a virtual key then the keyboard app uses mozKeyboard.sendKey() to send key presses to input fields etc.
Relevant Source Code
- Homescreen App http://mxr.mozilla.org/gaia/source/apps/homescreen/
- Everything.me http://mxr.mozilla.org/gaia/source/apps/homescreen/everything.me/
Permissions
The keyboard app requests the following permissions:
- "settings":{ "access": "readwrite" }
Once bug 838308 lands it will also have the 'keyboard' permission.
Web Activity Handlers
None
Web Activity Usage
None
Notable Event Handlers
- resize events (orientation changes)
- mouse events (over the keyboard)
- Input Methods - IME (which each have init() and click() methods)
- init() called on app on start up
- click() call when virtual key tapped
Code Review Notes
1. XSS & HTML Injection attacks
The keyboard app seems to use innerHTML unnecessarily in some places, where textContent could be used instead. However the only real inputs to the keyboard app are touch events - all key data is loaded from layouts.js. There may be a risk in the future when more layouts are supported, but at the moment there is not functionality which allows a user to define their own keyboard layouts. So for now no issues found, other than a recommendation to use textContent and DOM methods rather than innerHTML where possible.
2. Secure Communications
The keyboard app doesn't open any remote connections. The only loading that is done is spelling dictionaries are these are loaded locally.
3. Secure data storage
The keyboard doesn't store any user data or other sensitive information.
4. Denial of Service
Because the keyboard app is the global input device for all other apps, if an app was able to cause the keyboard app not to function.
Action: Fuzz/test malicious forms or other actions which generate inputs to the keyboard app in order to see test its resilience to malicious apps or web content.
5. Use of Privileged APIs
The Keyboard app only has the 'settings' and 'keyboard' permission. Keyboard is needed so that this app can function as a keyboard. The settings app permission (both read and write) is needed to in order to read and update locales settings.
6. Interfaces with other Apps/Content
The Keyboard app has a narrow interface in that the only real input is focus change events. In a sense, keyboard layout files are also input, however these are static and not user configurable.In terms of output, the keyboard app sends key events using mozKeyboard.sendKey to input fields. It also signals to the System app when it wants to be opened or closed, by settings the hash property of its location (which the system app observes changes too) No way to manipulate these inputs in either direction was found - apart from an app deliberately changing focus state, which is currently being tested (see 4 above)
Security Risks & Mitigating Controls
- Background app tries to grab focus, to steal key events from a foreground app
- How do we ensure that when keyboard app is shown, mozKeyboard.sendKey will be sending a key to the foreground app only ? (note, I have tried to break this through simulating focus and touch events but with no success, so it feels like this is prevented, but I would prefer to understand exactly what prevents this)
- On b2gdesktop, if an app has focus, with the keyboard open, it can maintain focus after the home screen is pressed by having an on blur handler. From then on, input typed with a keyboard ends up in the app that is background, until another app steals the keyboard app. Its weird to have key events going to a background app, but it doesn't really apply to a phone that doesn't have a keyboard. This might be something to think about down the track for a device that has a keyboard (either physical or paired etc).
- Simulate key presses over the virtual keyboar
No app should be able to send events to the keyboard( Does it run OOP? Or in the system app? )
- Coerce the user into pressing certain keys? (e.g. tapping game, then cause keyboard to appear when user isn't expecting it to get an accidental tap ?)
Not an issue if you can only cause the keyboard to show up over the user app.
- App implements its own keyboard to use instead (or just embed our keyboard)
Not a risk exactly, but I am interested if we have a policy on this - for example, an app could implement a keyboard so that