הגנה על החשבון

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

הגנה על חשבונות פיתוח

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

שמירה על קבוצות בררניות

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

אף פעם לא להשתמש ב-HTTP, Ever

בעת בקשה או שליחה של נתונים, יש להימנע מחיבור HTTP. נניח שכל חיבורי HTTP כוללים ציתות או מכילים שינויים. תמיד צריך להעדיף HTTPS כי הוא כולל מובנה אבטחה שעוקפת את רוב התקפות אדם בתווך.

בקשה להרשאות מינימליות

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

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

XMLHttpRequest חוצה-מקורות

תוסף יכול להשתמש ב-XMLHttpRequest רק כדי לקבל משאבים ממנו ומדומיינים שצוינו בהרשאות.

{
  "name": "Very Secure Extension",
  "version": "1.0",
  "description": "Example of a Secure Extension",
  "permissions": [
    "/*",
    "https://*.google.com/"
  ],
  "manifest_version": 2
}

התוסף הזה מבקש גישה לכל מה שמופיע ב-developer.chrome.com ובתת-דומיינים של Google על ידי פירוט של "/*" ו-"https://*google.com/" בהרשאות. אם נפרץ, עדיין תהיה לו הרשאה לבצע אינטראקציה רק עם אתרים שעומדים בדרישות דפוס ההתאמה. התוקף לא יוכל לגשת אל "https://user_bank_info.com" או אינטראקציה עם "https://malicious_website.com".

הגבלה של שדות מניפסט

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

ניתן לחיבור חיצוני

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

{
  "name": "Super Safe Extension",
  "externally_connectable": {
    "ids": [
      "iamafriendlyextensionhereisdatas"
    ],
    "matches": [
      "/*",
      "https://*google.com/"
    ],
    "accepts_tls_channel_id": false
  },
  ...
}

משאבים נגישים לאינטרנט

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

{
  ...
  "web_accessible_resources": [
    "images/*.png",
    "style/secure_extension.css",
    "script/secure_extension.js"
  ],
  ...
}

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

לכלול מדיניות בנושא אבטחת תוכן בוטה

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

{
  "name": "Very Secure Extension",
  "version": "1.0",
  "description": "Example of a Secure Extension",
  "content_security_policy": "default-src 'self'"
  "manifest_version": 2
}

אם התוסף צריך לכלול סקריפטים ממארחים ספציפיים, אפשר לכלול אותם:

{
  "name": "Very Secure Extension",
  "version": "1.0",
  "description": "Example of a Secure Extension",
  "content_security_policy": "default-src 'self' https://extension.resource.com"
  "manifest_version": 2
}

הימנעות מממשקי API להפעלה

צריך להחליף ממשקי API שמפעילים קוד בחלופות בטוחות יותר.

document.write() ו-innerHTML

אומנם יכול להיות שיהיה פשוט יותר ליצור רכיבי HTML באופן דינמי עם document.write() ו-innerHTML, אבל היא משאירה את התוסף, ודפי אינטרנט שהתוסף תלוי בהם, פתוחים לתוקפים שמוסיפים סקריפטים זדוניים. במקום זאת, צריך ליצור צומתי DOM באופן ידני ולהשתמש ב-innerText כדי להוסיף תוכן דינמי.

function constructDOM() {
  let newTitle = document.createElement('h1');
  newTitle.innerText = host;
  document.appendChild(newTitle);
}

eval()

כדי למנוע התקפות, יש להימנע משימוש ב-eval() כשאפשר, כי כל קוד שיעביר את eval() יופעל לתוכו, שעלול להיות זדוני.

var xhr = new XMLHttpRequest();
xhr.open("GET", "https://api.example.com/data.json", true);
xhr.onreadystatechange = function() {
  if (xhr.readyState == 4) {
    // WARNING! Might be evaluating an evil script!
    var resp = eval("(" + xhr.responseText + ")");
    ...
  }
}
xhr.send();

במקום זאת, אני רוצה להשתמש בשיטות בטוחות ומהירה יותר, כמו JSON.parse()

var xhr = new XMLHttpRequest();
xhr.open("GET", "https://api.example.com/data.json", true);
xhr.onreadystatechange = function() {
  if (xhr.readyState == 4) {
    // JSON.parse does not evaluate the attacker's scripts.
    var resp = JSON.parse(xhr.responseText);
  }
}
xhr.send();

חשוב להשתמש בסקריפטים של תוכן בזהירות

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

  • סקריפטים של תוכן הם החלק היחיד בתוסף שמקיים אינטראקציה ישירה עם דף האינטרנט. לכן, דפי אינטרנט עוינים עלולים לתמרן חלקים ב-DOM שסקריפט התוכן תלוי בו, או לנצל התנהגות מפתיעה באינטרנט, כמו פריטים בעלי שם.
  • כדי לקיים אינטראקציה עם DOM של דפי אינטרנט, סקריפטים של תוכן צריכים לפעול באותו תהליך של רינדור כמו דף האינטרנט. כך סקריפטים של תוכן חשופים לדליפת נתונים דרך התקפות ערוץ צדדי (למשל Spectre), והשתלטות על ידי תוקף אם דף אינטרנט זדוני פורץ תהליך הרינדור.

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

  • נניח שהודעות מסקריפט תוכן נוצרו על ידי תוקף (למשל, אימות וניקוי רע של כל הקלט ולהגן על הסקריפטים מפני כתיבת סקריפטים בין אתרים).
  • נניח שהנתונים שנשלחים לסקריפט התוכן עשויים להדליף לדף האינטרנט. אין לשלוח מידע אישי רגיש (למשל סודות מהתוסף, נתונים ממקורות אחרים באינטרנט, היסטוריית גלישה) אל תוכן סקריפטים.
  • צריך להגביל את היקף הפעולות הקשורות שסקריפטים של תוכן יכולים להפעיל. אסור סקריפטים של תוכן כדי להפעיל בקשות לכתובות URL שרירותיות או להעביר ארגומנטים שרירותיים ממשקי API של תוספים (למשל, לא מאפשרים להעביר כתובות URL שרירותיות אל fetch או API של chrome.tabs.create).

רישום וניקוי נתונים

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

תוסף צריך להירשם רק לדומיין runtime.onRequestExternal, אם הוא צפוי מאתר או מתוסף חיצוני. תמיד צריך לוודא שהשולח תואם מקור מהימן.

// The ID of an external extension
const kFriendlyExtensionId = "iamafriendlyextensionhereisdatas";

chrome.runtime.onMessageExternal.addListener(
  function(request, sender, sendResponse) {
    if (sender.id === kFriendlyExtensionId)
      doSomething();
});

יש לבחון בקפידה את ההודעות שנשלחות באירוע runtime.onMessage מהתוסף עצמו. מוודאים ש-MessageSender לא הגיע מסקריפט תוכן שנפרץ.

chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
  if (request.allowedAction)
    console.log("This is an allowed action.");
});

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

function sanitizeInput(input) {
    return input.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/"/g, '&quot;');
}