במסמך הזה מתוארות תלות של אפליקציות ושיטות מומלצות לניהול שלהן, כולל מעקב פגיעויות, אימות ארטיפקטים, צמצום טביעת הרגל של התלות ותמיכה בבנייה שניתנת לשחזור.
תלות בתוכנה היא תוכנה שהאפליקציה שלכם צריכה כדי לפעול, כמו ספריית תוכנה או פלאגין. יחסי תלות נפתרים כשמבצעים קומפילציה של קוד, כשמבצעים בנייה, כשמריצים, כשמורידים או כשמתקינים את התוכנה.
יחסי תלות יכולים לכלול רכיבים שאתם יוצרים, תוכנות קנייניות של צד שלישי ותוכנות קוד פתוח. הגישה שלכם לניהול תלות יכולה להשפיע על האבטחה והמהימנות של האפליקציות.
הפרטים הספציפיים להטמעה של שיטות מומלצות עשויים להשתנות בהתאם לפורמט של הארטיפקט ולכלים שבהם אתם משתמשים, אבל העקרונות הכלליים עדיין תקפים.
יחסי תלות ישירים וטרנזיטיביים
האפליקציות יכולות לכלול תלויות ישירות ותלויות מעבר:
- תלות ישירה
- רכיבי תוכנה שאפליקציה מפנה אליהם ישירות.
- יחסי תלות טרנזיטיביים
- רכיבי תוכנה שהתלות הישירה של אפליקציה בהם נדרשת מבחינה פונקציונלית. לכל תלות יכולות להיות תלויות ישירות ועקיפות משלה, וכך נוצר עץ רקורסיבי של תלויות טרנזיטיביות שכולן משפיעות על האפליקציה.
שפות תכנות שונות מציעות רמות שונות של שקיפות לגבי תלות והקשרים שלהן. בנוסף, בשפות מסוימות נעשה שימוש במנהלי חבילות כדי לפתור את עץ התלות כשמתקינים או פורסים חבילה.
במערכת האקולוגית של Node.js, מנהלי החבילות npm ו-yarn משתמשים בקובצי נעילה כדי לזהות גרסאות של יחסי תלות לצורך בניית מודול, וגרסאות של יחסי תלות שמנהל חבילות מוריד להתקנה ספציפית של המודול. במערכות אקולוגיות של שפות אחרות, כמו Java, יש תמיכה מוגבלת יותר בבדיקת תלות. בנוסף, מערכות build חייבות להשתמש במנהלי תלות ספציפיים כדי לנהל את התלות באופן שיטתי.
לדוגמה, מודול npm glob בגרסה 8.0.2. מצהירים על תלות ישירה במודולים של npm בקובץ package.json. בקטע dependencies של קובץ package.json של glob מפורטות תלויות ישירות של החבילה שפורסמה.
בקטע devDepdencies מפורטות התלויות בפיתוח ובבדיקות מקומיים על ידי מנהלים ותורמים של glob
בדף glob באתר npm מפורטים יחסי התלות הישירים ויחסי התלות של הפיתוח, אבל לא מצוין אם גם למודולים האלה יש יחסי תלות משלהם.
מידע נוסף על התלות של
globזמין באתר Open Source Insights. רשימת התלויות של glob כוללת תלויות ישירות ותלויות עקיפות (טרנזיטיביות).יכול להיות שעומק התלות הטרנזיטיבית בעץ התלות הוא כמה שכבות. לדוגמה:
-
glob8.0.2 יש תלות ישירה ב-minimatch5.0.1. -
minimatch5.0.1 יש תלות ישירה ב-brace-expression2.0.1. -
brace-expression2.0.1 תלוי ישירות ב-balanced-match1.0.2.
-
ללא נראות של תלות עקיפה, קשה מאוד לזהות פגיעויות ובעיות אחרות שמקורן ברכיב שהקוד שלכם לא מפנה אליו ישירות, ולהגיב להן.
כשמתקינים את החבילה glob, npm פותר את כל עץ התלות ושומר את רשימת הגרסאות הספציפיות שהורדו בקובץ package.lock.json, כדי שיהיה לכם תיעוד של כל התלויות. התקנות עוקבות באותה סביבה יאחזרו את אותן גרסאות.
כלים לתובנות לגבי תלות
אתם יכולים להשתמש בכלים הבאים כדי להבין את התלות שלכם בקוד פתוח ולהעריך את מצב האבטחה של הפרויקטים שלכם. הכלים האלה מספקים מידע על פורמטים שונים של חבילות.
- תובנות אבטחה במסוף Google Cloud
- Google Cloud מספק תובנות לגבי האבטחה של הארטיפקטים ב-Cloud Build, ב-Cloud Run וב-GKE, כולל פגיעויות, מידע על תלות, רשימת חומרים (SBOM) ואישור המקור של Build. שירותים אחרים מספקים גם תכונות שמשפרות את מצב האבטחה לאורך מחזור החיים של פיתוח התוכנה. Google Cloud סקירה כללית על אבטחת שרשרת האספקה של תוכנות
- כלים בקוד פתוח
יש מספר כלים בקוד פתוח, כולל:
Open Source Insights: אתר שמספק מידע על תלות ישירה ועקיפה ידועה, על נקודות חולשה ידועות ועל פרטי רישיון של תוכנות קוד פתוח. בפרויקט Open Source Insights, הנתונים האלה זמינים גם כGoogle Cloud מערך נתונים. אפשר להשתמש ב-BigQuery כדי לבדוק ולנתח את הנתונים.
מסד נתונים של נקודות פגיעות בקוד פתוח: מסד נתונים שאפשר לחפש בו נקודות פגיעות, והוא מרכז נקודות פגיעות ממסדי נתונים אחרים במקום אחד.
כרטיסי ניקוד: כלי אוטומטי שבעזרתו אפשר לזהות שיטות מסוכנות בשרשרת אספקת התוכנה בפרויקטים שלכם ב-GitHub. הוא מבצע בדיקות במאגרים ונותן לכל בדיקה ציון מ-0 עד 10. אחר כך תוכלו להשתמש בציונים כדי להעריך את מצב האבטחה של הפרויקט.
Allstar: אפליקציית GitHub שמנטרת באופן רציף ארגונים או מאגרים ב-GitHub כדי לוודא שהם עומדים במדיניות שהוגדרה. לדוגמה, אפשר להחיל מדיניות על הארגון שלכם ב-GitHub כדי לבדוק אם יש משתפי פעולה מחוץ לארגון שיש להם גישת אדמין או גישת push.
גישות להכללת יחסי תלות
יש כמה שיטות נפוצות לכלול תלויות באפליקציה:
- התקנה ישירות ממקורות ציבוריים
- מתקינים תלות בקוד פתוח ישירות ממאגרים ציבוריים, כמו Docker Hub, npm, PyPI או Maven Central. הגישה הזו נוחה כי לא צריך לתחזק את התלות החיצונית. עם זאת, מכיוון שאין לכם שליטה בתלות החיצונית הזו, שרשרת אספקת התוכנה שלכם חשופה יותר להתקפות על שרשרת אספקת קוד פתוח.
- אחסון עותקים של יחסי תלות במאגר קוד המקור
- הגישה הזו נקראת גם vendoring. במקום להתקין תלות חיצונית ממאגר ציבורי במהלך תהליכי ה-build, אתם מורידים אותה ומעתיקים אותה לעץ המקור של הפרויקט. יש לכם יותר שליטה על התלויות של ספקים שבהן אתם משתמשים, אבל יש כמה חסרונות:
- תלות בספקים מגדילה את הגודל של מאגר המקור וגורמת ליותר שינויים.
- אתם צריכים להוסיף את אותן תלויות לכל אפליקציה בנפרד. אם מאגר המקור או תהליך build לא תומכים במודולים של קוד מקור שאפשר לעשות בהם שימוש חוזר, יכול להיות שתצטרכו לשמור כמה עותקים של התלות.
- יכול להיות שיהיה קשה יותר לשדרג תלות שסופקה על ידי ספק.
- אחסון יחסי תלות במאגר פרטי
מאגר פרטי, כמו Artifact Registry, מאפשר להתקין ממאגר ציבורי וגם לשלוט ביחסי התלות. בעזרת Artifact Registry, אפשר:
- לרכז את פריטי המידע שנוצרו בתהליך פיתוח (artifacts) בגרסת build ואת יחסי התלות של כל האפליקציות.
- מגדירים את הלקוחות של חבילות השפה ו-Docker כך שיפעלו עם מאגרים פרטיים ב-Artifact Registry באותו אופן שבו הם פועלים עם מאגרים ציבוריים.
שליטה רבה יותר בתלות במאגרים פרטיים:
- הגבלת הגישה לכל מאגר באמצעות ניהול זהויות והרשאות גישה (IAM).
- אפשר להשתמש במאגרים מרוחקים כדי לשמור במטמון תלויות ממקורות ציבוריים במעלה הזרם ולסרוק אותן כדי לזהות פגיעויות (גרסת טרום-השקה פרטית).
- אפשר להשתמש במאגרים וירטואליים כדי לקבץ מאגרים פרטיים ומרוחקים מאחורי נקודת קצה אחת. אתם יכולים להגדיר עדיפות לכל מאגר כדי לשלוט בסדר החיפוש כשמורידים או מתקינים ארטיפקט (גרסת טרום-השקה פרטית).
שימוש ב-Artifact Registry עם שירותים אחרים של Google Cloud Google Cloud, כולל Cloud Build, Cloud Run ו-Google Kubernetes Engine. אתם יכולים להשתמש בסריקה אוטומטית של נקודות חולשה לאורך מחזור החיים של פיתוח התוכנה, ליצור אישור המקור של Build, לשלוט בפריסות ולצפות בתובנות לגבי מצב האבטחה שלכם.
אם אפשר, כדאי להשתמש במאגר פרטי לתלות. במצבים שבהם אי אפשר להשתמש במאגר פרטי, כדאי לשקול להשתמש ביצירת עותק מקוד של צד שלישי (vendoring) של התלויות כדי שתהיה לכם שליטה על התוכן בשרשרת אספקת התוכנה.
הצמדת גרסה
הצמדת גרסה היא הגבלה של תלות באפליקציה לגרסה ספציפית או לטווח גרסאות מסוים. מומלץ להצמיד גרסה אחת של יחסי תלות.
הצמדת הגרסה של יחסי תלות עוזרת לוודא שגרסאות ה-build של האפליקציה ניתנות לשחזור. אבל זה גם אומר שהגרסאות שלכם לא כוללות עדכונים של התלות, כולל תיקוני אבטחה, תיקוני באגים או שיפורים.
כדי לפתור את הבעיה הזו, אפשר להשתמש בכלים אוטומטיים לניהול תלות, שעוקבים אחרי תלות במאגרי המקור כדי לזהות גרסאות חדשות. הכלים האלה מעדכנים את קובצי הדרישות כדי לשדרג את התלות לפי הצורך, ולעתים קרובות כוללים מידע על שינויים או פרטים נוספים.
הצמדת גרסה חלה רק על תלות ישירה, ולא על תלות טרנזיטיבית. לדוגמה, אם מצמידים את גרסת החבילה my-library, ההצמדה מגבילה את הגרסה של my-library אבל לא מגבילה את הגרסאות של תוכנה שיש לה תלות ב-my-library. בשפות מסוימות, אפשר להגביל את עץ יחסי התלות של חבילה באמצעות קובץ נעילה.
אימות החתימה והגיבוב (hash)
יש כמה שיטות שבהן אפשר להשתמש כדי לאמת את האותנטיות של ארטיפקט שמשמש כתלות.
- אימות הגיבוב (hash)
גיבוב (hash) הוא ערך שנוצר עבור קובץ ומשמש כמזהה ייחודי. כדי לוודא שהקובץ לא נפגם, אפשר להשוות את הגיבוב של ארטיפקט עם ערך הגיבוב שחושב על ידי הספק של הארטיפקט. אימות ה-Hash עוזר לכם לזהות החלפה, שיבוש או פגיעה בתלות, באמצעות מתקפת אדם בתווך או פגיעה במאגר הארטיפקטים.
כדי להשתמש באימות הגיבוב, צריך לסמוך על כך שהגיבוב שמתקבל ממאגר הארטיפקטים לא נפגע.
- אימות חתימה
אימות החתימה מוסיף אבטחה נוספת לתהליך האימות. אפשר לחתום על ארטיפקטים במאגר הארטיפקטים, על ידי מנהלי התחזוקה של התוכנה או על ידי שניהם.
שירותים כמו sigstore מאפשרים למתחזקים לחתום על ארטיפקטים של תוכנה ולצרכנים לאמת את החתימות האלה.
Binary Authorization יכול לאמת שקובצי אימג' של קונטיינרים שנפרסו בסביבות זמן ריצה של Google Cloud חתומים באמצעות אישורים למגוון קריטריונים.
נעילת קבצים ותלות מהודרת
קובצי נעילה הם קובצי דרישות מלאים, שמציינים בדיוק איזו גרסה של כל תלות צריכה להיות מותקנת באפליקציה. קובצי נעילה, שנוצרים בדרך כלל באופן אוטומטי על ידי כלי התקנה, משלבים הצמדת גרסה ואימות חתימה או גיבוב עם עץ תלות מלא של האפליקציה.
כלי ההתקנה יוצרים עצי תלות על ידי פתרון מלא של כל התלויות הטרנזיטיביות במורד הזרם של התלויות ברמה העליונה, ואז כוללים את עץ התלות בקובץ הנעילה. כתוצאה מכך, אפשר להתקין רק את יחסי התלות האלה, מה שהופך את הבנייה לשחזורית ועקבית יותר.
שילוב של תלויות פרטיות וציבוריות
אפליקציות מודרניות מבוססות-ענן מסתמכות לעיתים קרובות על קוד פתוח, על קוד של צד שלישי וגם על ספריות פנימיות בקוד סגור. Artifact Registry מאפשר לכם לשתף את הלוגיקה העסקית שלכם בין כמה אפליקציות, ולעשות שימוש חוזר באותם כלים כדי להתקין ספריות חיצוניות ופנימיות.
עם זאת, כשמשלבים תלות פרטית וציבורית, שרשרת אספקת התוכנה שלכם חשופה יותר להתקפה של בלבול תלות. אם מפרסמים פרויקטים עם אותו שם כמו הפרויקט הפנימי במאגרי קוד פתוח, תוקפים יכולים לנצל מתקינים שהוגדרו בצורה לא נכונה כדי להתקין את הקוד הזדוני שלהם במקום את התלות הפנימית שלכם.
כדי להימנע מהתקפת בלבול תלות, אפשר לבצע מספר פעולות:
- כדי לאמת את החתימה או את הגיבוב של התלות, צריך לכלול אותן בקובץ נעילה.
- מפרידים את ההתקנה של יחסי תלות של צד שלישי ויחסי תלות פנימיים לשני שלבים נפרדים.
- משכפלים באופן מפורש את התלויות בצד שלישי שאתם צריכים למאגר הפרטי, באופן ידני או באמצעות פרוקסי pull-through. מאגרים מרוחקים ב-Artifact Registry הם שרתי proxy מסוג pull-through למאגרים ציבוריים במעלה הזרם.
- אפשר להשתמש במאגרים וירטואליים כדי לאחד מאגרי Artifact Registry רגילים ומרוחקים מאחורי נקודת קצה אחת. אתם יכולים להגדיר עדיפויות למאגרי מידע במעלה הזרם, כך שגרסאות של ארטיפקטים פרטיים תמיד יקבלו עדיפות על פני ארטיפקטים ציבוריים עם אותו שם.
- חשוב להשתמש במקורות מהימנים לחבילות ציבוריות ולקובצי אימג' בסיסיים.
- אפשר להשתמש ב-Assured Open Source Software כדי לגשת לאימג'ים פופולריים של Java ו-Python שנבדקו ואומתו על ידי Google.
- אפשר להשתמש בקובצי אימג' בסיסיים שסופקו על ידי Google או בצינור מאובטח של קובצי אימג' כדי ליצור קובצי אימג' בסיסיים משלכם.
הסרת תלות שלא נמצאת בשימוש
יכול להיות שהצרכים שלכם ישתנו והאפליקציה תתפתח, ולכן תרצו לשנות חלק מהתלות או להפסיק להשתמש בהן. המשך התקנה של יחסי תלות שלא נעשה בהם שימוש באפליקציה מגדיל את טביעת הרגל של יחסי התלות ומגדיל את הסיכון לפגיעה בגלל פרצת אבטחה ביחסי התלות האלה.
אחרי שהאפליקציה פועלת באופן מקומי, נהוג להעתיק כל תלות שהתקנתם במהלך תהליך הפיתוח לקובץ הדרישות של האפליקציה. לאחר מכן פורסים את האפליקציה עם כל התלויות האלה. הגישה הזו עוזרת לוודא שהאפליקציה שנפרסה פועלת, אבל סביר להניח שהיא גם תציג תלות שלא נדרשת בסביבת הייצור.
חשוב להפעיל שיקול דעת כשמוסיפים יחסי תלות חדשים לאפליקציה. כל אחד מהם עלול להוסיף קוד שאין לכם שליטה מלאה עליו. כחלק מצינור ה-linting והבדיקות הרגיל, כדאי לשלב כלים שמבצעים ביקורת על קובצי הדרישות כדי לקבוע אם אתם משתמשים בתלות או מייבאים אותן.
יש שפות שכוללות כלים שיעזרו לכם לנהל את התלות. לדוגמה, אפשר להשתמש ב-Maven Dependency Plugin כדי לנתח ולנהל תלות ב-Java.
בדיקת נקודות חולשה
תגובה מהירה לפגיעויות בתלות עוזרת להגן על שרשרת אספקת התוכנה.
סריקת נקודות חולשה מאפשרת לכם להעריך באופן אוטומטי ועקבי אם התלות שלכם מכניסה נקודות חולשה לאפליקציה. כלי סריקה של נקודות חולשה צורכים קובצי נעילה כדי לקבוע בדיוק באילו ארטיפקטים אתם תלויים, ומודיעים לכם כשמתגלות נקודות חולשה חדשות, לפעמים אפילו עם הצעות לשדרוג.
לדוגמה, Artifact Analysis מזהה נקודות חולשה בחבילות של מערכת הפעלה בקובצי אימג' של קונטיינרים. הוא יכול לסרוק תמונות כשהן מועלות ל-Artifact Registry ולעקוב אחריהן באופן רציף כדי למצוא נקודות חולשה חדשות למשך עד 30 יום אחרי שליחת התמונה.
אפשר גם להשתמש ב-On-Demand Scanning כדי לסרוק באופן מקומי תמונות של קונטיינרים ולחפש נקודות חולשה ב-OS, ב-Go וב-Java. כך תוכלו לזהות פגיעויות בשלב מוקדם ולטפל בהן לפני שתאחסנו אותן ב-Artifact Registry.
המאמרים הבאים
- כאן אפשר לקרוא על רכיבים של אבטחת שרשרת אספקת תוכנה ועל האופן שבו שירותיGoogle Cloud עוזרים לכם להגן על התוכנה.
- מידע על Artifact Registry
- מידע נוסף על ניתוח ארטיפקטים ועל סוגי סריקות