亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Android開(kāi)發(fā)中關(guān)于組件導(dǎo)出的風(fēng)險(xiǎn)及防范

 更新時(shí)間:2021年09月10日 08:58:08   作者:小混球  
這篇文章主要介紹了Android開(kāi)發(fā)中關(guān)于組件導(dǎo)出的風(fēng)險(xiǎn)及防范,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下

前言

近年來(lái),移動(dòng)APP存在一個(gè)非常的重要的問(wèn)題就是安全問(wèn)題,造成的后果有可能是用戶(hù)的隱私泄露和財(cái)產(chǎn)損失等,對(duì)于一款成熟的APP或者是金融銀行類(lèi)APP,這無(wú)疑是最致命的,所以對(duì)APP進(jìn)行有效的防范也是很有必要。
近段時(shí)間,公司安排了某安全公司對(duì)我們的APP進(jìn)行了全方面的安全測(cè)試,根據(jù)文檔檢測(cè)結(jié)果看,整體上看還是很安全的,其中有一項(xiàng)就是組件導(dǎo)出風(fēng)險(xiǎn),接下來(lái)我們說(shuō)說(shuō)四大組件、組件導(dǎo)出必要性、風(fēng)險(xiǎn)以及如何防范。

一、四大組件

從事Android開(kāi)發(fā),我們都知道Android有四大組件, 分別是:

  • 活動(dòng)(Activity),用于表現(xiàn)功能,是用戶(hù)操作的可視化界面,它為用戶(hù)提供了一個(gè)完成操作指令的窗口;
  • 服務(wù)(Service),后臺(tái)運(yùn)行服務(wù),不提供界面呈現(xiàn);
  • 廣播接受者(Broadcast Receive),用于接收廣播;
  • 內(nèi)容提供者(Content Provider),支持多個(gè)應(yīng)用中存儲(chǔ)和讀取數(shù)據(jù),相當(dāng)于數(shù)據(jù)庫(kù)。

從這些組件簡(jiǎn)單的介紹,我們知道它們的重要性,賦予了app更加豐富的功能,所以這四大組件的安全性對(duì)我們app和用戶(hù)來(lái)說(shuō)就顯得更加地重要。

二、組件導(dǎo)出必要性

什么是組件導(dǎo)出呢?組件導(dǎo)出的意思就是組件可以被外部應(yīng)用調(diào)用,我們可以在這四大組件聲明的清單文件設(shè)置組件是否導(dǎo)出,如下:

        <activity
            android:exported="true"
            android:name=".other.ComponentActivity">
        </activity>

或者:

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

上面兩種方式都是Activity組件導(dǎo)出的方式,主要是exported的值",為true時(shí)表示導(dǎo)出,Activity中exported的默認(rèn)值:

  • 沒(méi)有intent filter時(shí),默認(rèn)為false;
  • 有intent filter時(shí),默認(rèn)為true

Broadcast Receive和Service的默認(rèn)值都跟Activity的一樣。

Content Provider中exported的默認(rèn)值:

  •  當(dāng)minSdkVersion或者targetSdkVersion小于16時(shí),默認(rèn)為true
  • 大于17時(shí),默認(rèn)為false

開(kāi)發(fā)過(guò)程中,app會(huì)有一些特定需求會(huì)使用到三方SDK,如微信分享、支付、推送等功能,我們發(fā)現(xiàn)這里都有一個(gè)共同點(diǎn),都會(huì)涉及到組件導(dǎo)出的問(wèn)題,如微信的

WXEntryActivity:

        <!-- 微信分享 -->
        <activity
            android:name="${applicationId}.wxapi.WXEntryActivity"
            android:exported="true"
            android:launchMode="singleTask"
            android:theme="@android:style/Theme.Translucent.NoTitleBar" />

這樣就會(huì)被安全機(jī)構(gòu)檢測(cè)出來(lái)的,如果不設(shè)置WXEntryActivity為組件導(dǎo)出,微信分享等功能根本就調(diào)不起來(lái),這是官方的寫(xiě)法,我們認(rèn)為這是必須要設(shè)置為組件導(dǎo)出,除非你把微信分享需求干掉,那業(yè)務(wù)不把你罵死;又或者是監(jiān)聽(tīng)網(wǎng)絡(luò)變化的廣播接收器(7.0版本以上只能代碼中動(dòng)態(tài)注冊(cè)才能接收該廣播)、推送功能,集成過(guò)一些推送SDK都有印象,一些Service也會(huì)聲明android:exported="true"等等。
這些無(wú)可避免的組件導(dǎo)出,我們可以回復(fù)安全機(jī)構(gòu):微信分享、推送等功能必須設(shè)置組件導(dǎo)出,所以我們只有保證自己的四大組件的設(shè)置,確保其是安全的,這樣才能確保app處于比較安全的狀態(tài),應(yīng)付安全檢測(cè),給你的領(lǐng)導(dǎo)一個(gè)交代。

三、組件導(dǎo)出風(fēng)險(xiǎn)

前面說(shuō)明了組件的重要性、組件導(dǎo)出,那么組件導(dǎo)出的風(fēng)險(xiǎn)是什么呢?

  • Activity作為組成Apk的四個(gè)組件之一,是Android程序與用戶(hù)交互的界面,如果Activity打開(kāi)了導(dǎo)出權(quán)限,可能被系統(tǒng)或者第三方的App直接調(diào)出并使用。Activity導(dǎo)出可能導(dǎo)致登錄界面被繞過(guò)、拒絕服務(wù)攻擊、程序界面被第三方惡意調(diào)用等風(fēng)險(xiǎn)。
  • Broadcast Receiver作為組成Apk的四個(gè)組件之一,對(duì)外部事件進(jìn)行過(guò)濾接收,并根據(jù)消息內(nèi)容執(zhí)行響應(yīng),如果設(shè)置了導(dǎo)出權(quán)限,可能被系統(tǒng)或者第三方的App直接調(diào)出并使用。Broadcast Receiver導(dǎo)出可能導(dǎo)致敏感信息泄露、登錄界面被繞過(guò)等風(fēng)險(xiǎn)。S
  • ervice作為組成Apk的四個(gè)組件之一,一般作為后臺(tái)運(yùn)行的服務(wù)進(jìn)程,如果設(shè)置了導(dǎo)出權(quán)限,可能被系統(tǒng)或者第三方的App直接調(diào)出并使用。Service導(dǎo)出可能導(dǎo)致拒絕服務(wù)攻擊,程序功能被第三方惡意調(diào)用等風(fēng)險(xiǎn)。
  • Content Provider組成Apk的四個(gè)組件之一,是應(yīng)用程序之間共享數(shù)據(jù)的容器,可以將應(yīng)用程序的指定數(shù)據(jù)集提供給第三方的App,如果設(shè)置了導(dǎo)出權(quán)限,可能被系統(tǒng)或者第三方的App直接調(diào)出并使用。Content Provider導(dǎo)出可能導(dǎo)致程序內(nèi)部的敏感信息泄露,數(shù)據(jù)庫(kù)SQL注入等風(fēng)險(xiǎn)。

接下來(lái)以Activity導(dǎo)出為示例,說(shuō)明下其風(fēng)險(xiǎn),其它組件類(lèi)比就好。首先Activity要在清單文件AndroidManifest.xml注冊(cè):

        <activity android:name="com.littlejerk.sample.other.WebActivity"/>

Activity的啟動(dòng)通常有兩種方法

  • 顯式啟動(dòng),需要指定啟動(dòng)的Activity:
        Intent intent = new Intent(getContext(),WebActivity.class);
        intent.putExtra("URL","https://blog.csdn.net");
        startActivity(intent);
        
  • 隱式啟動(dòng),Intent中不再包含需要啟動(dòng)的具體的Activity類(lèi),而是通過(guò)Intent提供某些信息,系統(tǒng)去檢索符合啟動(dòng)意圖的Activity,這里是通過(guò)意圖過(guò)濾器聲明Intent信息:動(dòng)作(action)、數(shù)據(jù)(data)、分類(lèi)(Category)、類(lèi)型(Type),組件(Component)、和擴(kuò)展信息(Extra)。
        <!-- 通過(guò)隱式啟動(dòng)的方式需要在AndroidManifest.xml文件聲明-->
        <activity android:name=".other.WebActivity">
            <intent-filter>
                <action android:name="com.littlejerk.sample.action.VIEW_URL" />
                <category android:name="android.intent.category.DEFAULT"/>
            </intent-filter>
        </activity>

        //調(diào)用方式啟動(dòng)WebActivity
        Intent intent = new Intent();
        intent.setAction("com.littlejerk.sample.action.VIEW_URL");
        intent.putExtra("URL","https://blog.csdn.net");
        startActivity(intent);

使用Action跳轉(zhuǎn),如果有一個(gè)程序的AndroidManifest.xml中的某一個(gè) Activity的IntentFilter段中 定義了包含了相同的Action,那么這個(gè)Intent就與這個(gè)目標(biāo)Action匹配。如果這個(gè)IntentFilter段中沒(méi)有定義 Type、Category,那么這個(gè) Activity就匹配了。但是如果手機(jī)中有兩個(gè)以上的程序匹配,那么就會(huì)彈出一個(gè)對(duì)話(huà)框來(lái)提示說(shuō)明。
上面說(shuō)過(guò)有IntentFilter,如果不指定android:exported,那么該值默認(rèn)為true,外部的應(yīng)用通過(guò)隱式意圖的方式也能將對(duì)應(yīng)的組件啟動(dòng)起來(lái)。這種情況我們就是我們說(shuō)的組件導(dǎo)出,而導(dǎo)出則意味著很有可能存在安全問(wèn)題,接下來(lái)看下WebActivity頁(yè)面:

        Intent intent = getIntent();
        String url = intent.getStringExtra("URL");
        UILog.e(TAG, url.charAt(0));
        mTvContent.setText(url);
        

我們注意到WebActivity只是接收一個(gè)URL并且顯示出來(lái)(沒(méi)有加載這個(gè)URL),從這里我們可以看出URL并沒(méi)有做參數(shù)檢驗(yàn),應(yīng)用可能會(huì)崩潰;因?yàn)樵擁?yè)面又是可被三方應(yīng)用調(diào)用的,這時(shí)候如果別人惡意傳遞一些不良的網(wǎng)頁(yè)信息,那你這個(gè)應(yīng)用不攔截就直接加載了,則這個(gè)應(yīng)用有可能就要下架了。

四、如何防范

我們以最常見(jiàn)的Activity為例說(shuō)明了組件導(dǎo)出的風(fēng)險(xiǎn),因?yàn)檫@個(gè)URL參數(shù)是我們處理的,我們可以防止應(yīng)用空指針異常,這沒(méi)問(wèn)題,但是上面也說(shuō)如果加載了不良URL呢?其實(shí)組件導(dǎo)出的風(fēng)險(xiǎn)最根本原因是被別人調(diào)用了,那這樣有沒(méi)有辦法控制這個(gè)別人的范圍,只允許我們信賴(lài)的人去調(diào)用。
在這里不得不提Android的權(quán)限機(jī)制,Android的Permission檢查機(jī)制是用來(lái)控制一個(gè)應(yīng)用擁有哪些執(zhí)行權(quán)利。例如應(yīng)用擁有拍照權(quán)限才能擁有拍照權(quán)利,那么我們是否可以通過(guò)權(quán)限來(lái)控制一個(gè)應(yīng)用是否有啟動(dòng)WebActivity的權(quán)利呢?
Android提供了自定義權(quán)限的能力,應(yīng)用可以定義自己的權(quán)限,如在清單文件中自定義一個(gè)permission:

    <permission
        android:label="允許打開(kāi)WebActivity頁(yè)面權(quán)限"
        android:name="com.littlejerk.sample.permission.WEB"
        android:protectionLevel="signature" />
        

label:權(quán)限的描述

name:該權(quán)限的名稱(chēng),使用該權(quán)限時(shí)通過(guò)名稱(chēng)來(lái)指定使用的權(quán)限

protectionLevel:該權(quán)限受保護(hù)的等級(jí),這很重要,它有三個(gè)等級(jí)

  • signature:簽名級(jí)別權(quán)限,即權(quán)限的定義方和注冊(cè)方必須具有相同的簽名才有效
  • system:系統(tǒng)級(jí)別權(quán)限,即權(quán)限的定義方和注冊(cè)方必須為系統(tǒng)應(yīng)用
  • signatureOrSystem :同簽名或系統(tǒng)應(yīng)用,上述二者具備其一即可

權(quán)限定義完成,如何用它來(lái)保護(hù)暴露的組件呢,看下面代碼:

        <!-- 通過(guò)隱式啟動(dòng)的方式需要在AndroidManifest.xml文件聲明-->
        <activity
            android:permission="com.littlejerk.sample.permission.WEB"
            android:name=".other.WebActivity">
            <intent-filter>
                <action android:name="com.littlejerk.sample.action.VIEW_URL" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>

在activity聲明時(shí),activity標(biāo)簽下有一個(gè)permission,通過(guò)permission就能指定保護(hù)該activity的權(quán)限名稱(chēng)了,這樣,只有具有了該權(quán)限的activity才能啟動(dòng)它(注意在定義方和使用方都要在清單文件中定義和聲明自定義的權(quán)限),在調(diào)用方的清單文件中聲明和使用該權(quán)限:

    <!--調(diào)用方可不用聲明-->
    <permission
        android:label="允許打開(kāi)WebActivity頁(yè)面權(quán)限"
        android:name="com.littlejerk.sample.permission.WEB"
        android:protectionLevel="signature" />
    <!--調(diào)用方必須申請(qǐng)此權(quán)限-->
    <uses-permission android:name="com.littlejerk.sample.permission.WEB"/>

有了權(quán)限的控制,activity組件導(dǎo)出的范圍就可控了,當(dāng)我們公司應(yīng)用間存在相互的組件調(diào)用時(shí),就可以使用同簽名的權(quán)限來(lái)做限制,至于其它應(yīng)用因?yàn)椴皇窍嗤暮灻?,所以它們無(wú)法調(diào)用我們暴露出去的組件,這很有效地規(guī)避了風(fēng)險(xiǎn)。
Activity是我們最常見(jiàn)的一個(gè)組件了,但是BroadcastReceiver用的地方也不少,一般安全評(píng)測(cè)都有提到這個(gè)組件的,我們有必要提一提它,其實(shí)各個(gè)組件的安全控制也可通過(guò)permission來(lái)控制的。
BroadcastReceiver的注冊(cè)有兩種方式

  • 靜態(tài)注冊(cè),在Manifest中聲明注冊(cè)
  • 動(dòng)態(tài)注冊(cè),在代碼中依賴(lài)其他組件,通過(guò)registerReceiver注冊(cè)

BroadcastReceiver有廣播的發(fā)送方和接收方,所以當(dāng)使用permission來(lái)校驗(yàn)通信的時(shí)候一般都需要雙向校驗(yàn),即廣播的方送方和接收方都需要添加權(quán)限檢驗(yàn),保證發(fā)送方只將廣播發(fā)送給信賴(lài)的接收方,同樣的接收方也只接受來(lái)自信賴(lài)方的廣播。

廣播發(fā)送方

發(fā)送方需要在清單文件AndroidManifest.xml中聲明權(quán)限:

    <permission
        android:label="聲明發(fā)送方權(quán)限"
        android:name="com.littlejerk.sample.permission.BROADCAST_SEND"
        android:protectionLevel="signature" />
        

然后使用sendBroadcast(Intent intent, String receiverPermission)方法發(fā)送廣播:

        //發(fā)送廣播
        Intent intent = new Intent();
        intent.setAction("com.littlejerk.sample.broadcast.action.TEST");
        sendBroadcast(intent, "com.littlejerk.sample.permission.BROADCAST_SEND");

從receiverPermission字面意思就知道,接收廣播方必須要申請(qǐng)com.littlejerk.sample.permission.BROADCAST_SEND這個(gè)自定義權(quán)限,不然,無(wú)法接收到action通知,如接收方的清單文件AndroidManifest.xml:

    <!-- 接收方需申請(qǐng)發(fā)送方權(quán)限-->
    <uses-permission android:name="com.littlejerk.sample.permission.BROADCAST_SEND"/>

如果接收方的廣播接收器不控制自己的權(quán)限,則同開(kāi)發(fā)者應(yīng)用只監(jiān)聽(tīng)com.littlejerk.sample.broadcast.action.TEST這個(gè)action就行了,但是為了雙重檢驗(yàn),我們也需要給接收方聲明自己的權(quán)限。

廣播接收方

我們定義一個(gè)廣播接收器TestReceiver:

public class TestReceiver extends BroadcastReceiver {
    private static final String TAG = "TestReceiver";

    //接收到廣播信息的回調(diào)
    @Override
    public void onReceive(Context context, Intent intent) {
        //對(duì)外來(lái)的參數(shù)應(yīng)該做些合法的檢查
        String action = intent.getAction();
        if (TextUtils.isEmpty(action)) {
            return;
        }
        UILog.e(TAG, "action:" + action);
    }
}

接著在清單文件AndroidManifest.xml中聲明控制權(quán)限:

    <permission
        android:label="聲明接收方權(quán)限"
        android:name="com.littlejerk.sample.permission.BROADCAST_RECEIVER"
        android:protectionLevel="signature" />

然后把這個(gè)控制權(quán)限給廣播接收器,接收器有兩種注冊(cè)方式
靜態(tài)注冊(cè)方式,在清單文件AndroidManifest.xml中:

        <receiver
            android:name=".widget.receiver.TestReceiver"
            android:permission="com.littlejerk.sample.permission.BROADCAST_RECEIVER">
            <intent-filter>
                <action android:name="com.littlejerk.sample.broadcast.action.TEST"/>
            </intent-filter>
        </receiver>

然后是動(dòng)態(tài)注冊(cè)方式,在你需要注冊(cè)的地方聲明:

Receiver receiver = new Receiver();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("com.littlejerk.sample.broadcast.action.TEST");
registerReceiver(receiver, intentFilter, "com.littlejerk.sample.permission.BROADCAST_RECEIVER", null);

這兩種注冊(cè)方式都可以,但是推薦使用動(dòng)態(tài)注冊(cè)廣播的方式,因?yàn)锳ndroid O上為了App性能和功耗的考慮,對(duì)靜態(tài)注冊(cè)的廣播做了很大的限制,至于是什么限制,這里就不說(shuō)了。
我們對(duì)接收器也做了權(quán)限限制,那么發(fā)送方也必須要申請(qǐng)這個(gè)權(quán)限才能發(fā)送action給它呀,所以發(fā)送方的清單文件AndroidManifest.xml中在原有的基礎(chǔ)上需要添加:

    <!-- 發(fā)送方需申請(qǐng)接收方權(quán)限-->
    <uses-permission android:name="com.littlejerk.sample.permission.BROADCAST_RECEIVER"/>

至此,廣播的雙向檢驗(yàn)就完成了,以上所有代碼都測(cè)試過(guò)了,沒(méi)有任何問(wèn)題,很好地過(guò)濾了無(wú)關(guān)廣播,保護(hù)了組件的安全。

總結(jié)

文章主要講了四大組件的含義及其重要性,然后闡明為什么會(huì)組件導(dǎo)出及導(dǎo)出風(fēng)險(xiǎn),有些組件導(dǎo)出時(shí)必須的,因?yàn)橐獙?shí)現(xiàn)一些特定功能,但是對(duì)于可控的組件,盡量設(shè)置不導(dǎo)出。如果需要導(dǎo)出組件,我們需要嚴(yán)格地做參數(shù)檢驗(yàn),防止崩潰;除此之外,最好地防范就是添加權(quán)限,這樣才能有效地防止被惡意調(diào)用,造成不必要的損失。

到此這篇關(guān)于Android開(kāi)發(fā)中關(guān)于組件導(dǎo)出的風(fēng)險(xiǎn)及防范的文章就介紹到這了,更多相關(guān)Android 組件導(dǎo)出內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論