android - "Exportierter Empfänger benötigt keine Erlaubnis" für Empfänger, die von Systemdiensten empfangen sollen

70

Ich habe einige Empfänger in meinem AndroidManifest deklariert:

<!-- no warning -->
<receiver
    android:name=".receivers.TriggerMonitoringBootReceiver"
    android:enabled="false">
    <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED" />
    </intent-filter>
</receiver>

<!-- no warning -->
<receiver
    android:name=".receivers.ScanResultsReceiver"
    android:enabled="false">
    <intent-filter>
        <action android:name="android.net.wifi.SCAN_RESULTS" />
    </intent-filter>
</receiver>

<!-- warning : Exported receiver does not require permission-->
<receiver
    android:name=".receivers.BatteryMonitoringReceiver"
    android:enabled="false">
    <intent-filter>
        <action android:name="@string/intent_action_setup_alarm" />
        <action android:name="@string/intent_action_cancel_alarm" />
        <action android:name="@string/intent_action_monitor" />
    </intent-filter>
</receiver>

Der erste soll eine BOOT_COMPLETEDAktion erhalten. Der zweite soll empfangen android.net.wifi.SCAN_RESULTS. Die dritte soll einige Aktionen empfangen, die ich gesendet habe (intent_action_monitor), und einige Aktionen, die vom AlarmManager(intent_action_setup_alarm usw.) gesendet werden .

Zwei Fragen:

  • Warum erhalte ich nicht die Warnung auf allen Empfängern?
  • Welche Berechtigungen muss ich für Empfänger festlegen , die von Systemdiensten empfangen werden sollen, um die Warnung zu korrigieren (ich verstehe, worum es geht, und ich möchte sowieso nicht, dass jemand meine Empfänger verwendet)? Werden exported="false" Sie für die Boot - Empfänger, Wi - Fi - Empfänger, Alarmempfänger usw. ?
    Ich habe überlegt, eine benutzerdefinierte Berechtigung mit zu verwenden, android:protectionLevel="signatureOrSystem"aber die Dokumente raten sowohl von dieser Schutzstufe als auch von benutzerdefinierten Berechtigungen ab . Wie soll ich mit dieser Warnung umgehen?

Links zu den Dokumenten und / oder einem Code werden sehr geschätzt.

Mr_and_Mrs_D
quelle

Antworten:

67

Warum erhalte ich nicht die Warnung auf allen Empfängern?

Denn die ersten beiden sind eindeutig für die Ausstrahlung durch Android konzipiert. Der letzte ist unbekannt, teilweise weil Sie die Zeichenfolgenressourcenwerte nicht angegeben haben und möglicherweise weil es sich um Ihre eigenen eindeutigen Aktionszeichenfolgen handelt.

Welche Berechtigungen muss ich für Empfänger festlegen, die von Systemdiensten empfangen werden sollen, um die Warnung zu korrigieren

Die richtige Lösung ist das Löschen der <intent-filter>. Wenn Sie diese senden Intentsoder ein Intentin ein getBroadcast() PendingIntenteinschließen, benötigen Sie keine Aktionszeichenfolgen. Verwenden Sie den IntentKonstruktor, der das Java-Klassenobjekt als zweiten Parameter verwendet, und verwenden Sie Folgendes:

new Intent(this, BatteryMonitoringReceiver.class)

Sie können dem gerne eine Aktionszeichenfolge hinzufügen Intent, wenn Sie möchten, aber Sie können die sichern <intent-filter>(das Routing basiert auf der bereitgestellten Komponente, in diesem Fall der Java-Klasse).

Verwenden Sie eine nur, <intent-filter>wenn Sie erwarten, dass das Betriebssystem oder Apps von Drittanbietern sich selbst initiieren Intent(die Ausführung einer von PendingIntentIhnen erstellten Anwendung zählt nicht).

CommonsWare
quelle
Oh Danke ! Nur um ganz klar zu sein: " Die ersten beiden sind eindeutig für die Ausstrahlung durch Android konzipiert. " Ich dachte schon, aber sie werden immer noch exportiert, nicht wahr? - Wenn ich also die Absichten lösche, gibt es immer noch eine Möglichkeit, wie jemand die Empfänger verwenden kann - macht das Hinzufügen exported="false"einen Unterschied? (Nebenbei: Ich benötige die Aktionen, aber Ihre Klarstellung "Verwenden Sie einen <intent-filter> nur, wenn Sie erwarten, dass das Betriebssystem oder Apps von Drittanbietern den Intent selbst initiieren (das Ausführen eines von Ihnen erstellten PendingIntent zählt nicht)." Ist sehr wichtig sehr willkommen - +1)
Mr_and_Mrs_D
1
@Mr_and_Mrs_D: Sie erhalten keine Warnung zu den ersten beiden, daher konzentriert sich meine Antwort auf die dritte. "Ich dachte schon, aber sie werden immer noch exportiert, nicht wahr?" -- Ja. "Wenn ich also die Absichten lösche, gibt es immer noch eine Möglichkeit, wie jemand die Empfänger verwenden kann" - da Sie für diese keine Warnungen erhalten, lassen Sie sie in Ruhe.
CommonsWare
Ich frage mich, ob es nützlich ist, eine benutzerdefinierte Erlaubnis zu erteilen. Genau wie die Aktion der Absicht. Ich kann Dekompilierungswerkzeuge verwenden, um die Datei manifest.xml zu extrahieren und den Aktionsnamen zu lesen. Dann kann der Name der Erlaubnis auch das gleiche Gesicht haben ...
Yeung
34

Die Warnung "Exportierter Empfänger benötigt keine Berechtigung" bedeutet, dass Sie eine intent-filterAktion ausführen (was bedeutet, dass Sie standardmäßig festgelegt haben android:exported="true"und dies jetzt receive broadcastsvon JEDEN Sendern außerhalb Ihrer Anwendung möglich ist application). Da dies receive broadcastsvon JEDEM broadcastersaußerhalb Ihrer Anwendung möglich ist, werden Sie gewarnt mit den Worten „Hey, bist du sicher , dass jeder Fernsehveranstalter können Sie aufrufen? meiner Meinung nach ist es besser , wenn man nur diejenigen , erlauben broadcastersSie aufzurufen, muss die permissionSie für diese festgelegt haben receiverdurchandroid:permission"

Sie können diese Warnung entfernen, indem Sie android:exported="false"sie dem Empfänger-Tag hinzufügen

AndroidGeek
quelle
24

Wenn Sie Ihren Empfänger in andere Prozesse exportieren möchten, können Sie Ihre eigene Berechtigungsdefinition in Ihre Android-Manifest-Datei einfügen, um diese Warnung zu vermeiden

<permission
    android:name="com.yourpage.permission.YOUR_PERMISSION"
    android:protectionLevel="normal" />

<uses-permission
    android:name="com.yourpage.permission.YOUR_PERMISSION" />

<receiver <!-- warning : Exported receiver does not require permission-->
    android:name=".receivers.BatteryMonitoringReceiver"
    android:permission="com.yourpage.permission.YOUR_PERMISSION"
    android:enabled="false" >
    <intent-filter>
        <action android:name="@string/intent_action_setup_alarm" />
        <action android:name="@string/intent_action_cancel_alarm" />
        <action android:name="@string/intent_action_monitor" />
    </intent-filter>
</receiver> 

Weitere Informationen finden Sie unter http://developer.android.com/training/articles/security-tips.html

Lubo
quelle
1
Dies ist eine korrekte Lösung, wenn Sie Ihre eigene Erlaubnis deklarieren müssen. In der offiziellen Dokumentation wird jedoch empfohlen: "Das Erstellen einer neuen Berechtigung ist für die meisten Anwendungen relativ selten, da die systemdefinierten Berechtigungen viele Situationen abdecken." Sie sollten die systemdefinierte Liste überprüfen: developer.android.com/reference/android/…
Cuddlecheek
4

Wenn Sie wie ich hier sind, weil Ihre mit einer früheren SDK-Version erstellte App nicht mehr mit neueren Versionen funktioniert und Sie sie mit minimalen Änderungen beheben möchten, fügen Sie einfach hinzu

android: exportiert = falsch

an das Empfänger-Tag in der Manifest-Datei. Die Lösung von CommonsWare ist natürlich die langfristige Lösung, aber dies behebt das Problem vorübergehend, wenn Sie benutzerdefinierte Absichten verwenden und diese nicht exportieren möchten.

Nach Lubos Art müssten Sie diese benutzerdefinierte Berechtigung exportieren, die den Benutzer vor der Installation auffordert. Das bedeutet, dass der beschreibende Text für die Berechtigung gut geschrieben sein muss, damit Sie den Benutzer nicht dazu bringen, seine Meinung über die Installation der App zu ändern. Außerdem müsste es in alle Ihre Zielsprachen übersetzt werden.

navjotk
quelle