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

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

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

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

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

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

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

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

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

דפדפן 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;');
}