הטמעת IPC מאובטח באפליקציית Electron

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

פיתוח ותחזוקה של כל סוגי האתרים:

אתרי מידע או יישומי אינטרנט
אתרי תדמית, דפי נחיתה, אתרי חברה, קטלוגים מקוונים, חידונים, אתרי קידום, בלוגים, מקורות חדשות, פורטלי מידע, פורומים, אגרגטורים
אתרי מסחר אלקטרוני או יישומי אינטרנט
חנויות מקוונות, פורטלי B2B, שווקים, בורסות מקוונות, אתרי קאשבק, בורסות, פלטפורמות דרופשיפינג, מנתחי מוצרים
יישומי אינטרנט לניהול תהליכים עסקיים
מערכות CRM, מערכות ERP, פורטלים ארגוניים, מערכות ניהול ייצור, מנתחי מידע
אתרי שירות אלקטרוני או יישומי אינטרנט
פלטפורמות מודעות, בתי ספר מקוונים, בתי קולנוע מקוונים, בוני אתרים, פורטלים לשירותים אלקטרוניים, פלטפורמות אירוח וידאו, פורטלים נושאיים

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

השירותים שאנו מציעים
מציג 1 מתוך 1כל 2062 השירותים
הטמעת IPC מאובטח באפליקציית Electron
בינוני
~2-3 ימים

הכישורים שלנו:

שאלות נפוצות

העבודות האחרונות

  • פיתוח אפליקציית ווב עבור FEEDME
    פיתוח אפליקציית ווב עבור FEEDME
    1365
  • פיתוח חנות מקוונת לחברת FURNORO
    פיתוח חנות מקוונת לחברת FURNORO
    1330
  • פיתוח אפליקציית ווב עבור Enviok
    פיתוח אפליקציית ווב עבור Enviok
    1077
  • פיתוח CRM עבור Chasseurs
    פיתוח CRM עבור Chasseurs
    1113
  • פיתוח אתר עבור SBH Partners
    פיתוח אתר עבור SBH Partners
    1201
  • פיתוח אתר עבור Red Pear
    פיתוח אתר עבור Red Pear
    619

מדוע IPC לא מאובטח ב-Electron שובר את האפליקציה

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

ברגע שהערוץ פתוח "להכול" — בלי לבדוק את השולח, עם העברת אובייקטים גולמיים ובלי אימות קלט — הבידוד הופך לפורמליות, וכל שגיאה בצד הלקוח הופכת לפגיעות של האפליקציה.

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

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

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

דרך ערוץ כזה דליפת נתונים מתרחשת בלי פריצה — מספיק שתוקף ישפיע על תוכן הדף: סקריפט מוזרק מווידג'ט חיצוני, תגובה מוחלפת של שירות חיצוני או סתם שגיאה בקוד מפעילים פעולות שלממשק אסור שתהיה להן הרשאה.

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

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

מה נותן IPC מאובטח: השפעות מדידות

IPC מאובטח הוא לא "סימון וי בצ'קליסט אבטחה", אלא הפרדת ערוצים: כל חלון מקבל רק את השיטות שבאמת נחוצות לו, וכל השאר נחסם ברמת הסכימה. להלן — מה משתנה בארבעה צירים שהמזמין רואה ישירות.

זמן בנייה והפעלה

כאשר חוזה ה-IPC מתואר באופן הצהרתי, ולא נבנה מקריאות מפוזרות לאורך הקוד, הבנייה מפסיקה "לזלוג": המהנדס לא מחפש ידנית איזה ערוץ רשום היכן. בפועל זמן הבנייה מתקצר ב-20–40% בזכות כך שאין צורך לבנות מחדש מודולים שנפגעו מתיקונים עקיפים במטפלים משותפים.

סוג הכשל

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

עלות זמן ההשבתה

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

יציבות והגנת נתונים

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

השוואה בין גישות לארגון IPC

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

אפשרות מתי מתאימה מגבלות
ערוצים פתוחים אב טיפוס, כלי פנימי ללא גישה לנתונים רגישים כל קוד בחלון רואה את כל הערוצים; בטעינת תוכן צד שלישי זהו נתיב ישיר לדליפה
בידוד הקשר אפליקציה עם סקריפטים חיצוניים, ווידג'טים מוטמעים, טפסי תשלום דורש שכתוב הפניות לפונקציות מערכת דרך גשר מפורש; חלק מהספריות המוכנות יצטרכו התאמה
סקריפטים טרום-טעינה תרחיש עיקרי לבנייה לפרודקשן: נדרש סט מצומצם של פעולות הגשר הופך לנקודת כשל — יש לתעד את ה-API שלו בגרסאות ולכסות בבדיקות
פרוטוקול מותאם אישית החלפת נתונים מובנים בין חלונות ותהליכי רקע סכמת ולידציה וטיפול בשגיאות משל עצמו; סף כניסה גבוה יותר למפתחים חדשים

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

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

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

שלבי יישום IPC מאובטח

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

  1. ביקורת הערוצים הנוכחיים. אוספים מפה מלאה של הקריאות: אילו חלונות ולשוניות פונים למה, אילו ערוצים פתוחים, והיכן מופעל גישה ישירה למודולי מערכת מתוך הממשק. מתעדים כל ערוץ בסימון "נדרש / לא נדרש / נדרש עם הגבלות" — זה הבסיס לכל העבודה בהמשך.
  2. תכנון סכימת ה-IPC. מפרידים את הערוצים לפי ייעוד: קריאת נתונים, כתיבה, פעולות מערכת. עבור כל אחד מגדירים מי היוזם, אילו ארגומנטים מותרים ומה מוחזר. ערוצים רחבים מסוג "עשה מה שתרצה" מוחלפים בערוצים צרים — פעולה אחת לכל קריאה.
  3. הגדרת מדיניות. מפעילים בידוד הקשר, מכבים גישה ישירה למודולי מערכת מתוך הממשק, ומשאירים רק קריאות המאושרות במפורש. בודקים שכל חלון רואה רק את הערוצים שלו, ותוכן צד שלישי אינו מקבל גישה לפעולות מורשות.
  4. אימות בצד המערכת. כל נתון שהגיע מהממשק נבדק לפי סכימה לפני ביצוע: סוג, טווח, ערכים מותרים. קריאה שנדחתה לא אמורה להגיע למערכת הקבצים או לפקודות מעטפת.
  5. בדיקה. מריצים תרחישים: ניסיונות לקרוא לערוץ סגור, החלפת ארגומנטים, קריאה מחלון מוטמע עם תוכן צד שלישי. כל עקיפה צריכה להיתקל בסירוב, ולא בביצוע שקט.
  6. תיעוד ומסירה. מוסרים מפת ערוצים, רשימת מדיניות עם נימוק לכל הגבלה, והוראות כיצד להוסיף ערוץ חדש בלי לפתוח יותר מדי. לצוות שלכם נשאר נוהל ברור, ולא אוסף איסורים בלי הסברים.

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

מה הלקוח מקבל לידיו

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

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

הערכה נשארת אצלכם: אפשר להעביר אותה לצוות פנימי או לקבלן אחר. תארו את המשימה — נחזור עם הערכה ותוכנית, באיזה היקף הארטיפקטים האלה מכסים את המקרה שלכם.

מקרה בוחן: תיקון פגיעות ב-IPC

אפליקציית Electron — לקוח שולחני עם גישה לקבצים מקומיים ולקריאות מערכת. מטפלי תקשורת בין-תהליכית (IPC) הוצהרו עם הרשאות רחבות: שכבת הרינדור יכלה לקרוא לכל ערוץ ולהעביר ארגומנטים שרירותיים.

לא היו בדיקות בצד התהליך הראשי — הוולידציה התקיימה בממשק המשתמש, ולכן ניתן היה לעקוף אותה דרך הקונסול או סקריפט מוחלף.

מה היה לפני

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

מה שינו

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

מה נהיה

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

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

הניתוח הראה: אבטחת IPC אינה תיקון חד-פעמי, אלא חוזה בין תהליכים שיש לתחזק בכל ערוץ חדש.

במה שונה בידוד הקשר מערוצים פתוחים?

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

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

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

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

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

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

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

ספקות טכניים נפוצים

contextBridge ו-ipcRenderer.invoke אינם תוספת מעל ה-remote הישן, אלא קו מתאר אחר: הערוץ מתואר במפורש, וחלון הרנדרר אינו מקבל גישה לאובייקטים של Node.js.

התאימות עם הקוד הנוכחי נקבעת לפי האופן שבו האפליקציה מתקשרת עם המערכת כיום — דרך remote, sendSync סינכרוני או קריאות ישירות מהרנדרר. שלושת התרחישים הללו עוברים מיגרציה בדרכים שונות, ואנו מנתחים אותם לפני תחילת העבודה כדי לא לכתוב מחדש את האפליקציה כולה.

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

תאימות: האם הקוד הנוכחי יישבר לאחר המעבר?

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

מה עם ביצועים בנפחי נתונים גדולים?

הערוץ מחזיק בעומס כל עוד לא מעבירים דרכו אובייקטים גדולים בשלמותם. אנו מעבירים מקומות כאלה להעברה בזרימה ומוציאים פעולות כבדות מהרנדרר — תגובת הממשק מפסיקה להיות תלויה בגודל הנתונים.

האם ניתן לחזור אחורה אם משהו ישתבש?

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

כיצד אתם בודקים שההרשאות לא התרחבו?

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

נדון במשימה שלכם

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

לאחר מכן העבודה מתנהלת בשלבים, ובכל שלב אתם רואים מה בדיוק משתנה:

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

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

תארו את המשימה בצורה הנוחה לכם — נחזור עם הערכה, תוכנית וסדר עבודה.