dbm
dbm

Reputation: 10485

Sync adapter service exported but unprotected

Fellow Developers!

I have a sync adapter in my app and a corresponding sync service. I have declared everything, including the sync service, according to Google example code. The greater picture looks something like this:

<service
    android:name="com.myapp.SyncService"
    android:exported="true"
    android:process=":sync">

    <intent-filter>
        <action
            android:name="android.content.SyncAdapter"/>
    </intent-filter>

    <meta-data
        android:name="android.content.SyncAdapter"
        android:resource="@xml/syncadapter" />

</service>

While it makes sense to set the android:exported attribute to true on the service (enabling the Android system to reach it), I'm a bit puzzled on how to tie it down in terms of access rights. I don't want anyone else but my app and the Android system to have access to the service.

Maybe a bit naively I have created my own permission for this:

<permission
    android:name="com.myapp.permission.SYNC_ADAPTER"
    android:protectionLevel="signatureOrSystem" />

But reading up a bit on the protectionLevel makes me wonder even more. Google says:

Please avoid using this option [...] "signatureOrSystem" permission is used for certain special situations where multiple vendors have applications built into a system image and need to share specific features explicitly because they are being built together.

The described scenario is far from my use case. The question then remains:

How do I secure my sync service so that the Android system, but no third party apps, can access it?

Any clarification would be greatly appreciated!

Upvotes: 11

Views: 962

Answers (5)

hb0
hb0

Reputation: 3737

You can safely set exported=false for both services

  • one service registering to the SyncAdapter
  • one service registering to the AccountAuthenticator intents

The system can still call the SyncAdapter Service via intents.

  • The reason why this works is mentioned in the official exported guide

If false, the activity can be launched ... [by] privileged system components.

I.e. you don't need to struggle with exported=true.

  • tested on Android 10 (Emulator with targetVersion: 30)
  • tested on Android 13 (with targetVersion: 31)

Old answer

The following is (for me) irrelevant as the above works.

I interpreted the replies in this thread this way:

  • Requesting this permission (see example) in an exported service (see below) should only allow apps signed with your signature - and the system - to call this service.

  • If you use exported=false then the system cannot call your service, i.e. Synchronization won't start if your app is closed(?)

    <permission
        android:name="com.myapp.USE_SYNC_AND_AUTHENTICATOR"
        android:protectionLevel="signature" />

    <application>
        <!-- Export sync and auth to allow the Android System to call them. -->
        <!-- Protect it using a signature permission.  -->
        <service
            android:name="com.myapp.SyncService"
            android:exported="true"
            android:process=":sync"
            android:permission="com.myapp.USE_SYNC_AND_AUTHENTICATOR">
            <intent-filter>
                <action android:name="android.content.SyncAdapter" />
            </intent-filter>
            <meta-data
                    android:name="android.content.SyncAdapter"
                    android:resource="@xml/sync_adapter" />
        </service>
        <service>..authenticator..</service>
    </application>

Upvotes: 1

rogup
rogup

Reputation: 1

The 'signature' protection level should be sufficient for your use case, which grants access to the system package. 'signatureOrSystem' also grants access to apps built into the system image.

Source code: see grantSignaturePermission() method https://android.googlesource.com/platform/frameworks/base/+/a029ea1/services/java/com/android/server/pm/PackageManagerService.java

Upvotes: 0

BLeB
BLeB

Reputation: 1746

It doesn't look like there is a SyncAdapter permission. I'm guessing that we can safely ignore the error. See the bug filed here: https://code.google.com/p/android/issues/detail?id=37280

Upvotes: 0

dmapr
dmapr

Reputation: 359

beworker is quite right. I have used signature permission and the system is able to sync without any trouble.

Upvotes: 3

Eric Woodruff
Eric Woodruff

Reputation: 6410

I have the same problem. Looking at this example source code here as a guide https://android.googlesource.com/platform/packages/apps/Exchange/+/ics-mr0/AndroidManifest.xml it seems to be that the sync adapters have plainly exported="true" without any permissions.

Upvotes: 0

Related Questions