如何保护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:
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).
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 returnsfalse, 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.
Obfuscation makes it exponentially harder for attackers to reverse-engineer and modify your logic:
- Enable R8 in your
build.gradlefor 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.
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.
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

