Closed
Bug 1245795
(CVE-2016-9061)
Opened 9 years ago
Closed 9 years ago
API Key (glocation) in broadcast protected with signature-level permission can be accessed by an application installed beforehand that defines the same permissions
Categories
(Firefox for Android Graveyard :: General, defect)
Tracking
(firefox49 wontfix, firefox-esr45 unaffected, fennec+, firefox50 fixed)
RESOLVED
FIXED
Firefox 50
Tracking | Status | |
---|---|---|
firefox49 | --- | wontfix |
firefox-esr45 | --- | unaffected |
fennec | + | --- |
firefox50 | --- | fixed |
People
(Reporter: kenken0980, Assigned: Grisha)
Details
(Keywords: reporter-external, sec-moderate, Whiteboard: [post-critsmash-triage][adv-main50+])
Attachments
(4 files, 2 obsolete files)
35.44 KB,
application/zip
|
Details | |
227.57 KB,
application/x-zip-compressed
|
Details | |
20.80 KB,
patch
|
nalexander
:
review+
|
Details | Diff | Splinter Review |
22.68 KB,
patch
|
nalexander
:
review+
|
Details | Diff | Splinter Review |
User Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.97 Safari/537.36
Steps to reproduce:
1. Launch an emulator (or device) whose API level is 19( or lower)
2. Install attached poc app (poc-apikey.apk) with adb
3. Install firefox for android (fennec) with adb
4. Launch and use firefox app
Actual results:
The poc app can receive a broadcast protedted with "org.mozilla.fennec.permission.PER_ANDROID_PACKAGE".
So, the poc app can read API Key in the broadcast.
Expected results:
The broadcast cannot be read from app whose signature is different from Mozilla's one.
Or the broadcast will change so that it does not have api key.
Updated•9 years ago
|
Flags: sec-bounty?
Updated•9 years ago
|
tracking-fennec: --- → ?
Ken, can you attach the source for your apk?
Flags: needinfo?(kenken0980)
Ah, source might not be very interesting. I guess the problem is that the poc app declares the permission first, and this somehow confuses the Android permission system. The Fennec permission protection is set to 'signature', but apparently that is not respected if the permission has already been declared elsewhere. Not sure what we can really do about this.
Flags: needinfo?(kenken0980)
There is a good description of the problem here: http://blog.trendmicro.com/trendlabs-security-intelligence/android-custom-permissions-leak-user-data/
This does appear to be a bug in Android, but we may be able to work around it by adding UID checks.
Actually, since we're broadcasting an intent here, I don't know if there is anything we can do other than not broadcast this...
This is the same as Bug 1229681, and I'm irritated that I didn't address these usages at the same time.
It's easy to address, though: make everything android:exported="false" as appropriate and remove the permissions.
This is a hold-over from the android-sync github repo days, when we had (mostly during development) multiple packages communicating in this way; and from the Old Sync days, when the account type was shared between Android packages. That's no longer the case, so this can be addressed more simply.
Assignee: nobody → nalexander
tracking-fennec: ? → +
Reporter | ||
Comment 6•9 years ago
|
||
(In reply to James Willcox (:snorp) (jwillcox@mozilla.com) from comment #1)
> Ken, can you attach the source for your apk?
Hi, James
Here is my poc source code.
Reporter | ||
Comment 7•9 years ago
|
||
Here is my poc source code.
Updated•9 years ago
|
Status: UNCONFIRMED → NEW
Ever confirmed: true
Reporter | ||
Comment 8•9 years ago
|
||
(In reply to Nick Alexander :nalexander from comment #5)
> This is the same as Bug 1229681, and I'm irritated that I didn't address
> these usages at the same time.
>
> It's easy to address, though: make everything android:exported="false" as
> appropriate and remove the permissions.
As you point out, this is the same as Bug 1229681 from an attacker.
but I think it is only a little different in the perspective of countermeasure.
In Bug 1229681, the receiver must be modified so that it refuse access from other application.(e.g. exported="false")
In this bug, the sender must be corrected so that other application cannot access the intent which is thrown by the sender. (e.g. LocalBroadcastManager)
(In reply to Ken Okuyama from comment #8)
> (In reply to Nick Alexander :nalexander from comment #5)
> > This is the same as Bug 1229681, and I'm irritated that I didn't address
> > these usages at the same time.
> >
> > It's easy to address, though: make everything android:exported="false" as
> > appropriate and remove the permissions.
>
> As you point out, this is the same as Bug 1229681 from an attacker.
> but I think it is only a little different in the perspective of
> countermeasure.
>
> In Bug 1229681, the receiver must be modified so that it refuse access from
> other application.(e.g. exported="false")
>
> In this bug, the sender must be corrected so that other application cannot
> access the intent which is thrown by the sender. (e.g. LocalBroadcastManager)
Meh, a distinction without a difference. This is part of a larger, long running project of separating Beta/Release and Aurora/Fennec apart. Most of these things are holdovers from when we expected to really share data; that idea is dead. We'll just do everything locally, android:exported="false", LocalBroadcastManager, and not worry about the signature permissions at all.
Status: NEW → ASSIGNED
Updated•9 years ago
|
Keywords: sec-moderate
Comment 10•9 years ago
|
||
Nick won't be able to fix this any time soon. Grisha, could you look into this?
Flags: needinfo?(gkruglov)
Assignee | ||
Updated•9 years ago
|
Assignee: nalexander → gkruglov
Flags: needinfo?(gkruglov)
Comment 11•9 years ago
|
||
Grisha, any updates on this security bug? It has been a month.
Flags: needinfo?(gkruglov)
To address this, we need to remove the PER_ANDROID_PACKAGE permission at https://dxr.mozilla.org/mozilla-central/source/mobile/android/base/FennecManifest_permissions.xml.in#24.
First, expunge all traces of OrderedBroadcastHelper. It's a nice hook into the Android system, but it's never been used and is a security vulnerability waiting to happen. That's one consumer of PER_ANDROID_PACKAGE gone.
Second, the interaction with the stumbler at https://dxr.mozilla.org/mozilla-central/source/mobile/android/base/java/org/mozilla/gecko/preferences/GeckoPreferences.java#1013. I think we can use the LocalBroadcastManager, or invoke the service directly. In both cases the stumbler receiver needs to be split into the external intents and this internal intent (see https://dxr.mozilla.org/mozilla-central/source/mobile/android/stumbler/java/org/mozilla/mozstumbler/service/mainthread/PassiveServiceReceiver.java#57 and https://dxr.mozilla.org/mozilla-central/source/mobile/android/stumbler/manifests/StumblerManifest_services.xml.in#13).
Be aware that the stumbler can be compiled out of Fennec, so it's not easy to invoke the service directly *without an Intent filter*, because the stumbler service class may not present. (I think the build system enforces this, probably crudely!) Therefore, I think the path is to split the receiver, and then wire up the LBM listener. Unfortunately, there's no good way for Fennec to talk to the stumbler, for exactly the build system reasons above! So I'd suggest sending a "safe" Intent on Fennec app startup to the stumbler telling it to register the LBM listener, and then using the LBM broadcast. (By safe I mean a broadcast that others can trigger and it'll just set up a listener, and even then only once. If Android gives a way to figure out that your own APp has been launched, this would work -- but I don't think it does.) That should work even when the stumbler isn't compiled into Fennec.
Assignee | ||
Comment 13•9 years ago
|
||
First pass.
Flags: needinfo?(gkruglov)
Attachment #8767815 -
Flags: review?(nalexander)
Assignee | ||
Comment 14•9 years ago
|
||
Pre: Purge OrderedBroadcast
Attachment #8767815 -
Attachment is obsolete: true
Attachment #8767815 -
Flags: review?(nalexander)
Attachment #8768099 -
Flags: review?(nalexander)
Assignee | ||
Comment 15•9 years ago
|
||
Part1: Split Stumbler BroadcastReceivers into Local, System and Safe
SafeReceiver is responsible for registering LocalReceiver with a LocalBroadcastManager.
SystemReceiver is responsible for handling BOOT_COMPLETE and EXTERNAL_APPLICATIONS_AVAILABLE intents.
LocalReceiver is responsible for handling passed in Stumbler preferences (enabled state, API key, user agent).
StumblerPreferences are now sent using LocalBroadcastManager, avoiding any possibility of leaking API key.
Attachment #8768101 -
Flags: review?(nalexander)
Comment on attachment 8768099 [details] [diff] [review]
no-package-permission-pre1.patch
Review of attachment 8768099 [details] [diff] [review]:
-----------------------------------------------------------------
So sad. If it works for you, it works for me!
Attachment #8768099 -
Flags: review?(nalexander) → review+
Comment on attachment 8768101 [details] [diff] [review]
no-package-permission-part1.patch
Review of attachment 8768101 [details] [diff] [review]:
-----------------------------------------------------------------
This is looking solid. I have a few nits and a few small issues, but overall this is fine. Test plan must include enabling/disabling the stumbler, and ensuring that we can build with the stumbler off. (This might not be trivial, since we don't build the stumbler off in automation these days.)
I would like to see a "messaging diagram" in comments, which probably should go in `StumblerManifest_services.xml.in`. Something like:
Application.onCreate -> system broadcast STUMBLER_PREF. This broadcast decouples the Fennec App from the Stumbler internal library. Most systems would use dependency injection mechanism or a message bus for this; we use the system.
Stumbler receives STUMBLER_PREF, registers local broadcast receiver. It's safe for other apps to maliciously send STUMBLER_PREF -- this doesn't turn things on or off, just (duplicates) the listener, potentially before Fennec even starts.
Fennec starts or Fennec toggles pref -> local broadcast on/off with sensitive information.
Stumbler receives local broadcast on/off with sensitive information, adjusts internal state.
::: mobile/android/stumbler/java/org/mozilla/mozstumbler/service/mainthread/SafeReceiver.java
@@ +21,5 @@
> +
> + private boolean registeredLocalReceiver = false;
> +
> + @Override
> + public void onReceive(Context context, Intent intent) {
Either synchronize this method, or explain why this doesn't need to be synchronized. (I think it does need to be synchronized :))
::: mobile/android/stumbler/java/org/mozilla/mozstumbler/service/mainthread/SystemReceiver.java
@@ +25,5 @@
> + }
> +
> + final String action = intent.getAction();
> +
> + if (!action.equals(Intent.ACTION_BOOT_COMPLETED) && !action.equals(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE)) {
In general, `TextUtils.equals` or constant first -- this will NPE if action is null. (Which might not be possible, but we've seen *all kinds* of Intents.)
::: mobile/android/stumbler/manifests/StumblerManifest_services.xml.in
@@ +5,5 @@
>
> <receiver android:name="org.mozilla.mozstumbler.service.uploadthread.UploadAlarmReceiver" />
> <service android:name="org.mozilla.mozstumbler.service.uploadthread.UploadAlarmReceiver$UploadAlarmService" />
>
> +<receiver android:name="org.mozilla.mozstumbler.service.mainthread.SafeReceiver">
This can be `android:exported="false"`, right?
@@ +12,4 @@
> </intent-filter>
> </receiver>
> +
> +<receiver android:name="org.mozilla.mozstumbler.service.mainthread.SystemReceiver">
This should be `android:exported="true"` for clarity, right?
Attachment #8768101 -
Flags: review?(nalexander) → review+
Assignee | ||
Comment 18•9 years ago
|
||
Addressed feedback for patch: Split Stumbler BroadcastReceivers into Local, System and Safe
Attachment #8768101 -
Attachment is obsolete: true
Attachment #8769021 -
Flags: review?(nalexander)
Comment on attachment 8769021 [details] [diff] [review]
no-package-permission-part1.patch
Review of attachment 8769021 [details] [diff] [review]:
-----------------------------------------------------------------
If it works for you, it works for me! Good job on these sec patches.
Attachment #8769021 -
Flags: review?(nalexander) → review+
Assignee | ||
Comment 20•9 years ago
|
||
https://hg.mozilla.org/integration/fx-team/rev/3687f36b1f85c09aaa4c47c99a3286fd7975b9ff
Bug 1245795 - Pre: Purge OrderedBroadcast r=nalexander
https://hg.mozilla.org/integration/fx-team/rev/97ac5877d152245c846ce052f2a60e2a250f6b72
Bug 1245795 - Split Stumbler BroadcastReceivers into Local, System and Safe r=nalexander
Comment 21•9 years ago
|
||
https://hg.mozilla.org/mozilla-central/rev/3687f36b1f85
https://hg.mozilla.org/mozilla-central/rev/97ac5877d152
Status: ASSIGNED → RESOLVED
Closed: 9 years ago
status-firefox50:
--- → fixed
Resolution: --- → FIXED
Target Milestone: --- → Firefox 50
Comment 22•9 years ago
|
||
The bounty on bug 1229681 was higher than justified by the rating/impact (too much holiday partying?) but we shouldn't hold that against this bug: this gets a bounty too.
Flags: sec-bounty? → sec-bounty+
Updated•9 years ago
|
Group: firefox-core-security → core-security-release
Updated•8 years ago
|
Flags: qe-verify-
Whiteboard: [post-critsmash-triage]
Updated•8 years ago
|
status-firefox49:
--- → wontfix
status-firefox-esr45:
--- → unaffected
Whiteboard: [post-critsmash-triage] → [post-critsmash-triage][adv-main50+]
Updated•8 years ago
|
Alias: CVE-2016-9061
Updated•8 years ago
|
Group: core-security-release
Updated•4 years ago
|
Product: Firefox for Android → Firefox for Android Graveyard
Updated•9 months ago
|
Keywords: reporter-external
You need to log in
before you can comment on or make changes to this bug.
Description
•