تغییر مسیر قصد زمانی اتفاق میافتد که یک مهاجم بتواند تا حدی یا به طور کامل محتوای یک intent را که برای راهاندازی یک مؤلفه جدید در زمینه یک برنامه آسیبپذیر استفاده میشود، کنترل کند.
هدف مورد استفاده برای راهاندازی مولفه جدید میتواند به روشهای مختلفی ارائه شود، معمولاً یا به صورت یک هدف سریالی در یک فیلد extras ، یا به یک رشته و تجزیه میشود. کنترل جزئی پارامترها نیز می تواند به همین نتیجه منجر شود.
تاثیر
تاثیر می تواند متفاوت باشد. مهاجم ممکن است ویژگی های داخلی را در برنامه آسیب پذیر اجرا کند یا ممکن است به اجزای خصوصی مانند اشیاء ContentProvider صادر نشده دسترسی داشته باشد.
کاهش
به طور کلی، ویژگیهای مربوط به تغییر جهت مقاصد تودرتو را افشا نکنید. در مواردی که اجتناب ناپذیر است، از روش های کاهش دهنده زیر استفاده کنید:
اطلاعات همراه را به درستی ضد عفونی کنید. مهم است که به یاد داشته باشید پرچمها را بررسی یا پاک کنید ( FLAG_GRANT_READ_URI_PERMISSION, FLAG_GRANT_WRITE_URI_PERMISSION, FLAG_GRANT_PERSISTABLE_URI_PERMISSION, and FLAG_GRANT_PREFIX_URI_PERMISSION مجدداً به کجا هدایت میشود) IntentSanitizer می تواند به این فرآیند کمک کند.
از اشیاء PendingIntent استفاده کنید. این کار از صادر شدن کامپوننت شما جلوگیری می کند و قصد اقدام هدف را تغییرناپذیر می کند.
برنامه ها می توانند با استفاده از روش هایی مانند ResolveActivity بررسی کنند که یک intent به کجا هدایت می شود:
کاتلین
valintent=getIntent()// Get the component name of the nested intent.valforward=intent.getParcelableExtra<Parcelable>("key")asIntentvalname:ComponentName=forward.resolveActivity(packageManager)// Check that the package name and class name contain the expected values.if(name.packagename=="safe_package" && name.className=="safe_class"){// Redirect the nested intent.startActivity(forward)}
جاوا
Intentintent=getIntent()// Get the component name of the nested intent.Intentforward=(Intent)intent.getParcelableExtra("key");ComponentNamename=forward.resolveActivity(getPackageManager());// Check that the package name and class name contain the expected values.if(name.getPackageName().equals("safe_package")&&
name.getClassName().equals("safe_class")){// Redirect the nested intent.startActivity(forward);}
برنامه ها می توانند از IntentSanitizer با استفاده از منطقی مشابه موارد زیر استفاده کنند:
اندروید 16 یک راهحل سختسازی امنیتی پیشفرض را برای بهرهبرداریهای Intent Redirection معرفی میکند. در بیشتر موارد، برنامههایی که از intent استفاده میکنند معمولاً با مشکل سازگاری مواجه نمیشوند.
انصراف از مدیریت تغییر مسیر Intent
اندروید 16 یک API جدید معرفی میکند که به برنامهها اجازه میدهد از حفاظتهای امنیتی راهاندازی منصرف شوند. این ممکن است در موارد خاصی که رفتار امنیتی پیشفرض با موارد استفاده قانونی برنامه تداخل میکند ضروری باشد.
در اندروید 16، میتوانید با استفاده از روش removeLaunchSecurityProtection() در شیء Intent از حفاظتهای امنیتی انصراف دهید. به عنوان مثال:
vali=intentvaliSublevel:Intent? =i.getParcelableExtra("sub_intent")iSublevel?.removeLaunchSecurityProtection()// Opt out from hardeningiSublevel?.let{startActivity(it)}
اشتباهات رایج
بررسی اینکه getCallingActivity() یک مقدار غیر تهی را برمی گرداند. برنامه های مخرب می توانند مقدار تهی برای این تابع ارائه دهند.
با فرض اینکه checkCallingPermission() در همه زمینه ها کار می کند، یا زمانی که متد در واقع یک عدد صحیح را برمی گرداند یک استثنا ایجاد می کند.
ویژگی های اشکال زدایی
برای برنامههایی که Android 12 (سطح API 31) یا بالاتر را هدف قرار میدهند، میتوانید یک ویژگی اشکالزدایی را فعال کنید که در برخی موارد به شما کمک میکند تشخیص دهید که آیا برنامه شما راهاندازی ناایمن یک intent را انجام میدهد یا خیر.
اگر برنامه شما هر دو عملکرد زیر را انجام دهد، سیستم یک هدف ناامن را شناسایی می کند و یک نقض StrictMode رخ می دهد:
برنامه شما یک هدف تودرتو را از موارد اضافی یک هدف ارائه شده جدا می کند.
برنامه شما فوراً یک مؤلفه برنامه را با استفاده از آن هدف تودرتو، مانند ارسال intent به startActivity() ، startService() یا bindService() راه اندازی می کند.
محتوا و نمونه کدها در این صفحه مشمول پروانههای توصیفشده در پروانه محتوا هستند. جاوا و OpenJDK علامتهای تجاری یا علامتهای تجاری ثبتشده Oracle و/یا وابستههای آن هستند.
تاریخ آخرین بهروزرسانی 2025-07-29 بهوقت ساعت هماهنگ جهانی.
[[["درک آسان","easyToUnderstand","thumb-up"],["مشکلم را برطرف کرد","solvedMyProblem","thumb-up"],["غیره","otherUp","thumb-up"]],[["اطلاعاتی که نیاز دارم وجود ندارد","missingTheInformationINeed","thumb-down"],["بیشازحد پیچیده/ مراحل بسیار زیاد","tooComplicatedTooManySteps","thumb-down"],["قدیمی","outOfDate","thumb-down"],["مشکل ترجمه","translationIssue","thumb-down"],["مشکل کد / نمونهها","samplesCodeIssue","thumb-down"],["غیره","otherDown","thumb-down"]],["تاریخ آخرین بهروزرسانی 2025-07-29 بهوقت ساعت هماهنگ جهانی."],[],[],null,["# Intent redirection\n\n\u003cbr /\u003e\n\n**OWASP category:** [MASVS-PLATFORM: Platform Interaction](https://mas.owasp.org/MASVS/09-MASVS-PLATFORM)\n\nOverview\n--------\n\nAn intent redirection occurs when an attacker can partly or fully control the\ncontents of an intent used to launch a new component in the context of a\nvulnerable app.\n\nThe intent used to launch the new component can be supplied in several ways,\nmost commonly either as a serialized intent in an `extras` field, or marshaled\nto a string and parsed. Partial control of parameters can also lead to the same\nresult.\n\nImpact\n------\n\nThe impact can vary. An attacker might execute internal features in the\nvulnerable app, or it might access private components like unexported\nContentProvider objects.\n\nMitigations\n-----------\n\nIn general, don't expose features related to redirecting nested intents. In\ncases where it's unavoidable, apply the following mitigation methods:\n\n- Properly sanitize the bundled information. It's important to remember to check or clear flags (`FLAG_GRANT_READ_URI_PERMISSION,\n FLAG_GRANT_WRITE_URI_PERMISSION, FLAG_GRANT_PERSISTABLE_URI_PERMISSION, and\n FLAG_GRANT_PREFIX_URI_PERMISSION`), and to check where the intent is being redirected. [`IntentSanitizer`](/reference/kotlin/androidx/core/content/IntentSanitizer) can help with this process.\n- Use [`PendingIntent`](/guide/components/intents-filters#PendingIntent) objects. This prevents your component from being exported and makes the target action intent immutable.\n\nApps can check where an intent is being redirected using methods such as\n[`ResolveActivity`](/reference/android/content/Intent#resolveActivity(android.content.pm.PackageManager)): \n\n### Kotlin\n\n val intent = getIntent()\n // Get the component name of the nested intent.\n val forward = intent.getParcelableExtra\u003cParcelable\u003e(\"key\") as Intent\n val name: ComponentName = forward.resolveActivity(packageManager)\n // Check that the package name and class name contain the expected values.\n if (name.packagename == \"safe_package\" && name.className == \"safe_class\") {\n // Redirect the nested intent.\n startActivity(forward)\n }\n\n### Java\n\n Intent intent = getIntent()\n // Get the component name of the nested intent.\n Intent forward = (Intent) intent.getParcelableExtra(\"key\");\n ComponentName name = forward.resolveActivity(getPackageManager());\n // Check that the package name and class name contain the expected values.\n if (name.getPackageName().equals(\"safe_package\") &&\n name.getClassName().equals(\"safe_class\")) {\n // Redirect the nested intent.\n startActivity(forward);\n }\n\nApps can use [`IntentSanitizer`](/reference/kotlin/androidx/core/content/IntentSanitizer) using logic similar to the\nfollowing: \n\n### Kotlin\n\n val intent = IntentSanitizer.Builder()\n .allowComponent(\"com.example.ActivityA\")\n .allowData(\"com.example\")\n .allowType(\"text/plain\")\n .build()\n .sanitizeByThrowing(intent)\n\n### Java\n\n Intent intent = new IntentSanitizer.Builder()\n .allowComponent(\"com.example.ActivityA\")\n .allowData(\"com.example\")\n .allowType(\"text/plain\")\n .build()\n .sanitizeByThrowing(intent);\n\n#### Default protection\n\nAndroid 16 introduces a by-default security hardening solution to `Intent`\nredirection exploits. In most cases, apps that use intents normally won't\nexperience any compatibility issues.\n\n##### Opt out of Intent redirection handling\n\nAndroid 16 introduces a new API that allows apps to opt out of launch security\nprotections. This might be necessary in specific cases where the default\nsecurity behavior interferes with legitimate app use cases.\n| **Important:** Opting out of security protections should be done with caution and only when absolutely necessary, as it can increase the risk of security vulnerabilities. Carefully assess the potential impact on your app's security before using this API.\n\nIn Android 16, you can opt out of security protections by using the\n`removeLaunchSecurityProtection()` method on the `Intent` object. For example: \n\n val i = intent\n val iSublevel: Intent? = i.getParcelableExtra(\"sub_intent\")\n iSublevel?.removeLaunchSecurityProtection() // Opt out from hardening\n iSublevel?.let { startActivity(it) }\n\n#### Common mistakes\n\n- Checking if `getCallingActivity()` returns a non-null value. Malicious apps can supply a null value for this function.\n- Assuming that `checkCallingPermission()` works in all contexts, or that the method throws an exception when it is actually returning an integer.\n\n#### Debugging features\n\nFor apps that target Android 12 (API level 31) or higher, you can enable a\n[debugging feature](/guide/components/intents-filters#DetectUnsafeIntentLaunches) that, in some cases, helps you detect whether your app is\nperforming an unsafe launch of an intent.\n\nIf your app performs **both** of the following actions, the system detects an\nunsafe intent launch, and a `StrictMode` violation occurs:\n\n- Your app unparcels a nested intent from the extras of a delivered intent.\n- Your app immediately starts an app component using that nested intent, such as passing the intent into `startActivity()`, `startService()`, or `bindService()`.\n\nResources\n---------\n\n- [Remediation for Intent Redirection](https://support.google.com/faqs/answer/9267555)\n- [Intents and intent filters](/guide/components/intents-filters#DetectUnsafeIntentLaunches)"]]