Android Uygulama Güvenliği ve Bileşenleri

Giriş

Android uygulama güvenliği, mobil cihazların hayatımızdaki yerinin artmasıyla daha da kritik hale gelmiştir. Açık kaynak yapısı geliştiricilere esneklik sağlarken, kötü niyetli yazılımların sisteme sızmasını da kolaylaştırır. Bu dokümanda, Android uygulamalarında sık kullanılan bileşenler ve bu bileşenlerin güvenlik açıkları ele alınmakta; özellikle exported gibi yapıların oluşturabileceği riskler incelenmektedir.

 

AndroidManifest

Uygulamaların özeti niteliğinde bir dosyadır. Uygulama bileşenlerinin nasıl ve hangi izinlerle kullanıldığını içerir. Uygulamanın hangi versiyonda çalışacağını içerir. Bu iş için minSdkVersion ve targetSdkVersion anahtar değerlerini kullanır. Kullanıcıdan alınan izinler bu dosyaya yazılır.

AndroidManifest.xml dosyası, uygulamanın bileşenlerini (Activity, Service, vb.) ve izinlerini tanımlar. Bu dosya olmadan uygulama çalışmaz.

Andorid Uygulamaların Kullandığı Bileşenler:

  • Content Provider
  • Activity
  • Service
  • BroadcastRecaiver
  • Intent

Content Provider:

Dışarıdan veri okuma/yazma işlemlerine açık Content Provider bileşenleri, yetkilendirme hatası sonucu hassas veri sızdırabilir.

Kodda path-permission ifadesinin yanlış yapılandırılması, saldırganların belli URI’leri kullanarak veri erişimi sağlamasına neden olabilir

Örnek Kod Bloğu:

corsur = contentResolver.query(

     UserDictionary.Words.CONTENT_URI,

      projection,

       selectionClause,

        selectionArgs.toTypedArray(),

        sortOrder

)

 

      AndroidManifest Kodu:

<provider 

    android:name=”ornek.uygulama.LocationProvider” 

    android:authorities=”ornek.uygulama.location.provider” 

    android:exported=”true” 

    android:readPermission=”ornek.uygulama.data.READ_LOCATION” 

    android:writePermission=”android.permission.ACCESS_FINE_LOCATION” 

    <path-permission 

        android:pathPrefix=”/visit” 

        android:readPermission=”android.permission.WRITE_CALENDAR”/> 

</provider>

 

Burada uygulamanın ismi, dışarıya açık olup olmadığı, hangi izinleri istediği yazılır. Veri tabanın sorgusu ve ismi ve gerekeli yetki izinleri yazılır. Burada dikkat çekilmesi gereken yer

    android:exported=”true”   kısmıdır. android:exported değeri uygulama bileşeninin dış sistemlere açık olup olmadığını belirtir. exported=”true” olan bileşenler, dışardan çağrılabilir durumdadır, bu da kötü niyetli uygulamaların sisteme erişim kazanması için bir kapı aralayabilir.

Android 12 itibariyle, tüm bileşenlerde exported değeri zorunlu hale gelmiştir. Belirtilmediğinde uygulama derlemesi başarısız olur. Bu durum, güvenlik açısından önemli bir adımdır

Android 4.2 ve öncesi versiyonlarda “exported” anahtar değeri aksi belirtilmedikçe “true” kabul edilir.

Activity

Bazı uygulamalar arayüz kapalıyken servisleri arka planda çalıştırabilir. Kullanıcı uygulamayı sonlandırsa bile, servis veri toplamaya devam edebilir.

Servislerin android:permission ve enabled gibi parametreleri dikkatlice yönetilmelidir. Uygulama içinde gereksiz yere internet yetkisi verilmiş servisler veri trafiğini izinsiz kullanabilir.

 

Bir Activity örnek kodu:

override fun onCreate(savedInstanceState: Bundle?) {

    super.onCreate(savedInstanceState)   

    if (savedInstanceState != null) {

        with(savedInstanceState) {

            currentScore = getInt(STATE_SCORE)

            currentLevel = getInt(STATE_LEVEL)

        }

    } else {

}

Activity içerisinde çalışan servisler arka planda çalışır ve uzun süren işleri yürüten bir bileşendir.

Service, varsayılan olarak ana thread’de çalışır, ancak arka planda işlem yapmak için ayrı bir thread oluşturulabilir. Servisler, arka planda uzun süren işlemler için tasarlan bileşenlerdir, ancak yanlış yapılandırıldığında güvenlik riski oluşturabilir bir uygulama çalıştırdığı zaman arka planda başka bir servisin çalışmasına izin vermez, kullanıcı uygulamayı activite üzerinden kapatıyoruz ama arka planda çalışan uygulamalar activite üzerinden kapatılmıyor. Arka planda çalışan processler bazen güvenlik açığı oluşturduğu için arka planda çalışmaz.

Örnek process kodu:

class RSSPullService : IntentService(RSSPullService::class.simpleName) {

    override fun onHandleIntent(workIntent: Intent) {

        val dataString = workIntent.dataString

    }

}

Manifest içinde görünümü:

<service

    android:name=”ornek.uygulama.IndirmeServisi”

    android:enabled=”true”

    android:exported=”true”

    android:permission=”android.permission.INTERNET”>

</service>

 

Exported değerini “true” olarak görüyoruz yani dışarıdan ve arka planda veri çekebileceğimizi anlıyoruz çekilen kaynağında internet olduğunu görüyoruz. Aklımıza şu soru gelmeli bu servisi çağıran kim indirme servisimi yoksa uygulama servisi mi ?

Service

Android Service, kullanıcı arayüzü olmadan çalışan ve genellikle arka planda uzun süren işlemleri yürüten bir bileşendir. Bu bileşen, sistem kaynaklarını etkin kullanmak ve görevleri kullanıcı etkileşimi olmadan yerine getirmek için kullanılır. Ancak, yanlış yapılandırıldığında ciddi güvenlik açıklarına neden olabilir.

<service
android:name=”com.ornek.uygulama.IndirmeServisi”
android:enabled=”true”
android:exported=”true”
android:permission=”android.permission.INTERNET”>
</service>

Yukarıdaki örnekte dikkat edilmesi gereken nokta exported="true" ifadesidir. Bu servis, dışarıdan çağrılabilir durumdadır ve internet erişim izniyle birlikte geldiğinde ciddi bir veri sızıntısı potansiyeli taşır. Güvenlik açısından, servislerin yalnızca gerektiğinde export edilmesi ve uygun izinlerle sınırlandırılması önerilir.

Kotlin kodu gösterimi

class RSSPullService : IntentService(“RSSPullService”) {
        override fun onHandleIntent(intent: Intent?) {
         val dataString = intent?.dataStringr
     }
}

u örnekte, dışarıdan gelen bir Intent nesnesiyle veri alınmakta. Eğer bu servis dış dünyaya açıksa, saldırganlar özel Intent verileriyle bu servisi tetikleyebilir.

BroadcastReceiver

Sistem broadcastlerini yakalayarak cihaz hakkında bilgi toplayan yayın alıcıları (örneğin batarya durumu, uçak modu vb.), kullanıcı hareketlerini analiz edebilir.

intent-filter tanımında açık bırakılan filtreler, dış sistemlerin uygulama içi davranışları tetiklemesine sebep olabilir. Özellikle BOOT_COMPLETED gibi sistem etkinlikleri, kötü amaçlı uygulamalarda yaygın kullanılmaktadır.

Manifest içerisinden bir görünüm

<receiver android:name=”.MyBroadcastReceiver” android:exported=”true”>

    <intent-filter>

        <action android:name=”android.intent.action.BOOT_COMPLETED” />

        <action android:name=”android.intent.action.INPUT_METHOD_CHANGED” />

    </intent-filter>

</receiver>

Exported “true” olduğu için başka yayın akıcılardan veri çektiği görülür. Input   metodu ise klavye açılıp bir şeyler yazmaya başlandığımı başlanmadığını kontrol eder.

Eğer bir BroadcastReceiver’ın android:exported değeri true olarak ayarlanmışsa ve intent-filter tanımlanmışsa, dış uygulamalar tarafından tetiklenebilir. Bu durum güvenlik riski oluşturabilirÖrnek bir yayın alıcı kodu

private const val TAG = “MyBroadcastReceiver”

class MyBroadcastReceiver : BroadcastReceiver() {

    override fun onReceive(context: Context, intent: Intent) {

        StringBuilder().apply {

            append(“Action: ${intent.action}\n”)

            append(“URI: ${intent.toUri(Intent.URI_INTENT_SCHEME)}\n”)

        }.toString().also { log ->

            Log.d(TAG, log)

            Toast.makeText(context, log, Toast.LENGTH_LONG).show()

        }

    }

}

Yayın alıcıya log aldırıyor ve aldığı loglara göre sistemi düzenliyor ekran parlaklığını azaltıp arttırmak gibi fonksiyonlarda kullanılıyor.

Intnet

Implicit intent kullanımıyla uygulamalar arası veri aktarımı yapılabilir. Ancak bu, veri güvenliğini riske sokar. Kötü amaçlı uygulamalar, bu yolla kullanıcının özel dosyalarına erişebilir.

Bu nedenle hassas içerikler için explicit intent tercih edilmeli, veri paylaşımı kontrollü yapılmalıdır.

Örnek ıntent kodu

val downloadIntent = Intent(this, DownloadService::class.java).apply {

    data = Uri.parse(fileUrl)

}

startService(downloadIntent)

 

Burada ıntent servisinde bu aktiviteden bu servisi çağırmak istiyorum diyor. Ve indirme sevisine dosyası indiriyor.

Intent’ler ikiye ayrılır:

Implicit intent: her uygulama işleyebilir

Explicit intent: Explicit intent, belirli bir bileşeni (Activity, Service vb.) hedefleyen intent türüdür. Implicit intent ise bir eylemi gerçekleştirebilecek herhangi bir uygulamayı hedefler.

mplicit intent kullanırken, intent’in hangi uygulamalar tarafından işleneceği kontrol edilmez. Bu nedenle kötü amaçlı uygulamalar veri sızıntısına yol açabilir. Hassas veri paylaşımlarında explicit intent kullanılmalıdır.

 Sonuç

Android cihaz güvenliği, yalnızca antivirüs uygulamalarıyla değil, uygulama bileşenlerinin doğru yapılandırılmasıyla sağlanabilir. Manifest dosyasında yer alan her izin, her bileşenin dışa açıklığı ve çalışma mantığı, siber saldırılara karşı dirençli bir yapı kurulmasında belirleyici rol oynar. Uygulama geliştiricileri, her bir bileşeni tanımlarken sistem çağrılarını ve dış erişim haklarını bilinçli şekilde ele almalı; kullanıcılar ise uygulama izinlerini dikkatle gözden geçirmelidir. Bu döküman, Android mimarisini güvenlik perspektifinden ele alarak, siber güvenlik bilinci oluşturmayı ve güvenli uygulama geliştirme süreçlerine katkı sağlamayı amaçlamaktadır.

Android dünyasını seviyorsanız RootBeer ile Android Root Tespiti: Güvenlik Analizi  bu araştırmayı da okuyabilirsiniz.

Sistemeler hakkında daha fazla bilgi almak isterseniz Android Mobil Uygulama Geliştirici Araçları – Android Geliştiricileri  |  Android Developers bu siteyi takip edebilirsiniz.

About The Author

No Responses

Reply