en
Feedback
ToCode

ToCode

Open in Telegram

טיפים קצרים למתכנתים מאת ינון פרק

Show more
1 419
Subscribers
No data24 hours
No data7 days
+130 days
Posts Archive
ToCode
1 419
# איך להשתמש ב Web Worker כדי לשפר ביצועים בקומפוננטת ריאקט רוב הזמן יישומי Front End לא עושים עבודה חישובית יותר מדי קשה, ולכן את רוב שיפורי הביצועים בריאקט אפשר לפתור עם צמצום קריאות מהשרת או צמצום render-ים. אבל מדי פעם כן יש לנו קומפוננטה שצריכה לעשות עבודה חישובית, וכשזה קורה כדאי לדעת מה לעשות - והתשובה הפשוטה היא Web Worker. ניקח לדוגמה את הקומפוננטה הבאה שמציגה את מספר המספרים הראשוניים עד מיליון:
import { useState } from 'react';

function isPrime(n) {
  for (let i=2; i < n/2; i++) {
    if (n % i === 0) {
      return false;
    }
  }
  return true;
}

function calculatePrimesUntilMillion() {
  let count = 0;
  console.log('Start');

  for (let i=2; i < 1000000; i++) {
    if (isPrime(i)) {
      count += 1;
    }
  }
  console.log('Ready');
  return count;
}

function App() {
  const [_, forceRender] = useState(0);

  return (
    <div className="App">
      <p>There are {calculatePrimesUntilMillion()} prime numbers &lt; 1,000,000</p>
      <button onClick={() => forceRender(v => !v)}>Calculate again</button>
    </div>
  );
}

export default App;
אני כתבתי לבד את הקוד שסופר ואני אעשה לכם ספוילר - זאת ממש לא הדרך הכי יעילה לספור מספרים ראשוניים. למעשה היא מספיק לא יעילה כדי שאם תריצו את הקומפוננטה הזאת על המחשב תוכלו להרגיש כמה שניות טובות שהדפדפן ממש "תקוע", ואפילו לא מגיב כשמשנים את גודל החלון. אם יהיה לכם מזל תקבלו מכרום את ההודעה שהטאב נתקע והוא מציע לכם לסגור אותו. כל זה קורה בגלל שלפונקציה calculatePrimesUntilMillion לוקח יותר מדי זמן לרוץ, ובזמן הזה היא תוקעת את כל ממשק המשתמש. ברור שהדרך הכי טובה לפתור את הבעיה במקרה הזה היא לתקן את הקוד כך שירוץ יותר מהר, אבל במקרה הכללי לפעמים אתם באמת צריכים לעשות הרבה עבודה. בשביל זה בדיוק יש לנו את ה Web Worker. ווב וורקר הוא דרך להפעיל קוד חישובי ב Thread אחר ולקבל ממנו תשובה. בריאקט אנחנו נשתמש ב useEffect כדי לשלוח הודעה ל Worker שלנו, ה Worker יעשה את החישוב בצורה אסינכרונית ובסוף נשתמש במשתנה State כדי לשמור את התוצאה ולהציג אותה. בעצם Web Worker יהפוך את הקוד שלנו מכזה ש"תוקע" את הדפדפן לקוד אסינכרוני רגיל שמחכה למשהו שיקרה. אני משתמש ב create-react-app בגירסה החדשה ביותר והוא משתמש ב webpack 5 ושם התמיכה מ Web Worker היא מובנית. בשביל להפוך את הפרויקט שלי להשתמש ב Web Worker אני צריך: 1. ליצור קובץ חדש בשם primes.js עם התוכן הבא:
function isPrime(n) {
  for (let i=2; i < n/2; i++) {
    if (n % i === 0) {
      return false;
    }
  }
  return true;
}

function calculatePrimesUntilMillion() {
  let count = 0;
  console.log('Start');

  for (let i=2; i < 1000000; i++) {
    if (isPrime(i)) {
      count += 1;
      postMessage({ count });
    }
  }
  console.log('Ready');
  return count;
}

onmessage = function(_ev) {
  const count = calculatePrimesUntilMillion();
  postMessage({ count });
}

2. לעדכן את קוד הקומפוננטה כדי לטעון את ה Worker:
const worker = new Worker(new URL('./primes.js', import.meta.url));
לעדכן את הקומפוננטה עצמה כך שתשתמש ב Worker, כלומר תשלח לו הודעות ותקבל ממנו עדכונים:
function App() {
  const [forceRender, setForceRender] = useState(0);
  const [primesCount, setPrimesCount] = useState(0);

  useEffect(() => {
    worker.onmessage = function(ev) {
      setPrimesCount(ev.data.count);
    };

    worker.postMessage({});
  }, [forceRender]);

  return (
    <div className="App">
      <p>There are {primesCount} prime numbers &lt; 1,000,000</p>
      <button onClick={() => setForceRender(v => !v)}>Calculate again</button>
    </div>
  );
}
בהפעלה בגירסה החדשה לא רק שהדפדפן ממשיך להגיב בזמן החישוב, אלא שאנחנו גם רואים את המספרים עולים - כי כל פעם שה Worker מוצא מספר ראשוני חדש הוא שולח Post Message שמגיע לקומפוננטה וגורם לעדכון המשתנה primesCount. אם אתם עובדים בגירסאות ישנות יותר של create-react-app או וובפאק, שווה לבדוק את הספריה https://github.com/developit/workerize-loader שמאפשרת לטעון Web Worker גם בוובפאק 4.

ToCode
1 419
# מעלה הילוך כשאנחנו מקשיבים למה שקורה בתעשיה או מסתכלים ברשת על כל מיני Best Practices אנחנו עלולים לטעות ולחשוב ש- 1. כולם כותבים Micro Services, מונוליט זה מיושן. 2. אצל כולם יש בדיקות (יחידה + קצה לקצה). 3. כולם עובדים עם הגירסאות החדשות ביותר של התלויות, מתקינים טלאי אבטחה בזמן ומבצעים Pen Testing לפי הוראות היצרן. 4. לכולם יש גיבויים מתוקתקים ופעם בחודש הם עושים תרגיל שחזור מגיבוי. 5. כולם משתמשים ב CI ומחזיקים מנגנון Deployment אוטומטי שיודע להריץ את הבדיקות ולהעביר גירסאות לפרודקשן ללא מגע יד. 6. לכולם יש מערכות ניטור מתוחכמות שמזהות פירצות לשרתים בזמן אמת. 7. כולם מחזיקים תיעוד עדכני של המערכת כך שמתכנתים חדשים יכולים בקלות להיכנס לקוד. 8. כולם מוחקים קוד שלא משתמשים בו. 9. כולם שולטים בטכנולוגיות בהן הם עובדים. אני בטוח שיש מתכנתים שיכולים לסמן "וי" על כל הרשימה כאן, אבל האמת שמעולם לא פגשתי אותם. המטרה של כל הכתבות האלה באינטרנט היא לא שנרגיש רע, אלא שתמיד יהיה לנו מול העיניים רעיון לצעד הבא. אבל זה לא אומר שחייבים עכשיו לקחת אותו. לכל סעיף כאן יש עלות. כמו שאי אפשר להתחיל נסיעה בהילוך חמישי, גם פרויקט צריך את הקצב והזמן שלו. עד שצוברים מהירות מספיק להשאיר את הרשימה מול העיניים ולהחליט עם עצמכם ומראש מה יהיה ההילוך הבא.

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

ToCode
1 419
# אופטימיות בטעות קניתי היום את הספר הלא נכון באודיבל. נו, רציתי לקנות ספר מסוים ואיכשהו הייתי בטוח שאני בעמוד שלו אפילו שהייתי בעמוד של ספר אחר ומפה לשם שילמתי על הספר שלא רציתי. עכשיו לא נעים להגיד אבל זאת לא הפעם הראשונה שזה קורה לי. אני מכיר את אמזון ואודיבל, וקיבלתי מהם כבר לא מעט החזרים בעבר אפילו על דברים הרבה יותר מוזרים. לכן בלי לחשוב פעמיים שלחתי אימייל לתמיכה להסביר את המצב והמשכתי לקנות את הספר שרציתי, בלי לחכות לתשובה של התמיכה או לזיכוי. הכל טוב הזיכוי יגיע. היכולת להתקדם בלי לחכות לראות שהצעד הקודם הצליח היא חלק ממה שאנחנו קוראים אופטימיות. ככל שיש לנו פחות נסיון בנושא מסוים כך נדרשת מנה גדולה יותר של אופטימיות כדי להתקדם, והיא רק הופכת יותר חשובה כשאנחנו מסתכלים על דברים גדולים יותר מספרים קוליים: 1. אופטימיות מאפשרת לי להמשיך להשקיע בפיתוח הפרויקט שלי, גם אם הוא עדיין לא הכניס אף לקוח. אני יודע שבסוף אמצא את הדרך למכירות, וכדאי שהפרויקט יהיה מוכן כשזה יקרה. 2. אופטימיות מאפשרת לי להמשיך ללמוד ולתרגל JavaScript, גם אם הקורות חיים שלי עדיין לא מספיק טובים כדי להגיע לראיון עבודה. אני יודע שבסוף אצליח למצוא את הדרך לראיונות וכדאי שאגיע מוכן כשזה יקרה. 3. אופטימיות מאפשרת לי לחקור לעומק כיוון מסוים לפיתרון בלי לדאוג שאולי זה לא הכיוון הנכון. אני יודע שבסוף אמצא את הבאג והדרך להגיע אליו היא להיכנס לעובי הקורה. בקצרה אופטימיות מאפשרת לנו להתקדם עם התהליך שעכשיו דורש את תשומת הלב שלנו (קניית הספר הנכון), ולהניח שתהליכים אחרים יסתדרו (אפילו שאולי לא לגמרי ברור עכשיו איך). ומרגע שהבנו איך האופטימיות משפיעה על ההתנהגות ביום יום אפשר להתחיל לתרגל אותה: גם אם אתה לא בטוח בכלל שתקבל זיכוי, בכל זאת לקנות את הספר הנכון. גם אם את מרגישה שלעולם לא יזמינו אותך לראיון עבודה, בכל זאת להמשיך ללמוד כל יום לפי שעון ולא לפי מוטיבציה. כי ההתנהגות משפיעה על הגישה, ולאורך זמן ההתנהגות האופטימית והגישה האופטימית עוזרות לנו להשקיע בתהליכים הנכונים ובכמות הנדרשת בשביל להתקדם.

ToCode
1 419
# הזמן הכי טוב לתקן בדיקה הזמן הכי טוב לתקן בדיקה הוא בדיוק ברגע שכתבת את הקוד ששבר אותה. ככל שמתרחקים מאותו הרגע קורים שני דברים רעים: 1. אתה שוכח מה עשית ולמה זה שבר את הבדיקה. 2. בדיקות נוספות נשברות בגלל שינויים חדשים. כמעט בכל פרויקט, אם אני מעביר חודשיים בלי להריץ את הבדיקות - אפילו אם באמת לא שברתי כלום מבחינת הלוגיקה של המערכת - עדיין יהיו לי לא מעט בדיקות שבורות לתקן. בעבודה עם גיט קל לייצר תהליך עבודה אוטומטי שמריץ את הבדיקות לפני הקומיט. בהנחה שאתם בפרויקט node ומריצים את הבדיקות עם npm test כל מה שצריך לעשות זה ליצור סקריפט חדש בתיקיית .git/hooks ולקרוא לו בשם pre-commit, בתוכו לכתוב את התוכן:
#!/bin/sh

echo "*****Running unit tests******"

git stash -q --keep-index

npm test

status=$?

git stash pop -q

exit $status
ולתת לו הרשאות הרצה:
$ chmod +x .git/hooks/pre-commit
בפעם הבאה שתנסו לעשות commit לקוד גיט קודם כל יריץ את הבדיקות ויצעק עליכם אם משהו נכשל. נ.ב. בפרויקט שנוצר עם create-react-app צריך להפעיל את שורת הרצת הבדיקות ובמקום לכתוב npm test נכתוב שם npm test -- --watchAll=false כדי להריץ את הבדיקות פעם אחת ולא לעקוב אחרי שינויים בקבצים.

ToCode
1 419
# איך לבדוק Custom Hook בריאקט ספריית react-testing-library מספקת כלים מצוינים לבדיקת קומפוננטות - אבל מה עושים עם Custom Hooks? האם עלינו להשאיר אותם לגורלם להישבר ללא בדיקות? מסתבר שיש פיתרון ואפילו פשוט - במקום לכתוב קוד שבודק את ה Hook, אנחנו כותבים קומפוננטה שמשתמשת ב Hook ובודקים את הקומפוננטה. בואו נראה דוגמה. ## ה Hook שאני רוצה לבדוק: useLocalStorage אחד ההוקים האהובים עליי בריאקט נראה כמו useState אבל מוסיף עליו אפקט כך שהמידע גם יישמר ב Local Storage. בפעם הבאה שיפעילו את הקומפוננטה היא תוכל לטעון את המידע מה local storage והמשתמש יוכל להמשיך את העבודה מאותה נקודה. הנה הקוד:
import { useEffect, useState, useCallback } from 'react';

export function useLocalStorage(key, initialValue) {
  const oldValue = localStorage.getItem(key);
  const [value, setValue] = useState(oldValue ? JSON.parse(oldValue) : initialValue);
  useEffect(() => {
    localStorage.setItem(key, JSON.stringify(value));
  }, [value]);

  const clearValue = useCallback(function clearValue() {
    localStorage.removeItem(key);
  }, [key]);

  return [value, setValue, clearValue];
}
ה Hook מחזיר שלוש פונקציות: שתיים ראשונות זהות למה ש useState מחזיר והשלישית היא פונקציה שמוחקת את הערך מה local storage. הערך עובר JSON.stringify לפני השמירה כדי שאפשר יהיה לשמור מידע מכל טיפוס נתונים. ## קוד הבדיקה: קומפוננטת עזר בשביל לבדוק את ה Hook אני פותח קובץ חדש בשם useLocalStorage.test.js ובתוכו מגדיר קומפוננטה פשוטה פנימית שתשתמש ב Hook:
import { render } from '@testing-library/react';
import { useLocalStorage } from './useLocalStorage';
import userEvent from '@testing-library/user-event'


function Dummy() {
  const [text, setText, clearText] = useLocalStorage('__test_text', 'hello world');
  return (
    <div>
      <p>dummy app: {text}</p>
      <button onClick={() => setText('Ouch!')}>set</button>
      <button onClick={() => clearText()}>clear</button>
    </div>
  );
}
מה שחשוב שהקומפוננטה תשתמש בכל היכולות של ה Hook. בעולם האמיתי הייתי יוצר עוד כמה קומפוננטות כאלה, אחת שתשמור מספרים, אחת שתשמור מערך וכך הלאה. את קוד הבדיקה אני כותב בהמשך הקובץ והוא בסך הכל משתמש בכפתורים של הקומפוננטה ובודק שהכל מתנהג כמו שצריך. בדוגמה שלנו אפשר לבדוק ששינויים בערך גם נכתבים ל Local Storage:
test('initial value is saved in local storage', () => {
  const screen = render(<Dummy />);
  const textElement = screen.getByText(/hello world/i);
  expect(textElement).toBeInTheDocument();
  expect(JSON.parse(localStorage.getItem('__test_text'))).toEqual('hello world');
});

test('changed value is saved in local storage', () => {
  const screen = render(<Dummy />);
  const setButton = screen.getByText(/set/i);
  userEvent.click(setButton);
  expect(JSON.parse(localStorage.getItem('__test_text'))).toEqual('Ouch!');
});

test('clear value removes the value from local storage', () => {
  const screen = render(<Dummy />);
  const clearButton = screen.getByText(/clear/i);
  userEvent.click(clearButton);
  expect(localStorage.getItem('__test_text')).toBe(null);
});
או שאם יש כבר ערך ב Local Storage אז נטען אותו ונשתמש בו לתצוגה:
test('existing value is read', () => {
  localStorage.setItem('__test_text', JSON.stringify('lazy dog'));
  const screen = render(<Dummy />);
  const textElement = screen.getByText(/lazy dog/i);
  expect(textElement).toBeInTheDocument();
});
ככל שתגדירו יותר קומפוננטות בדיקה פנימיות (ותמיד באותו קובץ הבדיקה) כך תוכלו לבדוק יותר התנהגויות שונות של ה Hook שלכם ולהיות בטוחים שהוא יעבוד בכל סיטואציה.

ToCode
1 419
# יש'ך באג - "אין מצב, אצלי זה עובד" - "ככה זה כשלא משאירים זמן לבדיקות" - "ככה זה כשאין תהליכי עבודה מסודרים" - "איך לא מצאו את זה ב QA??" - "זה לא באג זה פיצ'ר" - "הי הי אף אחד באיפיון לא דיבר על ה Use Case הזה" - "לא הצלחתי לשחזר נמשיך לעקוב" - "מעניין! אפשר לראות?" אתם לא בוחרים כמה באגים לייצר אבל כן בוחרים איך להגיב כשמגלים אחד. וההשפעה של הבחירה היא הרבה יותר משמעותית ממה שיקרה עם הבאג הספציפי.

ToCode
1 419
## באג Goto Fail במנגנון SSL של אפל ואם חשבתם שאפל תצא נקיה מהרשימה הזאת אז כנראה שכחתם את אחד הבאגים המביכים של העשור - ה Goto Fail. ב 2014 התגלה באג קריטי באופן שבו מכשירי אפל מפענחים תעודות SSL, באג שאיפשר לכל אחד לזייף מנעול SSL וספארי יציג את המנעול כמו תקשורת מאובטחת רגילה לגמרי. הבאג הזה זכה לתהודה קודם כל כי היה מאוד קל לראות אותו: פשוט תגלוש לאתר הדוגמה ואם אתה רואה את המנעול שמסמן תקשורת מאובטחת אתה יודע שעבדו עליך; אבל יותר מזה הוא זכה לתהודה כי הקוד שגרם לו היה זמין בקוד פתוח והופץ יחד עם כל הדיווח על הבאג. היכולת שלנו לראות בעיניים את הקוד שגרם לחולשה הפכה את הסיפור לפיקנטי וכל אחד ניסה לחשוב אם הוא היה מצליח לזהות את הבעיה בקוד. לקריאת הקוד עם התקלה ופרטים נוספים על הסיפור שווה לקפוץ ל: https://nakedsecurity.sophos.com/2014/02/24/anatomy-of-a-goto-fail-apples-ssl-bug-explained-plus-an-unofficial-patch/

ToCode
1 419
# תזכורת: 5 תקלות אבטחה יותר גרועות מ log4j בימים האחרונים כולם מדברים על הפירצה הנוראית ב log4j, ולפעמים אני מרגיש שקל לשכוח שההיסטריה הזאת היתה פה בעבר ותהיה שוב בעתיד. אז הנה תזכורת ל-5 בעיות אבטחה מהעבר שלידן log4j נדמית כמו טיול בפארק. ## ספקטר ספקטר הוא שם כולל לסידרה של בעיות אבטחה במעבדים שמשתמשים במנגנון שנקרא branch prediction, שזה בעצם רוב המעבדים בעולם. הבגדול של ספקטר הוא שתוכנית אחת יכולה לקבל מהמעבד מידע שהיא לא צריכה לראות לגבי התנהגות של תוכניות אחרות על המכונה, וההשפעה הפרקטית הראשונה היתה האפשרות של אתרים שנפתחים בטאב אחד בדפדפן כרום לדעת מה קורה בכל הטאבים האחרים שלכם. מאז שהתגלה ב 2018, כל החברות הגדולות הוציאו טלאי אבטחה שנועדו להתמודד עם ספקטר: כל הדפדפנים כוללים היום מנגנוני הגנה ספציפיים לבאג זה, מערכות הפעלה כוללות הגנה ספציפית נגד תוכניות שמנסות לנצל את ספקטר, ואפילו המעבדים עצמם מגיעים עם מנגנוני הגנה שמזהים או מנסים לזהות ניצול לרעה של התנהגות החיזוי שלהם. למרות כל ההשקעה ההגנות שיש לנו היום מספקטר מתבססות כולן על "לתחמן" את התוקף ולא לאפשר לו לנצל את החולשה מתוך הבנה שהחולשה עצמה היא משהו שמאוד קשה לתקן. לקריאה נוספת על ספקטר שווה לבקר בדף הפירצה: https://spectreattack.com ## הארטבליד חלק גדול מתשתית התקשורת המאובטחת באינטרנט משתמש בספרית קוד פתוח בשם OpenSSH. בשנת 2012 שינוי בקוד שהוכנס לספריה זו גרם לכך שכל שרת שהשתמש בספריה היה פגיע ותוקפים היו יכולים לקרוא את כל הזיכרון של השרת, כולל את כל מפתחות ההצפנה הפרטיים. התיקון בספריית OpenSSH יחד עם גילוי הפירצה התרחשו רק ב 2014, כלומר שנתיים מאוחר יותר, וחשפו את העולם לסכנות בשימוש בספריות קוד פתוח. אף אחד לא יודע איזה ארגונים וגורמים הכירו את הפירצה בשנתיים בין 2012 ל 2014 והשתמשו בה כדי לרגל אחרי משתמשים ולפרוץ תקשורת שנחשבה מאובטחת. בזמן גילוי הפירצה מעריכים כי באזור ה 17% מסך השרתים באינטרנט הריצו גירסה פגיעה של OpenSSH. מה שמפחיד באמת ב Heartbleed זה שלמרות שהבאג תוקן, אין לנו דרך לדעת כמה בעיות אבטחה נוספות קיימות במוצרי קוד פתוח המהווים את התשתית של הרשת - וכן גם הבאג ב log4j הוא עוד דוגמה לתקלות מסוג זה. לקריאה נוספת על hearbleed אפשר לבקר בדף הפירצה: https://heartbleed.com ## טרידנט אחמד מנסור היה פעיל פוליטי שניהל בלוג הקורא לרפורמות בזכויות אדם באיחוד האמירויות. באוגוסט 2016 הוא קיבל הודעת סמס שמבטיחה גילויים חדשים על עינויים בבתי הכלא של איחוד האמירויות בלינק המצורף. במקום ללחוץ על הלינק מנסור שלח את ההודעה לבדיקה במעבדת אבטחת מידע, שם הצליחו לגלות שהלינק שייך לחברת NSO, ואם מנסור היה לוחץ אז האייפון 6 שלו היה נפרץ ותוכנת הריגול פרסוס היתה מותקנת עליו באופן אוטומטי ובלי ידיעתו של הפעיל. שלושת בעיות האבטחה הקריטיות שאיפשרו התקנת תוכנת ריגול דרך לחיצה על לינק זכו לשם Trident, וחשפו את העולם לעולם האפל של ריגול דרך טלפונים. מאז NSO ותוכנת פגסוס הפכו מפורסמות ואין לדעת כמה בעיות אבטחה קריטיות במערכות הפעלה של טלפונים עוד נמצאות אצלם במחסנים ומשמשות להתקנת תוכנות ריגול בלי ידיעת בעלי הטלפונים. בכתבה הבאה תוכלו למצוא את כל הפרטים העסיסיים על הסיפור: https://citizenlab.ca/2016/08/million-dollar-dissident-iphone-zero-day-nso-group-uae/ ## פרינט נייטמייר בתחילת יולי השנה מייקרוסופט דחפה עדכון אבטחה דחוף למערכת הפעלה Windows כדי לתקן באג בסרביס שנקרא Print Spooler. הבאג אפשר לתוקפים להריץ קוד מרחוק על כל מכונת Windows והשפיע על כל הגירסאות של Windows. הבאג הזה זכה לתהודה בגלל שהניסיון הראשון של Microsoft לתקן אותו לא הצליח, וחוקרי אבטחה המשיכו לנצל אותו ולהעלות Exploits נוספים גם אחרי התיקון, וזה לקח כמה סבבים עד ש Microsoft סגרה סופית את הפירצה. פרינט נייטמייר הזכיר לנו שגם מערכות ההפעלה של המחשבים שלנו פגיעות ושבדיוק כמו בטלפונים, החולשות במערכת ההפעלה הן הבוננזה של הסייבר ההתקפי. (זיכרו שפירצה זו היתה קיימת בחלונות בכל הגירסאות, ורק דמיינו כמה שנים היא מאפשרת גישה פתוחה לכל מערכת חלונות בעולם לפני שהפירצה תוקנה, וכמה פירצות כאלה עוד יש שאנחנו לא יודעים עליהן). אפשר למצוא עוד מידע על Print Nightmare בתזכיר שמייקרוסופט הוציאה כאן: https://msrc.microsoft.com/update-guide/vulnerability/CVE-2021-34527

ToCode
1 419
# לא מאמין שלא עשיתי Save בין כל הבאגים שאפשר לפגוש אלה שקשורים לדברים טפשיים מחוץ לקוד הם המרגיזים ביותר- כשאתה מגלה שהתיקון שעשית בקוד לא באמת נקלט כי וובפאק נתקע, אחרי חצי שעה שאתה מנסה להבין למה גם אחרי התיקון דברים לא עובדים. כשאתה מגלה שאתה מדבג את הדבר הלא נכון, כי שכחת ללחוץ Save. כשאתה מגלה שהמערכת לא עובדת כי השתמשת ב ^ ב package.json והותקנה גירסה חדשה מדי של אחת התלויות. כשאתה מגלה שכל הזמן הזה שחיפשת את הבעיה בעצם היית מחובר לשרת הלא נכון. מה שכל כך מרגיז בבאגים האלה הוא שממש בקלות היה אפשר לגלות אותם, אם רק הייתי חושב על לבדוק את הדבר הנכון מההתחלה. והאופטימיות במפגש עם כל באג מהסוג הזה באה מהשיעור שהוא מלמד- כשדברים מוזרים קורים, קודם כל לסגור ולפתוח את webpack לפני שממשיכים. כשדברים מוזרים קורים, קודם כל לעשות Save. כשדברים מוזרים קורים, קודם כל להשוות גירסאות שהותקנו עם npm ls כשדברים מוזרים קורים, קודם כל להסתכל על איזה שרת אני עובד. ככל שרשימת הבדיקות המהירות שלכם מדויקת יותר ומתאימה יותר למצבים שאנחנו נתקלים בהם ביום יום, כך עולה סיכוי לחסוך את ההתברברות בפעם הבאה.