הרשאת רשת מקומית

אפשר לגשת למכשירים ברשת מקומית (LAN) מכל אפליקציה שיש לה הרשאה INTERNET. כך קל לאפליקציות להתחבר למכשירים מקומיים, אבל יש לכך גם השלכות על הפרטיות, כמו יצירת טביעת אצבע של המשתמש ושימוש במיקום כפרוקסי.

מטרת הפרויקט 'הגנות על הרשת המקומית' היא להגן על פרטיות המשתמש באמצעות הגבלת הגישה לרשת המקומית מאחורי הרשאת זמן ריצה חדשה.

השפעה

במהלך Android 16, ההרשאה הזו היא תכונה אופציונלית, כלומר היא תשפיע רק על האפליקציות שהביעו הסכמה לשימוש בה. מטרת ההסכמה היא לעזור למפתחי אפליקציות להבין אילו חלקים באפליקציה שלהם תלויים בגישה משתמעת לרשת המקומית, כדי שיוכלו להתכונן להגנה על ההרשאות שלהם בגרסת Android עתידית.

האפליקציות יושפעו אם הן ניגשות לרשת המקומית של המשתמש באמצעות:

  • שימוש ישיר או דרך ספרייה בשקעים (sockets) גולמיים בכתובות של רשת מקומית, לדוגמה, Multicast DNS (mDNS) או Simple Service Discovery Protocol (SSDP).
  • שימוש במחלקות ברמת המסגרת שיש להן גישה לרשת המקומית, לדוגמה, NsdManager.

פרטים על ההשפעה

כדי להעביר תנועה לכתובת ברשת מקומית וממנה, צריך הרשאת גישה לרשת המקומית. בטבלה הבאה מפורטות כמה דוגמאות נפוצות:

פעולת רשת ברמה נמוכה באפליקציה נדרשת הרשאת גישה לרשת המקומית
ביצוע חיבור TCP יוצא כן
אישור של חיבור TCP נכנס כן
שליחת שידור יחיד, שידור לקבוצה או שידור לכולם ב-UDP כן
קבלת שידור יחיד, שידור מרובה או שידור לכל ברשת ב-UDP כן

ההגבלות האלה מוטמעות עמוק במערך של רכיבי הרשת, ולכן הן חלות על כל ממשקי ה-API של הרשת. הסנכרון יכלול שקעים שנוצרו בפלטפורמה או בקוד מנוהל, ספריות רשת כמו Cronet ו-OkHttp, וכל ממשקי API שהוטמעו מעל אלה. כדי לפתור בעיות בשירותים ברשת המקומית עם הסיומת .local, צריך הרשאה לגישה לרשת המקומית.

חריגים לכללים הקודמים:

  • אם שרת ה-DNS של המכשיר נמצא ברשת מקומית, לא נדרשת הרשאת גישה לרשת המקומית כדי להעביר תנועה אל השרת או ממנו (ביציאה 53).
  • אפליקציות שמשתמשות בכלי לבחירת פלט בתור הכלי לבחירה בתוך האפליקציה לא יצטרכו הרשאות גישה לרשת המקומית (הנחיות נוספות יפורסמו בגרסה מאוחרת יותר).

אכיפה ב-Android 17

החל מ-Android 17, חובה להשתמש באמצעי הגנה על הרשת המקומית באפליקציות שמטרגטות ל-Android 17 ומעלה, והמערכת אוכפת את השימוש בהם.

יחס גובה-רוחב Android 16 Android 17
גרסת יעד של SDK 36 ‫37 ומעלה
הרשאה נעשה שימוש זמני ב-NEARBY_WIFI_DEVICES ACCESS_LOCAL_NETWORK
גישה שמוגדרת כברירת מחדל הגישה לרשת המקומית פתוחה כברירת מחדל, הגישה לרשת המקומית חסומה לכל האפליקציות שמעדכנות את ה-SDK לטירגוט
קבוצת הרשאות חלק מקבוצת ההרשאות הקיימת NEARBY_DEVICES

כדי לוודא שהפונקציונליות של האפליקציה לא נפגמת אחרי האכיפה, אפליקציות שמטרגטות SDK בגרסה 37 ומעלה צריכות לבחור באחת מהדרכים הבאות לניהול גישה לרשת מקומית:

נתיב א': שימוש בכלי בחירת תאריכים ששומר על הפרטיות

כדי להימנע מבקשת הרשאה רחבה בתחילת ההפעלה, כדאי להשתמש בבוחרים למשימות של גילוי וחיבור בתיווך המערכת. משתמשים בכלי לבחירת תאריכים בהתאם לתרחיש השימוש:

  • סטרימינג של מדיה: באפליקציות שתומכות ב-Google Cast, אפשר להשתמש בתכונה מתג המעבר למכשיר אחר. כך מפתחים יכולים לאפשר למשתמשים לבחור מכשירי סטרימינג ספציפיים בלי שהאפליקציה תצטרך לבקש את ההרשאה הרחבה ACCESS_LOCAL_NETWORK.
  • קישוריות כללית: חבילת NsdManager כוללת כלי לבחירת שירותים שמופעל על ידי המערכת לצורך זיהוי mDNS. במקום שהאפליקציה תסרוק את כל הרשת, המערכת מציגה תיבת דו-שיח שמאפשרת למשתמש לבחור מכשיר יחיד שהאפליקציה תוכל לגשת אליו.
val discoveryRequest = DiscoveryRequest.Builder("_http._tcp")
    .setFlags(DiscoveryRequest.FLAG_SHOW_PICKER)
    .build()

nsdManager.registerServiceInfoCallback(discoveryRequest, executor, object : NsdManager.ServiceInfoCallback {
    override fun onServiceUpdated(serviceInfo: NsdServiceInfo) {
        // Handle the user-selected and discovered service
        // NsdServiceInfo.getHostAddresses() can now be connected to
        // without ACCESS_LOCAL_NETWORK permission
    }
})

נתיב ב': בקשה להרשאה בזמן ריצה (גישה רחבה)

הנתיב הזה נדרש לתרחישי שימוש מורכבים כמו אוטומציה של הבית או ניהול מכשירי IoT, שדורשים גישה רחבה ומתמשכת לרשת המקומית.

  • מצהירים על ההרשאה במניפסט: מצהירים במפורש על ACCESS_LOCAL_NETWORK ב-AndroidManifest.xml.

  • בקשת הרשאה בזמן ריצה: לפני שמנסים לגשת לרשת המקומית, האפליקציות צריכות לבדוק אם ההרשאה ניתנה. אם לא, הם צריכים להתקשר אל Activity.requestPermission() כדי להפעיל את ההנחיה הסטנדרטית של המערכת.

  • תרחיש שבו ההרשאה ניתנה מראש: ההרשאה ACCESS_LOCAL_NETWORK היא חלק מקבוצת ההרשאות NEARBY_DEVICES. אם משתמש כבר העניק הרשאה אחרת בקבוצה הזו (למשל הרשאות Bluetooth), הוא לא יתבקש שוב לאשר גישה לרשת המקומית.

  • טיפול בדחייה ובביטול: האפליקציות צריכות לטפל בצורה חלקה במקרים שבהם המשתמש דוחה את הבקשה או מבטל את ההרשאה בהגדרות המערכת בשלב מאוחר יותר. בתרחישים כאלה, תנועת הנתונים ברשת המקומית תיחסם.

אסטרטגיה לאיפוס מונה בקשות ההרשאה

הפלטפורמה מטמיעה אסטרטגיה לאיפוס המונה שמטפלת בתרחישים שבהם דחייה קודמת של קבוצת ההרשאות NEARBY_DEVICES באפליקציה (שכוללת עכשיו את ACCESS_LOCAL_NETWORK) מנעה מהאפליקציה לבקש את ההרשאה אחרי שהוצג נימוק מספק. המנגנון הזה מעניק לאפליקציה הזדמנויות נוספות להפעיל את requestPermission()ה-API, ובפועל מאפס את מספר הדחיות של ההרשאה ACCESS_LOCAL_NETWORK. כך אפשר ליצור אינטראקציה מחדש עם המשתמש בצורה מתוחכמת יותר, במיוחד אם הדחייה הראשונית התרחשה לפני שהאפליקציה יכלה להסביר את הצורך בגישה לרשת המקומית כדי להשתמש בפונקציונליות העיקרית שלה.

מודל הרשאות מפוצל

ההרשאה לגישה לרשת המקומית משתמשת באסטרטגיית העברה של הרשאות מפוצלות כדי לטפל באפליקציות חדשות ובאפליקציות מדור קודם באופן שונה, בהתאם ל-SDK שהן מטרגטות

קטגוריה רמת ה-SDK לטירגוט התנהגות של גישה לרשת המקומית פעולה נדרשת מהמפתחים
אפליקציות חדשות / אפליקציות מעודכנות ‫>= 37 (Android 17) חסימה כברירת מחדל הצהרה על הרשאה בזמן ריצה וביקשת הרשאה כזוACCESS_LOCAL_NETWORK
אפליקציות מדור קודם ‫< 37 אפליקציות עם הרשאת INTERNET מקבלות הרשאה מרומזת ל-ACCESS_LOCAL_NETWORK, שמאפשרת להן לשמור על הגישה. זהו מצב זמני, והאפשרות הזו תיחסם כברירת מחדל ברגע שאפליקציות ישדרגו את ערכת ה-SDK לגרסה 37 לא צריך לשנות את הקוד באופן מיידי. אל תבקשו ACCESS_LOCAL_NETWORK בזמן ריצה לפני טירגוט SDK 37.

אסטרטגיית ניוד מספרים לפי תרחיש לדוגמה

  • הפעלת Cast: כדי להשתמש בפונקציות של הפעלת Cast למדיה, האסטרטגיה המתאימה ביותר לשמירה על הפרטיות היא שימוש בבורר הפלט. השיטה הזו מאפשרת למערכת לטפל בגילוי של רשת מקומית ובחיבור אליה בשם המשתמש, וכך האפליקציה לא צריכה לבקש הרשאה ACCESS_LOCAL_NETWORK.

  • דפדפנים: כדי לטפל בשגיאות צריך להשתמש בגישות שונות בהתאם לפרוטוקול. שגיאות UDP מובילות לקוד השגיאה EPERM. בחיבורי TCP, הדפדפנים צריכים להשתמש ב-NDK API‏ android_getnetworkblockedreason(int sockFd) כדי לקבוע אם חבילה נחסמה על ידי LNP. ה-API הזה מחזיר ANDROID_NETWORK_BLOCKED_REASON_LNP.

  • תרחישי שימוש אחרים (לדוגמה, IoT): אפליקציות שמאתרות מכשירים באמצעות mDNS צריכות להשתמש ב-android.net.nsd.DiscoveryRequest#FLAG_SHOW_PICKER, שמאפשרת לאתר מכשירים ללא הרשאה, וב-NsdManager#registerServiceInfoCallback / NsdManager#resolveService כדי לקבל כתובות IP. כדי להתחבר לכתובות IP שהתקבלו בדרך הזו לא נדרשת ההרשאה ACCESS_LOCAL_NETWORK.

באפליקציות שנדרשת בהן תקשורת ישירה ברשת המקומית ושאי אפשר להשתמש בהן בכלי לבחירת קבצים שמופעל על ידי המערכת, הגישה המומלצת היא להשתמש בשיטה של מונה לאיפוס הרשאות כשמטרגטים את Android 17 ‏ (SDK 37) ואילך. אם המשתמש מבטל את ההרשאה ACCESS_LOCAL_NETWORK, המנגנון הזה מספק לאפליקציה הזדמנויות נוספות לבקש שוב את ההרשאה, וכך המפתחים יכולים להציג למשתמש נימוק ברור יותר.

הנחיות לגבי Android 16

כדי להפעיל את ההגבלות על גישה לרשת המקומית:

  1. צריבת ROM‏ (flash) במכשיר לגרסת build עם Android 16 Beta 3 ואילך
  2. התקנת האפליקציה לבדיקה
  3. החלפת מצב ההגדרה של Appcompat באמצעות adb

    adb shell am compat enable RESTRICT_LOCAL_NETWORK <package_name>
    
  4. הפעלת המכשיר מחדש

עכשיו הגישה של האפליקציה לרשת המקומית מוגבלת, וכל ניסיון לגשת לרשת המקומית מוביל לשגיאות בשקע. אם אתם משתמשים בממשקי API שמבצעים פעולות ברשת המקומית מחוץ לתהליך של האפליקציה (לדוגמה, NsdManager), הם לא יושפעו במהלך ההצטרפות.

כדי לשחזר את הגישה, צריך לתת לאפליקציה הרשאה לNEARBY_WIFI_DEVICES.

  • מוודאים שהאפליקציה מצהירה על ההרשאה NEARBY_WIFI_DEVICES ב-manifest שלה.
  • עוברים אל הגדרות > אפליקציות > [שם האפליקציה] > הרשאות > מכשירים בקרבת מקום > אישור.

עכשיו הגישה של האפליקציה לרשת המקומית אמורה לחזור, וכל התרחישים אמורים לפעול כמו לפני שהאפליקציה נכללה ברשימת האפליקציות שמוחרגות מההגבלה. כך מושפעת תנועת הרשת של האפליקציה.

הרשאה בקשה יוצאת ב-LAN בקשה יוצאת/נכנסת באינטרנט בקשה נכנסת ב-LAN
הוענקה Microsoft Works Microsoft Works Microsoft Works
לא הוענקה גישה פספוסים Microsoft Works פספוסים

כדי להשבית את ההגדרה של Appcompat, מריצים את הפקודה הבאה

adb shell am compat disable RESTRICT_LOCAL_NETWORK <package_name>

שגיאות

אם בקשת גישה לרשת המקומית נכשלת בגלל הרשאה חסרה:

  • בדרך כלל, חיבורי TCP יגרמו לשגיאת זמן קצוב לתפוגה.

  • שגיאות UDP ודחיות כלליות של הרשאות בדרך כלל יגרמו לקוד השגיאה EPERM

באגים

שליחת דיווח על באגים ומשוב לגבי:

  • אי התאמות בגישה לרשת LAN (לדעתכם גישה מסוימת לא צריכה להיחשב כגישה לרשת מקומית)
  • באגים שבהם הגישה לרשת LAN אמורה להיות חסומה אבל היא לא חסומה
  • באגים שבהם הגישה לרשת המקומית נחסמת למרות שהיא לא אמורה להיחסם

השינוי הזה לא ישפיע על:

  • גישה לאינטרנט
  • רשת סלולרית