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.













