android-security-lints icon indicating copy to clipboard operation
android-security-lints copied to clipboard

MissingAutoVerifyAttribute contradicts AppLinkUrlError rule

Open G00fY2 opened this issue 8 months ago • 3 comments

So we use Android lint shipped with AGP (currently 8.10.0) and the lint checks provided by com.android.security.lint:lint::1.0.3.

Currently we use a custom scheme for intent filters in our app. This is intended and a requirement for us.

We get the following warning (from android.security.lint), because we do not set autoVerify attribute for this intent filter: MissingAutoVerifyAttribute

When we add autoVerify="true" we run into this lint warning from AGP: AppLinkUrlError

http(s) scheme and host attribute are missing, but are required for Android App Links

So not sure if makes sense that these rules somewhat contradict each other.

G00fY2 avatar May 14 '25 06:05 G00fY2

Interesting. Could you clarify where you've added the autoVerify attribute, what's inside the intent filter, and where the two lint warnings are specifically appearing? Also, could you clarify whether you're intending to implement app linking for this particular intent-filter or not (and this is a false positive for the MissingAutoVerifyAttribute lint check)? There's also more information here about app links here that may be helpful: https://developer.android.com/training/app-links/verify-android-applinks

The autoVerify attribute should only be added to the outer-most intent-filter component (<intent-filter autoVerify="true">) and not anything within it (e.g. action, category, data). Please let me know if the lint warning is suggesting you add it somewhere else.

I can't tell right now if the issue is a false positive with the MissingAutoVerifyAttribute lint check or the AppLinkUrlError one, so this additional information would be helpful. Thanks!

bjiang7 avatar May 29 '25 17:05 bjiang7

@bjiang7 sorry, I should have added the Manifest file directly. Just wasn't sure if it would add any benefits, since it's quit simple:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
    <uses-permission android:name="com.google.android.gms.permission.AD_ID" />

    <application
        android:name=".ExampleApp"
        android:allowBackup="true"
        android:fullBackupContent="@xml/backup_rules"
        android:dataExtractionRules="@xml/data_extraction_rules"
        android:enableOnBackInvokedCallback="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/example_app_name"
        android:supportsRtl="false"
        android:theme="@style/Theme.Example"
        android:usesCleartextTraffic="false"
        tools:replace="android:supportsRtl"
        tools:targetApi="tiramisu">

        <activity
            android:name=".ui.main.MainActivity"
            android:configChanges="uiMode"
            android:exported="true"
            android:launchMode="singleTask"
            android:permission=""
            android:screenOrientation="portrait"
            android:theme="@style/Theme.App.Starting"
            android:windowSoftInputMode="adjustPan"
            tools:ignore="DiscouragedApi">

            <meta-data
                android:name="android.app.shortcuts"
                android:resource="@xml/shortcuts" />

            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>

            <intent-filter>
                <action android:name="${applicationId}.intent.action.PUSH_NOTIFICATION" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>

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

                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />

                <data android:scheme="exampleapp" />
            </intent-filter>
        </activity>

        <service
            android:name="androidx.appcompat.app.AppLocalesMetadataHolderService"
            android:enabled="false"
            android:exported="false">
            <meta-data
                android:name="autoStoreLocales"
                android:value="true" />
        </service>

        <meta-data
            android:name="com.emarsys.mobileengage.small_notification_icon"
            android:resource="@drawable/ic_notification" />

        <meta-data
            android:name="com.google.firebase.messaging.default_notification_icon"
            android:resource="@drawable/ic_notification" />

        <provider
            android:name="io.sentry.android.core.SentryInitProvider"
            android:authorities="${applicationId}.SentryInitProvider"
            tools:node="remove" />

        <provider
            android:name="io.sentry.android.core.SentryPerformanceProvider"
            android:authorities="${applicationId}.SentryPerformanceProvider"
            tools:node="remove" />

        <provider
            android:name="androidx.core.content.FileProvider"
            android:authorities="${applicationId}.fileprovider"
            android:exported="false"
            android:grantUriPermissions="true"
            tools:node="merge">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/files" />
        </provider>

        <provider
            android:name="androidx.startup.InitializationProvider"
            android:authorities="${applicationId}.androidx-startup"
            android:exported="false"
            tools:node="merge">
            <meta-data
                android:name="androidx.work.WorkManagerInitializer"
                android:value="androidx.startup"
                tools:node="remove" />
        </provider>
    </application>

</manifest>

I was referring to the last intent-filter, which has the custom scheme.

Here android.security.lint wants us to add the autoVerify attribute:

<intent-filter android:autoVerify="true">
    <action android:name="android.intent.action.VIEW" />

    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />

    <data android:scheme="exampleapp" />
</intent-filter>

But this then causes AppLinkUrlError.

G00fY2 avatar Jun 03 '25 12:06 G00fY2

The implementation of this lint rule contradicts the official documentation. The official documentation states that the autoVerify attribute only takes effect for http/https and cannot be used with custom schemas. Therefore, this detector should not report issues for custom schemas. This lint check should specifically target http/https intent filters, rather than all non-standard schemas. The detector implementation in this security lint library contains a logical error and needs to be corrected to check the autoVerify attribute only for http/https schemas.

MrZJ avatar Oct 24 '25 08:10 MrZJ