什么是失效身份驗證?

身份驗證失效是一個寬泛的術(shù)語,它涵蓋了多種漏洞。我們將重點關注兩個主要漏洞:

攻擊可以非常具體,針對個人。攻擊者發(fā)動大規(guī)模攻擊也很常見。

會話管理

首先,每當用戶與應用程序交互時,都會為他們分配一個會話 ID 來幫助識別他們。這是應用程序用于與用戶通信的唯一 ID。會話 ID 通常以共享首選項的形式出現(xiàn)。由于共享首選項是讓用戶保持登錄狀態(tài)的好方法,攻擊者會嘗試使用各種方法來獲取這些 ID,從而獲取受保護的信息。

讓我們看一些不同類型的會話管理攻擊以及如何預防它們。

攻擊:會話 ID URL 重寫

在會話 ID URL 重寫中,用戶的會話 ID 會出現(xiàn)在 URL 中。在這種情況下,您已將用戶的私人數(shù)據(jù)暴露給大范圍攻擊。這可能導致攻擊者嗅探并獲取會話 ID 的訪問權(quán)限。

解決方案

Kotlin 仍然主要用于開發(fā)移動應用程序,但是也可以使用 Kotlin 構(gòu)建 Web 應用程序。在該網(wǎng)站上使用 HTTPS 非常重要。簡而言之,HTTPS 可以驗證網(wǎng)站并保護用戶提交的信息。黑客無法解密用戶信息,從而降低了攻擊的可能性。

大多數(shù)網(wǎng)站 URL 旁邊的掛鎖符號代表 HTTPS,可讓用戶知道該網(wǎng)站是安全的。Adobe 業(yè)務平臺后端已從 Java 遷移到 Kotlin。鎖圖標可讓用戶確信該網(wǎng)站可以安全使用。

Kotlin 身份驗證失敗指南:示例和預防措施圖片

URL 旁邊的鎖定圖標可確保用戶網(wǎng)站的安全

幸運的是,Kotlin 有許多框架可用于提供、使用和測試 HTTPS。例如,Ktor和http4k是用于連接 Kotlin 應用程序的流行框架。相比之下,Ktor 是完全異步的,而 http4k 則不是。選擇最適合您需求的框架很重要。

攻擊:會話固定

移動應用程序連接到外部服務以驗證用戶身份。這些服務包括其主機服務器、其他移動資源和第三方服務。黑客將利用此通信中的漏洞發(fā)起攻擊。

在會話固定攻擊中,攻擊者試圖誘騙用戶驗證預定的會話 ID。攻擊者將嘗試預先確定一個會話 ID。然后,他們向用戶發(fā)送一個帶有預定會話 ID 的鏈接。這將提示用戶登錄。攻擊者誤以為該鏈接指向合法應用程序,然后輸入其憑據(jù)。攻擊者能夠訪問受保護的資源,因為他們現(xiàn)在可以訪問經(jīng)過身份驗證的會話 ID。

解決方案

移動客戶端證書

阻止非人類攻擊訪問您的應用程序的最簡單方法是通過移動客戶端證書。本質(zhì)上,應用程序使用移動客戶端證書向后端驗證自身身份。客戶端證書只是驗證連接來自受信任的來源,并應允許訪問后端。因此,這允許防火墻阻止未經(jīng)授權(quán)的應用程序或惡意機器人。最重要的是,這只允許受信任的應用程序訪問您的后端。可以將其視為應用程序與外部服務之間的數(shù)字握手。

幸運的是,Kotlin 支持在您的應用中整合移動客戶端證書。使用 Kotlin 添加證書有三種方法:網(wǎng)絡安全配置、信任管理器和證書固定。每種方法都有自己的優(yōu)點和缺點,因此請確保選擇最適合您的 Kotlin 應用的方法。以下代碼是證書固定與okHttpClient一起使用的示例。

val certificatePinner = CertificatePinner.Builder()
       .add(
              "www.secureserver.com",
              "sha256/7HIpactkIAq2Y49orFEOQKurWxkmSFZhBCoQYcRyJ3Y="
       ).build()

val okHttpClient = OkHttpClient.Builder()
       .certificatePinner(certificatePinner)
       .build()
結(jié)束會話

此外,在長時間不活動后結(jié)束會話長度并在一定時間后注銷可以減少違規(guī)的可能性。您可以使用共享首選項刪除或添加會話 ID。同樣重要的是,Kotlin 會將共享首選項存儲在設備本身內(nèi)。因此,請記住對它們進行加密,以便任何獲得訪問權(quán)限的人都無法讀取它們。此外,一旦用戶長時間不活動,請確保銷毀 ID。

為了說明這一點,請考慮像 Amazon Prime 這樣的電影流媒體應用。流媒體應用希望讓用戶能夠輕松瀏覽應用,而無需每次都登錄。相反,銀行應用應該在幾分鐘后注銷用戶,因為攻擊的可能性要高得多。考慮到這一點,請確保在用戶不再活躍或離開應用時清除已保存的數(shù)據(jù)。您可以使用活動生命周期 onDestroy 和 onResume 來執(zhí)行此操作。

onDestroy(){
    val sharedPref = context.getSharedPreferences(STRING_VALUE, Context.MODE_PRIVATE)
    sharedPref.edit().clear().apply()
}
onResume(){
    context.getSharedPreferences(STRING_VALUE, 0).edit().clear().commit();
}

憑證管理

攻擊者獲取受保護信息的最簡單方法是使用用戶的憑據(jù)。

攻擊者會嘗試獲取用戶的憑證對(即用戶名和密碼)。獲取這些憑證后,攻擊者便可控制用戶的帳戶。這讓攻擊者可以訪問受保護的資源。

攻擊:憑證填充

憑證填充攻擊正在興起,不再以大型企業(yè)為目標。基本上,這種類型的攻擊發(fā)生在攻擊者已經(jīng)可以訪問用戶憑證的情況下。

黑客通常會將憑證出售或泄露給其他攻擊者。他們已經(jīng)獲得了未加密數(shù)據(jù)庫的訪問權(quán)限。這些攻擊者會自動嘗試不同的用戶名和密碼對。事實上,黑客會使用模擬器等虛擬環(huán)境來做到這一點。

最重要的是,這是一場數(shù)字游戲。其目的是劫持用戶賬戶。攻擊者之所以這樣做,是因為人們經(jīng)常在不同的應用程序上使用相同的密碼和用戶名。實際上,目前攻擊者已經(jīng)能夠訪問數(shù)十億個憑證。

解決方案

因此,有效防止移動應用成為憑證填充攻擊的受害者的最佳方法之一是防止其在虛擬設備上運行。這些虛擬設備包括模擬器、仿真器、虛擬環(huán)境、調(diào)試工具和其他虛擬環(huán)境。下面的代碼只是檢查應用是否在仿真器中打開。

首先,我們收集市場上所有的模擬器。其次,Kotlin 允許我們評估它們的屬性,主要是它們的 build 值。最后,我們使用返回值來確定是否可以授予應用程序訪問權(quán)限。

private fun checkBuildConfig(): Boolean {
var isEmulator = (Build.MANUFACTURER.contains("Genymotion")
|| Build.MODEL.contains("google_sdk")
|| Build.MODEL.toLowerCase().contains("droid4x")
|| Build.MODEL.contains("Emulator")
|| Build.MODEL.contains("Android SDK built for x86")
|| Build.HARDWARE == "goldfish"
|| Build.HARDWARE == "vbox86"
|| Build.HARDWARE.toLowerCase().contains("nox")
|| Build.FINGERPRINT.startsWith("generic")
|| Build.PRODUCT == "sdk"
|| Build.PRODUCT == "google_sdk"
|| Build.PRODUCT == "sdk_x86"
|| Build.PRODUCT == "vbox86p"
|| Build.PRODUCT.toLowerCase().contains("nox")
|| Build.BOARD.toLowerCase().contains("nox")
|| (Build.BRAND.startsWith("generic") && Build.DEVICE.startsWith("generic")))
return isEmulator
}

黑客希望使用服務器和后端來訪問應用程序。在這種情況下,請記住加密所有 API 端點,因為攻擊者將使用此信息進行憑證填充。例如,建議加密用戶名和密碼,因為攻擊者需要這些信息進行攻擊。為了增加保護,請考慮使用密鑰庫,這會使從設備中提取加密數(shù)據(jù)變得更加困難。

fun main():{
val plaintext: ByteArray = ...
al keygen = KeyGenerator.getInstance("AES")
keygen.init(256)
val key: SecretKey = keygen.generateKey()
val cypher = Cypher.getInstance("AES/CBC/PKCS5PADDING")
cypher.init(CYPHER.ENCRYPT_MODE, key)
val cyphertext: ByteArray = cypher.doFinal(plaintext)
val iv: ByteArray = cypher.iv
}

攻擊:密碼噴灑

密碼噴灑是一種暴力攻擊,類似于憑證填充。噴灑不涉及已經(jīng)存在的密碼和用戶名對。攻擊者將嘗試使用常用短語、術(shù)語、生日等來猜測用戶憑證。假設許多人會選擇弱密碼。平均而言,用戶必須記住 100 個密碼。這導致人們使用弱密碼或重復使用密碼來讓自己的生活更輕松。最重要的是,這可能導致您的應用容易受到惡意攻擊和入侵。

解決方案

總體而言,使用無密碼身份驗證可以消除不安全的密碼行為。用戶通常會選擇非常容易被破解的常用密碼。這讓黑客很容易利用此漏洞。考慮向用戶發(fā)送驗證鏈接、要求發(fā)送驗證所有權(quán)的短信或使用生物識別技術(shù)。生物識別技術(shù)是一項特別好的安全功能,因為它需要用戶采取獨特的身體動作。而 Kotlin 支持在您的應用程序中使用生物識別技術(shù)。

val biometricManager = BiometricManager.from(this)
when (biometricManager.canAuthenticate(BIOMETRIC_STRONG or DEVICE_CREDENTIAL)) {
    BiometricManager.BIOMETRIC_SUCCESS ->
        Log.d("MY_APP_TAG", "App can authenticate using biometrics.")
    BiometricManager.BIOMETRIC_ERROR_NO_HARDWARE ->
        Log.e("MY_APP_TAG", "No biometric features available on this device.")
    BiometricManager.BIOMETRIC_ERROR_HW_UNAVAILABLE ->
        Log.e("MY_APP_TAG", "Biometric features are currently unavailable.")
    BiometricManager.BIOMETRIC_ERROR_NONE_ENROLLED -> {
        // Prompts the user to create credentials that your app accepts.
        val enrollIntent = Intent(Settings.ACTION_BIOMETRIC_ENROLL).apply {
            putExtra(Settings.EXTRA_BIOMETRIC_AUTHENTICATORS_ALLOWED,
                BIOMETRIC_STRONG or DEVICE_CREDENTIAL)
        }
        startActivityForResult(enrollIntent, REQUEST_CODE)
    }
}

結(jié)論

身份驗證失敗可能會對您的 Kotlin 應用程序造成嚴重影響。因此,將安全性納入開發(fā)流程非常重要。

文章來源:Kotlin Broken Authentication Guide: Examples and Prevention

上一篇:

Vue XML 外部 實體(XXE)指南:示例和預防

下一篇:

你相信你的 X-Forwarded-For 標頭么?
#你可能也喜歡這些API文章!

我們有何不同?

API服務商零注冊

多API并行試用

數(shù)據(jù)驅(qū)動選型,提升決策效率

查看全部API→
??

熱門場景實測,選對API

#AI文本生成大模型API

對比大模型API的內(nèi)容創(chuàng)意新穎性、情感共鳴力、商業(yè)轉(zhuǎn)化潛力

25個渠道
一鍵對比試用API 限時免費

#AI深度推理大模型API

對比大模型API的邏輯推理準確性、分析深度、可視化建議合理性

10個渠道
一鍵對比試用API 限時免費