مسدود کردن متن ساده در برنامههای اندروید بدون تکیه بر VPN
متن ساده در بار و متن ساده در مسیر دو مسئله متفاوتاند. اولی را در برنامه و دومی را با تونل یا سیاست دستگاه حل کنید.
دو چیز کاملاً متفاوت را مسدود کردن متن ساده در اندروید مینامند. یکی سیاستی درون برنامه است که به پشته شبکه خودش دستور میدهد HTTP ساده را رد کند. دیگری ترتیبی در سطح دستگاه است که میکوشد همه چیز روی گوشی را یکجا محافظت کند، معمولاً با عبور دادن ترافیک از VPN. این دو مسئلههای متفاوتی را حل میکنند و دومی نمیتواند اولی را درست کند: تونل بخش میان گوشی و خروجی را محافظت میکند، اما برنامهای که HTTP حرف میزند همچنان با هر چیزی آنسوی آن خروجی HTTP حرف میزند.
دو مسئله با یک نام
مسئله اول بار است: برنامه اعتبارنامه یا توکنها را در درخواستی مینویسد که سرتاسر رمزنگاری نشده، پس هر گامی که آن را ببیند میتواند بخواند. مسئله دوم مسیر است: برنامه میتواند کاملاً درست باشد و شما باز هم بخواهید اپراتور وایفای محلی هیچ چیزی درباره مقصد اتصال نداند. VPN دومی را حل میکند و فقط دومی را.
همین تفکیک صاحب راهحل را تعیین میکند. بار متعلق به کسی است که برنامه را عرضه میکند، چون فقط همان کد تعیین میکند کدام نشانی فراخوانی میشود و آیا گواهی اعتبارسنجی میشود. مسیر متعلق به دستگاه یا شبکه است، چون بحث این است که بستهها کجا میروند، نه چه چیزی حمل میکنند.
مسیر یک: برنامهای که کنترل میکنید
اگر برنامه را عرضه میکنید، راهحل یک تصمیم انتقال بههمراه سیاستی است که آن را اجرا میکند. هر نقطه پایانی را به HTTPS ببرید، اعتبارسنجی نام میزبان و گواهی را روشن نگه دارید و مسیر بازگشتی HTTP ساده را حذف کنید، نه اینکه آن را یک پرچم پیکربندی دورتر رها کنید. تغییرمسیر اینجا کمکی نمیکند: درخواست HTTP که 301 دریافت میکند سرآیندها و بدنهاش را از پیش آشکار فرستاده است، پس اعتبارنامهها هرگز نباید با این فرض سفر کنند که تغییرمسیر از آنها محافظت میکند.
در اندروید 7.0 و بالاتر، Network Security Configuration این سیاست را بیان میکند. فایل زیر کوچکترین نسخه سودمند است: همهجا متن ساده را رد میکند مگر اینکه استثنایی مخصوص یک دامنه خلاف آن را بگوید.
<network-security-config>
<base-config cleartextTrafficPermitted="false" />
</network-security-config>از مانیفست به آن منبع ارجاع دهید، سپس پیش از عرضه استثناهایی را که از پیش وجود دارند بخوانید. یک دامنه قدیمی اشکالزدایی یا ورودی SDK یک ارائهدهنده پرداخت میتواند بیصدا متن ساده را برای همان میزبانی که میکوشیدید محافظت کنید دوباره مجاز کند.
دو جزئیات نسخه ارزش دانستن دارد. برنامههایی که API 28 یا بالاتر را هدف میگیرند از پیش بهطور پیشفرض متن ساده را رد میکنند، پس برنامهای که هنوز HTTP ساده حرف میزند یا سطح API قدیمیتری را هدف دارد یا جایی استثنا دارد. و وقتی پیکربندی امنیت شبکه حاضر باشد، ویژگی قدیمی مانیفست android:usesCleartextTraffic دیگر تعیینکننده نیست، و به همین دلیل گاهی تغییر آن پرچم بیاثر به نظر میرسد.
مسیر دو: برنامهای که کنترل نمیکنید
برای برنامه نصبشده شخص ثالث نمیتوانید پیکربندی امنیتی آن را با یک تنظیم کاربر بازنویسی کنید. گزینههای واقعبینانه کنترلهای اتصال ایمن خود محصول، جایگزینی نگهداریشده که از پیش از TLS استفاده میکند، یا سیاست دستگاه مدیریتشدهای است که محدود میکند دستگاه چه چیزی را مجاز است اجرا کند. اینها تعهدهای متفاوتی هستند و فقط سومی به یک ناوگان مقیاس میگیرد.
قواعد شبکه جایگزینهای ضعیفتری از آنچه به نظر میرسند هستند. اجازه دادن تنها به درگاه 443، TLS احرازشده را الزام نمیکند، چون بسیاری از پروتکلهای متن ساده را میتوان به آن درگاه منتقل کرد، و مسدود کردن درگاه 80 متن ساده روی درگاههای دیگر را پوشش نمیدهد. حالت فقط-HTTPS مرورگر هم محدود به همان مرورگر است، نه به برنامه ایمیل یا چت جداگانه روی همان گوشی.
نصب گواهی رهگیری برای اینکه ترافیک رمزنگاریشده به نظر برسد، تغییری در اعتماد است نه راهحل. احراز هویت سرور برنامه را با احراز هویت شما جایگزین میکند، و برنامهای که از آغاز گواهیها را اعتبارسنجی نمیکرد با این کار درست نمیشود؛ فقط جابهجا کردید که چه کسی میتواند جریان را بخواند.
VPN کجا کمک میکند و کجا نه
تونل ابزار درست است وقتی الزام این است که شبکه محلی هیچ چیزی درباره اتصال نداند، یا برنامه به سرویس خصوصیای برسد که در غیر این صورت نمیرسد. ابزار نادرست برای اینکه یک کلاینت HTTP به HTTPS سخن بگوید، چون درخواست دقیقاً همانگونه که وارد تونل شد از آن بیرون میرود.
اندروید یک محدودیت عملی میافزاید: پلتفرم هر بار تنها یک سرویس VPN اجرا میکند. برنامه پالایش محلی که آن جایگاه را میگیرد با تونل دوردستی که واقعاً لازم دارید رقابت میکند، و جابهجایی میان این دو کاری در سطح دستگاه است نه در سطح برنامه. همین یک جایگاه دلیل خوبی است برای گذاشتن سیاست بار در برنامه و نگه داشتن تونل برای مسیر.
تنها موردی که این دو همپوشانی دارند سرور خصوصیای است که خودتان هم اداره میکنید. آنجا تونل میتواند مسیر را خصوصی کند حتی اگر پروتکل هنوز متن ساده باشد، که مواجهه را کم میکند اما تغییر نمیدهد که بار چیست. با آن مانند کاهش ریسک رفتار کنید، نه رمزنگاری داده.
پیش از مسدود نامیدن چه چیزی را آزمایش کنید
با همان پیشفرضی شروع کنید که مردم را شگفتزده میکند: برنامهای که API 28 یا بالاتر را هدف میگیرد باید از پیش متن ساده را رد کند، پس سطح هدف را بررسی کنید پیش از افزودن پیکربندیای که یک پیشفرض را تکرار میکند. سپس مورد شکست را عمداً بیازمایید: درخواست به یک میزبان HTTP ساده باید شکست بخورد نه اینکه بیصدا از مسیر بازگشتی موفق شود.
adb shell dumpsys package com.example.app | grep -E 'targetSdk|versionName'
adb logcat | grep -i cleartextبرای مورد موفقیت تأیید کنید که فراخوانی HTTPS زنجیره گواهی واقعی را اعتبارسنجی میکند و پراکسی با گواهی نامعتبر رد میشود نه تحمل. دستدهیای که با هر گواهی موفق شود چیزی درباره امنیت انتقال اثبات نکرده است.
برای برنامه شخص ثالث، مرزی را بنویسید که واقعاً میتوانید اجرا کنید، چه سیاست دستگاه مدیریتشده باشد چه قاعده شبکه چه هیچ، و آن را در معیارهای پذیرش بگویید. راهنمای پیکربندی امنیت اندروید پیشفرضهای پلتفرم و اینکه کدام اجزا سیاست را رعایت میکنند فهرست میکند، و همین بخش تعیین میکند که آیا پیکربندی شما اصلاً کاری میکند.