حل مشکل اتصال به شبکه (مقصد فاقد TLS) و انتقال ترافیک cleartext در اندروید با API level 28


چند روز پیش هنگام تست اپلیکیشن تحت وب خود در virtual device با API level 28 در اندروید استودیو، متوجه عدم عبور درخواست‌های خروجی از اپلیکیشن جهت اتصال به Web Service و دریافت دیتا از سرور شدم. مشکلی که هنگام تست اپلیکیشن در ورژن‌های پایین‌تر به هیچ وجه رخ نداده و در ابتدا فرض را بر داون شدن سرور گذاشتم. فرضی که با تست Web Service و همچنین اجرای مجدد اپلیکیشن در دیوایس‌های فیزیکی و مجازی با api levelهای پایین‌تر رد شد و متوجه شدم که این مشکل مختص ورژن 9 اندروید می‌باشد. البته بهتر است به جای واژه مشکل از اصطلاح محدودیت برای اشاره به این مساله استفاده کنیم چرا که در واقع باگ یا مشکلی در سمت اندروید عامل عدم موفقیت اپلیکیشن در برقراری ارتباط با شبکه اینترنت نبوده و این صرفا یک محدودیت امنیتی اعمال شده از سوی تیم توسعه دهنده اندروید در ورژن 9 از این سیستم‌عامل می‌باشد.

اما این محدودیت امنیتی چیست؟

در اندروید ورژن 9، پروتکل امنیتی TLS به صورت دیفالت از سوی سیستم عامل فعال شده و در حالت عادی تنها ارتباطات اینترنتی رمزنگاری شده توسط این پروتکل اجازه برقراری می‌یابند.

با اعمال این محدودیت در اندروید ورژن 9 و بالاتر، متد isCleartextTrafficPermitted که در واقع یک فلگ برای مشخص ساختن اجازه یا عدم اجازه انتقال ترافیک رمزنگاری نشده از دیوایس می‌باشد به صورت پیشفرض مقدار false را در پاسخ برگشت داده و بدین ترتیب ارتباطات اینترنتی بدون رمزنگاری یا به اصطلاح cleartext network traffic از سوی لایه‌های امنیتی سیستم‌عامل اندروید بلاک شده و اجازه خروج از دیوایس را ندارند.

وجود چنین محدودیتی منجر خواهد شد تا در صورت عدم پیاده‌سازی پروتکل امنیتی TLS در مقصد و در نتیجه عدم رمزنگاری داده‌های ارسالی و دریافتی با استفاده از این پروتکل، اپلیکیشن ما در اتصال به شبکه اینترنت ناکام مانده و در نتیجه برنامه تحت وب ما عملا از کار بیفتد.

جهت رفع این محدودیت و دریافت مجوز انتقال ترافیک رمزنگاری نشده، می‌بایست دست به دامان پیکربندی امنیت شبکه (Network Security Configuration) شد. قابلیت تنظیم پیکربندی شبکه به توسعه‌دهندگان این امکان را می‌دهد که تنظیمات امنیتی شبکه مختص برنامه‌های خود را در یک فایل پیکربندی امن و بدون نیاز به تغییر کدهای برنامه انجام دهند.

اضافه کردن فایل پیکربندی امنیت شبکه در پروژه اندروید

ما می‌توانیم تنظیمات مد نظر خود جهت اعمال در پیکربندی امنیت شبکه را در یک فایل xml تعیین نموده (با ایجاد فایلی در دایرکتوری xml) و سپس این فایل را در فایل manifest پروژه خود بیفزاییم.

<?xml version="1.0" encoding="utf-8"?>
<manifest ... >
    <application android:networkSecurityConfig="@xml/network_security_config"
        ... >
        ...
    </application>
</manifest>

در ادامه جهت اعطای مجوز انتقال ترافیک cleartext جهت اتصال به سروهای فاقد پروتکل امنیتی TLS می‎بایست پیکربندی زیر را در فایل xml ایجاد شده قرار دهیم.

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <base-config cleartextTrafficPermitted="true">
        <trust-anchors>
            <certificates src="system" />
        </trust-anchors>
    </base-config>
</network-security-config>