You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何保护AndroidManifest.xml?求助解决登录权限被绕过的问题

Hey there, I totally get why this is frustrating—bypassing login by tweaking the AndroidManifest is a go-to trick for bad actors targeting paid apps, but we can lock this down with layered defenses that make this kind of tampering way harder. Let’s walk through the most effective fixes:

1. Enforce Authentication Checks in Every Protected Activity

Never rely solely on the manifest to control access. Every activity that requires paid access (especially your MainActivity) needs to validate the user’s status on launch.

  • Create a base protected activity that all restricted screens inherit from, or add this check directly in each activity’s onCreate:
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    // First, confirm the user is authenticated with Firebase
    val currentUser = FirebaseAuth.getInstance().currentUser
    if (currentUser == null) {
        startActivity(Intent(this, LoginActivity::class.java))
        finish()
        return
    }

    // Then verify the user's paid subscription status (example using Firestore)
    FirebaseFirestore.getInstance().collection("users").document(currentUser.uid)
        .get()
        .addOnSuccessListener { doc ->
            val isPaidUser = doc.getBoolean("isPaid") ?: false
            if (!isPaidUser) {
                // Redirect to subscription page or login
                startActivity(Intent(this, SubscriptionActivity::class.java))
                finish()
            } else {
                // Proceed to load the activity content
                setContentView(R.layout.activity_main)
                // Rest of your setup logic
            }
        }
        .addOnFailureListener {
            // Handle errors by redirecting to login as a fallback
            startActivity(Intent(this, LoginActivity::class.java))
            finish()
        }
}
  • Don’t forget: This check should apply to any activity that could be launched directly (e.g., via deep links or task stack recovery).
2. Validate App Integrity to Block Tampered APKs

Tampered APKs require re-signing, so we can check if the app’s signature matches your official release signature:

  • Add a local signature validation check (get your official signature fingerprint from Google Play Console or your keystore):
private fun isAppSignatureValid(): Boolean {
    val expectedFingerprint = "YOUR_OFFICIAL_SIGNATURE_FINGERPRINT"
    try {
        val packageInfo = packageManager.getPackageInfo(packageName, PackageManager.GET_SIGNATURES)
        for (signature in packageInfo.signatures) {
            val md = MessageDigest.getInstance("SHA")
            md.update(signature.toByteArray())
            val signatureHash = Base64.encodeToString(md.digest(), Base64.DEFAULT).trim()
            if (signatureHash == expectedFingerprint) return true
        }
    } catch (e: Exception) {
        e.printStackTrace()
    }
    return false
}
  • Call this method early in your app’s launch (e.g., in Application.onCreate). If it returns false, exit the app or redirect to a safe screen.
  • For stronger protection, enable Google Play App Integrity—it will verify if the APK is unmodified and officially signed, and you can block access if validation fails.
3. Obfuscate Code with R8/ProGuard

Obfuscation makes it exponentially harder for attackers to reverse-engineer and modify your logic:

  • Enable R8 in your build.gradle for release builds:
android {
    buildTypes {
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
}
  • Add custom rules to protect critical logic (like Firebase auth and subscription checks) from being stripped or easily understood.
4. Move Critical Validation to the Server

Never trust client-side checks alone. Shift subscription validation to a server (e.g., Firebase Cloud Functions) so attackers can’t tamper with local data:

  • Example Cloud Function (Node.js) to verify paid status:
exports.checkPaidStatus = functions.https.onCall(async (data, context) => {
    if (!context.auth) {
        throw new functions.https.HttpsError('unauthenticated', 'User must be logged in');
    }
    const userId = context.auth.uid;
    const userDoc = await admin.firestore().collection('users').doc(userId).get();
    if (!userDoc.exists) {
        throw new functions.https.HttpsError('not-found', 'User record missing');
    }
    return { isPaid: userDoc.data().isPaid || false };
});
  • Call this function from your client instead of reading local Firestore data—server-side checks are far harder to bypass.
5. Restrict Direct Launch of Protected Activities

In your manifest, mark restricted activities as exported="false" so they can’t be launched directly by external apps (including modified APKs trying to skip login):

<activity
    android:name=".MainActivity"
    android:exported="false">
</activity>

Note: This only works if your LoginActivity is the app’s exported launch activity.


No defense is 100% foolproof, but combining these layered checks will make it extremely difficult for casual attackers to bypass your login and paywall.

内容的提问来源于stack exchange,提问作者Miku jessi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 04:27:11