מתכנת אלמוני בכינוי ״Marak״ הוא שם לא ידוע לרוב הקוראים אבל הוא תחזק כמאה פרויקטים קוד פתוח בגיטהאב. שניים מהם מפורסמים ופופולריים ממש: colors ו-faker. הראשון, colors, זכה לעשרים מיליון הורדות שבועיות ו-24,000 פרויקטים השתמשו בו לצד חברות מסחריות רבות. faker שימש לבדיקות בג׳אווהסקריפט וזכה לשני מיליון הורדות שבועיות והשתמשו בו 2,500 פרויקטים.
זה המצב של לא מעט פרויקטים – פרויקטים אולטרא פופולריים, שמיליוני אנשים משתמשים בהם ותלויים בסופו של יום במאמץ של מפתח יחיד. במקרה הזה marak רצה למחות (או שנמצא במצוקה נפשית קשה – לפני שנתיים הוא נעצר על אחזקת פצצות) על עניין השימוש התאגידי בקוד פתוח בלי לתת תמורה. הדרך שלו היתה פשוטה – הוא מחק את faker.js מגיטהאב ו-npm, כאשר מה שנותר מהקוד הוא שאלה קריפטית: ״מה קרה לאהרון שוורץ?״
את הקוד החדש הוא הוציא כגרסת מייג׳ור: 6.6.6 – כיוון שהגרסה הקודמת היתה 5.5.3 – לא רבים שמו לב לכך. כיוון שגם אלו שמעדכנים ישירות את הפרויקטים שלהם לא עושים את זה עם הגרסה האחרונה.
המפתח הבין שזה לא תפס תשומת לב גדולה והחליט לגשת לפרויקט הגדול באמת: colors. הוא לא מחק את הפרויקט (שזה לגמרי זכותו) אלא עשה משהו זדוני בהרבה. מה? הוא הכניס ל-index.js, בנוסף לאיור גדול של איש עם דגל אמריקאי – גם לולאה אינסופית שמאיטה מאוד את הקוד שמשתמש בה (או שוברת אותו) ועושה את הדבר הבא:
let am = require('../lib/custom/american');
am();
for (let i = 666; i < Infinity; i++;) {
if (i % 333) {
}
console.log('testing testing testing testing testing testing testing'.zalgo)
}
הוא דחף את השינוי הזה כגרסת patch. כלומר כל הפרויקטים שמשתמשים בזה, ולא משתמשים בגרסה מקובעת, הורידו את הקוד הזה ובעצם נשברו.
וזו כבר חבלה מכוונת ממש.
בגיטהאב השעו את החשבון שלו ומנעו ממנו לבצע פעולות נוספות, אבל הנזק כבר נעשה כאשר מאות אלפי מתכנתים היו צריכים להבין מה קרה לקוד שלהם – אם הם לא השתמשו בספריות מקובעות. ניתן לראות ש-95,000 הורדות היו לפרויקט בגרסתו שעברה חבלה – כמה מהם בוודאי בקוד פרודקשן.
זה מראה עד כמה חשוב לכל מפתח להבין את המגבלות של הקוד הפתוח. קוד פתוח הוא באמת אחד מהמפעלים הגדולים של האנושות לדעתי. אבל יחד עם הכוח העצום של הקוד הפתוח מגיעה גם אחריות גדולה – שכל אחד יבדוק את מה שהוא משתמש בו ויבין שהקוד הזה, נרצה או לא נרצה, הוא קוד שאחר כתב. במקרה הזה ההתמודדות היא באמצעות קיבוע גרסאות.
באקוסיסטם של Node.js ניתן לקבע גרסאות בקלות עם package.lock וכן עם shrinkwrap – לכל אחד יש usecase שונה וכדאי להכיר. אם אתם משתמשים באקוסיסטם הזה, כדאי מאוד להשקיע כמה דקות בלימוד של הבעיה הזו ואיך מתמודדים איתה. כיוון שמדובר פה בקוד שמשולב במוצר שלנו אבל אנו לא כותבים אותו וגם לא יודעים מי כותב אותו. ל-npm יש כלי ניהול גרסאות ואנו חייבים להכיר אותם על מנת לא לשבור את הפרויקט שלנו או להכניס אליו קוד זדוני. אם אתם לא מכירים את נעילת הגרסאות או את הגרסאות ב-Node.js – שני הקישורים הקודמים הם עבורכם.
תודה רבה ללירן טל על שהביא לי את המידע הראשוני – אני ממליץ לכם לעקוב אחריו!