התכונה 'תצורה של אבטחת הרשת' מאפשרת לכם להתאים אישית את הגדרות אבטחת הרשת של האפליקציה בקובץ תצורה בטוח ודקלרטיבי, בלי לשנות את קוד האפליקציה. אפשר להגדיר את ההגדרות האלה לדומיינים ספציפיים ולאפליקציות ספציפיות. היכולות העיקריות של התכונה הזו הן:
- עוגני אמון בהתאמה אישית: אפשר להתאים אישית את רשויות האישורים (CA) שנחשבות מהימנות לחיבורים מאובטחים של אפליקציה. לדוגמה, אפשר להגדיר אמון באישורים מסוימים עם חתימה עצמית או להגביל את קבוצת רשויות האישורים הציבוריות שהאפליקציה נותנת בהן אמון.
- שינויים שחלים רק על ניפוי באגים: ניפוי באגים בחיבורים מאובטחים באפליקציה בצורה בטוחה, בלי להוסיף סיכון לבסיס המשתמשים.
- ביטול הסכמה לתעבורת טקסט גלוי: הגנה על אפליקציות מפני שימוש לא מכוון בתעבורת טקסט גלוי (לא מוצפנת).
- הסכמה לשימוש בשקיפות אישורים: הגבלת החיבורים המאובטחים של האפליקציה כך שישתמשו באישורים שמתועדים ביומן.
- הצמדת אישורים: הגבלת החיבור המאובטח של אפליקציה לאישורים מסוימים.
הוספה של קובץ הגדרות אבטחה לרשת
התכונה 'הגדרות אבטחה לרשת' משתמשת בקובץ XML שבו מציינים את ההגדרות של האפליקציה. צריך לכלול רשומה במניפסט של האפליקציה כדי להפנות לקובץ הזה. קטע הקוד הבא מתוך קובץ מניפסט מדגים איך ליצור את הרשומה הזו:
<?xml version="1.0" encoding="utf-8"?> <manifest ... > <application android:networkSecurityConfig="@xml/network_security_config" ... > ... </application> </manifest>
התאמה אישית של רשויות אישורים מהימנות
יכול להיות שתרצו שהאפליקציה תסמוך על קבוצה מותאמת אישית של רשויות אישורים במקום על ברירת המחדל של הפלטפורמה. הסיבות הנפוצות ביותר לכך הן:
- התחברות למארח עם רשות אישורים מותאמת אישית, כמו רשות אישורים בחתימה עצמית או רשות אישורים שהונפקה באופן פנימי בחברה.
- הגבלת קבוצת ה-CA רק ל-CA שאתם סומכים עליהם, במקום לכל CA שמותקן מראש.
- הוספת רשויות אישורים נוספות שלא נכללות במערכת.
כברירת מחדל, חיבורים מאובטחים (באמצעות פרוטוקולים כמו TLS ו-HTTPS) מכל האפליקציות נסמכים על אישורי CA של המערכת שהותקנו מראש, ואפליקציות שמטרגטות ל-Android 6.0 (רמת API 23) ומטה נסמכות גם על מאגר אישורי ה-CA שנוספו על ידי המשתמש כברירת מחדל. אפשר להתאים אישית את החיבורים של האפליקציה באמצעות base-config
(להתאמה אישית של האפליקציה כולה) או domain-config
(להתאמה אישית לכל דומיין).
הגדרה של רשות אישורים (CA) בהתאמה אישית
יכול להיות שתרצו להתחבר למארח שמשתמש באישור SSL בחתימה עצמית או למארח שאישור ה-SSL שלו הונפק על ידי רשות אישורים לא ציבורית שאתם סומכים עליה, כמו רשות האישורים הפנימית של החברה שלכם.
קטע הקוד הבא מראה איך להגדיר את האפליקציה ל-CA מותאם אישית ב-res/xml/network_security_config.xml
:
<?xml version="1.0" encoding="utf-8"?> <network-security-config> <domain-config> <domain includeSubdomains="true">example.com</domain> <trust-anchors> <certificates src="@raw/my_ca"/> </trust-anchors> </domain-config> </network-security-config>
מוסיפים את האישור בחתימה עצמית או את אישור ה-CA הלא ציבורי בפורמט PEM או DER אל
res/raw/my_ca
.
הגבלת קבוצת אישורי ה-CA המהימנים
אם אתם לא רוצים שהאפליקציה שלכם תיתן אמון בכל רשויות האישורים שהמערכת נותנת בהן אמון, אתם יכולים לציין במקום זאת קבוצה מצומצמת של רשויות אישורים שבהן אתם רוצים לתת אמון. כך האפליקציה מוגנת מפני אישורים מזויפים שהונפקו על ידי רשויות אישורים אחרות.
ההגדרה להגבלת קבוצת רשויות ה-CA המהימנות דומה להגדרת רשות CA מותאמת אישית כמהימנה עבור דומיין ספציפי, אלא שבמקרה הזה מסופקות כמה רשויות CA במשאב.
קטע הקוד הבא מדגים איך להגביל את קבוצת רשויות האישורים המהימנות של האפליקציה ב-res/xml/network_security_config.xml
:
<?xml version="1.0" encoding="utf-8"?> <network-security-config> <domain-config> <domain includeSubdomains="true">secure.example.com</domain> <domain includeSubdomains="true">cdn.example.com</domain> <trust-anchors> <certificates src="@raw/trusted_roots"/> </trust-anchors> </domain-config> </network-security-config>
מוסיפים את רשויות האישורים המהימנות בפורמט PEM או DER אל res/raw/trusted_roots
.
שימו לב: אם אתם משתמשים בפורמט PEM, הקובץ צריך להכיל רק נתוני PEM, בלי טקסט נוסף. אפשר גם לספק כמה רכיבי <certificates>
במקום אחד.
הוספת רשויות אישורים מהימנות
יכול להיות שתרצו שהאפליקציה שלכם תיתן אמון לרשויות אישורים נוספות שהמערכת לא נותנת להן אמון, למשל אם המערכת עדיין לא כוללת את רשות האישורים או אם רשות האישורים לא עומדת בדרישות להכללה במערכת Android. אפשר לציין כמה מקורות אישורים להגדרה ב-res/xml/network_security_config.xml
באמצעות קוד כמו בדוגמה הבאה.
<?xml version="1.0" encoding="utf-8"?> <network-security-config> <base-config> <trust-anchors> <certificates src="@raw/extracas"/> <certificates src="system"/> </trust-anchors> </base-config> </network-security-config>
הגדרת רשויות אישורים לניפוי באגים
כשמבצעים ניפוי באגים באפליקציה שמתחברת באמצעות HTTPS, יכול להיות שתרצו להתחבר לשרת פיתוח מקומי שאין לו אישור SSL לשרת הייצור שלכם. כדי לתמוך בזה בלי לבצע שינויים בקוד של האפליקציה, אפשר לציין רשויות אישורים (CA) לניפוי באגים בלבד, שהן מהימנות רק כש-android:debuggable הוא true
, באמצעות debug-overrides
. בדרך כלל, סביבות פיתוח משולבות (IDE) וכלי בנייה מגדירים את הדגל הזה באופן אוטומטי לגרסאות שאינן גרסאות הפצה.
השיטה הזו בטוחה יותר מקוד רגיל עם תנאים, כי מטעמי אבטחה, חנויות אפליקציות לא מקבלות אפליקציות שמסומנות כאפליקציות שאפשר לבצע בהן ניפוי באגים.
קטע הקוד הבא מראה איך מציינים רשויות אישורים שמשמשות רק לניפוי באגים ב-res/xml/network_security_config.xml
:
<?xml version="1.0" encoding="utf-8"?> <network-security-config> <debug-overrides> <trust-anchors> <certificates src="@raw/debug_cas"/> </trust-anchors> </debug-overrides> </network-security-config>
הצטרפות לשקיפות אישורים
הערה: התמיכה בשקיפות אישורים זמינה רק מ-Android 16 (רמת API 36).
שקיפות אישורים (CT, RFC 6962) היא תקן אינטרנט שנועד לשפר את האבטחה של אישורים דיגיטליים. החוק מחייב את רשויות האישורים לשלוח את כל האישורים שהן מנפיקות ליומן ציבורי שמתעד אותם, וכך מגביר את השקיפות והאחריות בתהליך הנפקת האישורים.
השמירה של רשומה ניתנת לאימות של כל האישורים מקשה מאוד על גורמים זדוניים לזייף אישורים או על רשויות אישורים להנפיק אותם בטעות. כך אנחנו מגנים על המשתמשים מפני מתקפות מסוג "אדם בתווך" ומאיומי אבטחה אחרים. מידע נוסף זמין בהסבר בנושא שקיפות ב-transparency.dev. מידע נוסף על תאימות ל-CT ב-Android זמין במדיניות ה-CT של Android.
כברירת מחדל, האישורים מתקבלים גם אם הם לא נשמרו ביומן של שקיפות אישורים. כדי לוודא שהאפליקציה מתחברת רק ליעדים עם אישורים שמתועדים ביומן CT, אתם יכולים להפעיל את התכונה באופן גלובלי או לכל דומיין בנפרד.
תנועה בטקסט גלוי
מפתחים יכולים להפעיל או להשבית תנועה בטקסט גלוי (באמצעות פרוטוקול HTTP לא מוצפן במקום HTTPS) באפליקציות שלהם.
פרטים נוספים מופיעים במאמר NetworkSecurityPolicy.isCleartextTrafficPermitted()
.
התנהגות ברירת המחדל של תנועה בטקסט גלוי תלויה ברמת ה-API:
- עד Android 8.1 (רמת API 27), התמיכה בטקסט גלוי מופעלת כברירת מחדל. אפליקציות יכולות להשבית תעבורה בטקסט גלוי כדי להגביר את האבטחה.
- החל מ-Android 9 (רמת API 28), התמיכה בטקסט גלוי מושבתת כברירת מחדל. אפליקציות שנדרשת בהן תנועה לא מוצפנת יכולות להצטרף לתנועה לא מוצפנת.
ביטול ההסכמה לשימוש בתנועה בטקסט גלוי
הערה: ההנחיות שבקטע הזה רלוונטיות רק לאפליקציות שמטרגטות Android 8.1 (רמת API 27) ומטה.
אם אתם רוצים שהאפליקציה שלכם תתחבר ליעדים רק באמצעות חיבורים מאובטחים, אתם יכולים לבטל את התמיכה בתנועה שאינה מוצפנת ליעדים האלה. האפשרות הזו עוזרת למנוע רגרסיות מקריות באפליקציות בגלל שינויים בכתובות URL שמסופקות על ידי מקורות חיצוניים, כמו שרתי קצה עורפי.
לדוגמה, יכול להיות שתרצו שהאפליקציה שלכם תוודא שהחיבורים אל
secure.example.com
תמיד מתבצעים באמצעות HTTPS כדי להגן על תעבורה רגישה מפני רשתות עוינות.
<?xml version="1.0" encoding="utf-8"?> <network-security-config> <domain-config cleartextTrafficPermitted="false"> <domain includeSubdomains="true">secure.example.com</domain> </domain-config> </network-security-config>
הצטרפות לאפשרות של תעבורת נתונים בטקסט גלוי
הערה: ההנחיות בקטע הזה רלוונטיות רק לאפליקציות שמטרגטות ל-Android 9 (רמת API 28) ומעלה.
אם האפליקציה שלכם צריכה להתחבר ליעדים באמצעות תנועה בטקסט גלוי (HTTP), אתם יכולים להביע הסכמה לתמיכה בטקסט גלוי ליעדים האלה.
לדוגמה, יכול להיות שתרצו לאפשר לאפליקציה ליצור חיבורים לא מאובטחים אל insecure.example.com
.
<?xml version="1.0" encoding="utf-8"?> <network-security-config> <domain-config cleartextTrafficPermitted="true"> <domain includeSubdomains="true">insecure.example.com</domain> </domain-config> </network-security-config>
אם האפליקציה צריכה להצטרף לתנועה שאינה מוצפנת לכל דומיין, צריך להגדיר את הערך
cleartextTrafficPermitted="true"
ב-base-config
.
חשוב לדעת שמומלץ להימנע מהגדרה לא מאובטחת כזו ככל האפשר.
<?xml version="1.0" encoding="utf-8"?> <network-security-config> <base-config cleartextTrafficPermitted="true"> </base-config> </network-security-config>
הצמדת אישורים
בדרך כלל, אפליקציה נותנת אמון לכל רשויות האישורים שמותקנות מראש. אם אחד ממרכזי האישורים האלה ינפיק אישור מזויף, האפליקציה תהיה בסיכון לתקיפה בנתיב. חלק מהאפליקציות בוחרות להגביל את קבוצת האישורים שהן מקבלות, על ידי הגבלת קבוצת רשויות האישורים שהן נותנות בהן אמון או על ידי הצמדת אישורים.
כדי להצמיד אישורים, צריך לספק קבוצה של אישורים לפי הגיבוב של המפתח הציבורי (SubjectPublicKeyInfo
של אישור X.509). שרשרת אישורים תקפה רק אם היא מכילה לפחות אחד מהמפתחות הציבוריים המוצמדים.
חשוב לזכור: כשמשתמשים ב-certificate pinning, צריך תמיד לכלול מפתח גיבוי, כדי שאם תהיו חייבים לעבור למפתחות חדשים או לשנות רשויות אישורים (כשמצמידים לאישור של רשות אישורים או לאישור ביניים של רשות האישורים הזו), הקישוריות של האפליקציה לא תיפגע. אחרת, תצטרכו לדחוף עדכון לאפליקציה כדי לשחזר את הקישוריות.
בנוסף, אפשר להגדיר זמן תפוגה לקודי אימות, שאחריו לא תתבצע הצמדה. כך אפשר למנוע בעיות בקישוריות באפליקציות שלא עודכנו. עם זאת, הגדרת זמן תפוגה לקיבוע עשויה לאפשר לתוקפים לעקוף את האישורים המקובעים.
קטע הקוד הבא מראה איך מצמידים אישורים ב-res/xml/network_security_config.xml
:
<?xml version="1.0" encoding="utf-8"?> <network-security-config> <domain-config> <domain includeSubdomains="true">example.com</domain> <pin-set expiration="2018-01-01"> <pin digest="SHA-256">7HIpactkIAq2Y49orFOOQKurWxmmSFZhBCoQYcRhJ3Y=</pin> <!-- backup pin --> <pin digest="SHA-256">fwza0LRMXouZHRC8Ei+4PyuldPDcf3UKgO/04cDM1oE=</pin> </pin-set> </domain-config> </network-security-config>
התנהגות של ירושת הגדרות
ערכים שלא מוגדרים בהגדרה ספציפית עוברים בירושה. ההתנהגות הזו מאפשרת הגדרות מורכבות יותר, תוך שמירה על קובץ ההגדרות כקובץ קריא.
לדוגמה, ערכים שלא מוגדרים ב-domain-config
נלקחים מהרכיב האב domain-config
, אם הם מוטמעים, או מהרכיב base-config
, אם לא. ערכים שלא מוגדרים ב-base-config
משתמשים בערכי ברירת המחדל של הפלטפורמה.
לדוגמה, נניח שכל החיבורים לתת-דומיינים של example.com
צריכים להשתמש בקבוצה מותאמת אישית של רשויות אישורים. בנוסף, תנועה שאינה מוצפנת לדומיינים האלה מותרת אלא אם מתחברים אל secure.example.com
.
אם מקננים את ההגדרה של secure.example.com
בתוך ההגדרה של example.com
, לא צריך לשכפל את trust-anchors
.
קטע הפיד הבא מראה איך הקינון הזה ייראה ב-res/xml/network_security_config.xml
:
<?xml version="1.0" encoding="utf-8"?> <network-security-config> <domain-config> <domain includeSubdomains="true">example.com</domain> <trust-anchors> <certificates src="@raw/my_ca"/> </trust-anchors> <domain-config cleartextTrafficPermitted="false"> <domain includeSubdomains="true">secure.example.com</domain> </domain-config> </domain-config> </network-security-config>
פורמט של קובץ תצורה
התכונה 'הגדרת אבטחת רשת' משתמשת בפורמט קובץ XML. מבנה הקובץ מוצג בדוגמת הקוד הבאה:
<?xml version="1.0" encoding="utf-8"?> <network-security-config> <base-config> <trust-anchors> <certificates src="..."/> ... </trust-anchors> </base-config> <domain-config> <domain>android.com</domain> ... <trust-anchors> <certificates src="..."/> ... </trust-anchors> <pin-set> <pin digest="...">...</pin> ... </pin-set> </domain-config> ... <debug-overrides> <trust-anchors> <certificates src="..."/> ... </trust-anchors> </debug-overrides> </network-security-config>
בקטעים הבאים מוסבר על התחביר ועל פרטים נוספים של פורמט הקובץ.
<network-security-config>
- יכולים להכיל:
-
0 או 1 מתוך
<base-config>
כל מספר של<domain-config>
0 או 1 מתוך<debug-overrides>
<base-config>
- תחביר:
<base-config cleartextTrafficPermitted=["true" | "false"]> ... </base-config>
- יכולים להכיל:
-
<trust-anchors>
<certificateTransparency>
- description:
-
ההגדרה שמוגדרת כברירת מחדל לכל החיבורים שהיעד שלהם לא נכלל ב
domain-config
.אם לא תגדירו ערכים, המערכת תשתמש בערכי ברירת המחדל של הפלטפורמה.
הגדרת ברירת המחדל לאפליקציות שמטרגטות ל-Android 9 (רמת API 28) ומעלה היא כדלקמן:
<base-config cleartextTrafficPermitted="false"> <trust-anchors> <certificates src="system" /> </trust-anchors> </base-config>
הגדרת ברירת המחדל לאפליקציות שמטרגטות Android 7.0 (רמת API 24) עד Android 8.1 (רמת API 27) היא כדלקמן:
<base-config cleartextTrafficPermitted="true"> <trust-anchors> <certificates src="system" /> </trust-anchors> </base-config>
הגדרת ברירת המחדל לאפליקציות שמטרגטות את Android 6.0 (רמת API 23) וגרסאות קודמות היא כדלקמן:
<base-config cleartextTrafficPermitted="true"> <trust-anchors> <certificates src="system" /> <certificates src="user" /> </trust-anchors> </base-config>
<domain-config>
- תחביר:
-
<domain-config cleartextTrafficPermitted=["true" | "false"]> ... </domain-config>
- יכולים להכיל:
-
1 או יותר
<domain>
0 או 1<certificateTransparency>
0 או 1<trust-anchors>
0 או 1<pin-set>
כל מספר של<domain-config>
מקוננים
- description:
- ההגדרה שמשמשת לחיבורים ליעדים ספציפיים, כפי שמוגדרים ברכיבי
domain
.שימו לב: אם כמה רכיבי
domain-config
חלים על יעד מסוים, המערכת משתמשת בהגדרה עם כלל הדומיין התואם הספציפי ביותר (הארוך ביותר).
<domain>
- תחביר:
-
<domain includeSubdomains=["true" | "false"]>example.com</domain>
- מאפיינים:
-
-
includeSubdomains
-
אם
"true"
, כלל הדומיין הזה תואם לדומיין ולכל תתי-הדומיין, כולל תתי-דומיין של תתי-דומיין. אחרת, הכלל חל רק על התאמות מדויקות.
-
<certificateTransparency>
- תחביר:
-
<certificateTransparency enabled=["true" | "false"]/>
- description:
-
אם
true
, האפליקציה תשתמש ביומני שקיפות האישורים כדי לאמת את האישורים. כשמשתמשים באפליקציה באישור משלה (או בחנות המשתמש), סביר להניח שהאישור לא ציבורי ולכן לא ניתן לאמת אותו באמצעות שקיפות האישורים. כברירת מחדל, האימות מושבת במקרים האלה. עדיין אפשר לכפות את האימות באמצעות<certificateTransparency enabled="true"/>
בתצורת הדומיין. לכל תג<domain-config>
, ההערכה מתבצעת לפי הסדר הבא:- אם
certificateTransparency
מופעל, מפעילים את האימות. -
אם אחד מהערכים
<trust-anchors>
הוא"user"
או מוטבע (כלומר,"@raw/cert.pem"
), משביתים את האימות. - אחרת, מסתמכים על ההגדרה שעברה בירושה.
- אם
<debug-overrides>
- תחביר:
-
<debug-overrides> ... </debug-overrides>
- יכולים להכיל:
-
0 או 1
<trust-anchors>
- description:
-
הגדרות ברירת המחדל שיחולו כש-android:debuggable
הוא
"true"
, שבדרך כלל זה המצב בגרסאות build שאינן גרסאות הפצה שנוצרות על ידי סביבות פיתוח משולבות (IDE) וכלים ליצירת build. ישויות עוגן אמינות שצוינו ב-debug-overrides
נוספות לכל שאר ההגדרות, ולא מתבצעת הצמדת אישורים אם שרשרת האישורים של השרת משתמשת באחת מישויות העוגן האמינות האלה שמיועדות לניפוי באגים בלבד. אם הערך של android:debuggable הוא"false"
, המערכת מתעלמת לחלוטין מהקטע הזה.
<trust-anchors>
- תחביר:
-
<trust-anchors> ... </trust-anchors>
- יכולים להכיל:
-
Any number of
<certificates>
- description:
- קבוצה של עוגני מהימנות לחיבורים מאובטחים.
<certificates>
- תחביר:
<certificates src=["system" | "user" | "raw resource"] overridePins=["true" | "false"] />
- description:
- קבוצה של אישורי X.509 לרכיבי
trust-anchors
. - מאפיינים:
-
src
-
המקור של אישורי CA. כל אישור יכול להיות אחד מהסוגים הבאים:
- מזהה משאב גולמי שמפנה לקובץ שמכיל אישורי X.509. האישורים צריכים להיות מקודדים בפורמט DER או PEM. במקרה של אישורי PEM, הקובץ לא יכול להכיל נתונים נוספים שאינם PEM, כמו תגובות.
-
"system"
לאישורי CA של המערכת שמותקנים מראש -
"user"
לאישורי CA שנוספו על ידי משתמשים
overridePins
-
המדיניות הזו קובעת אם רשויות האישורים מהמקור הזה יעקפו את הצמדת האישורים. אם
"true"
, אז הצמדה לא מתבצעת בשרשראות אישורים שנחתמו על ידי אחת מרשויות האישורים מהמקור הזה. האפשרות הזו יכולה להיות שימושית לניפוי באגים של רשויות אישורים או לבדיקת התקפות אדם בתווך על תנועת הגולשים המאובטחת של האפליקציה.ערך ברירת המחדל הוא
"false"
, אלא אם מציינים ערך אחר ברכיבdebug-overrides
. במקרה כזה, ערך ברירת המחדל הוא"true"
.
<pin-set>
- תחביר:
-
<pin-set expiration="date"> ... </pin-set>
- יכולים להכיל:
-
Any number of
<pin>
- description:
-
קבוצה של הצמדות של מפתחות ציבוריים. כדי שחיבור מאובטח ייחשב מהימן, אחד מהמפתחות הציבוריים בשרשרת האמון צריך להיות בקבוצת הפינים. במאמר
<pin>
מוסבר על הפורמט של הפינים. - מאפיינים:
-
-
expiration
-
התאריך, בפורמט
yyyy-MM-dd
, שבו תוקף הסיכות יפוג, כך שההצמדה תושבת. אם המאפיין לא מוגדר, התוקף של קודי האימות לא יפוג.תפוגה עוזרת למנוע בעיות בקישוריות באפליקציות שלא מקבלות עדכונים לסט של הפינים שלהן, למשל כשהמשתמש משבית את העדכונים של האפליקציה.
-
<pin>
- תחביר:
-
<pin digest=["SHA-256"]>base64 encoded digest of X.509 SubjectPublicKeyInfo (SPKI)</pin>
- מאפיינים:
-
-
digest
-
אלגוריתם הגיבוב ששימש ליצירת ה-pin. בשלב הזה, יש תמיכה רק ב-
"SHA-256"
.
-