מאמר זה הוא הראשון בסדרת פוסטים שאני כותב על הפעלת מוצרי SaaS ואתרי אינטרנט שונים ב-8 השנים האחרונות. אני אשתף כמה מהנושאים שעסקתי בהם, לקחים שלמדתי, טעויות שעשיתי, ואולי כמה דברים שהלכו כמו שצריך. תודיע לי מה אתה חושב!
עוד ב-2019 או 2020, החלטתי לשכתב את כל ה-backend עבור חסום שולח, אפליקציית SaaS המסייעת למשתמשים ליצור חסימות דוא"ל טובות יותר, בין היתר. בתהליך, הוספתי כמה פיצ'רים חדשים ושדרגתי לטכנולוגיות הרבה יותר מודרניות. הרצתי את הבדיקות, פרסתי את הקוד, בדקתי ידנית הכל בייצור, וחוץ מכמה סיכויים אקראיים, נראה שהכל עובד מצוין. הלוואי וזה היה סוף הסיפור, אבל...
כמה שבועות לאחר מכן, קיבלתי הודעה מלקוח (וזה מביך כשלעצמו) שהשירות לא עובד והם מקבלים הרבה מיילים שצריך לחסום בתיבת הדואר הנכנס שלהם, אז חקרתי. הרבה פעמים הבעיה נובעת מכך שגוגל הסירה את החיבור מהשירות שלנו לחשבון המשתמש, שהמערכת מטפלת בו על ידי הודעה למשתמש במייל ומבקשת ממנו להתחבר מחדש, אבל הפעם זה היה משהו אחר.
זה נראה כאילו ה-backend worker שמטפל בבדיקת אימיילים מול חסימות משתמש המשיך לקרוס כל 5-10 דקות. החלק המוזר ביותר - לא היו שגיאות ביומנים, הזיכרון היה בסדר, אבל ה-CPU עלה מדי פעם בזמנים אקראיים לכאורה. אז במשך 24 השעות הבאות (עם הפסקה של 3 שעות לישון - סליחה לקוחות 😬), הייתי צריך להפעיל מחדש את העובד בכל פעם שהוא קרס. מסיבה כלשהי, שירות Elastic Beanstalk חיכה זמן רב מדי להפעלה מחדש, וזו הסיבה שהייתי צריך לעשות זאת באופן ידני.
איתור באגים בייצור הוא תמיד כאב, במיוחד מכיוון שלא הצלחתי לשחזר את הבעיה באופן מקומי, שלא לדבר על להבין מה גורם לה. אז כמו כל מפתח "טוב", פשוט התחלתי לרשום הכל וחיכה שהשרת יקרוס שוב. מכיוון שה-CPU התגבר מעת לעת, הבנתי שזו לא בעיית מאקרו (כמו כשנגמר לך הזיכרון) וכנראה שהיא נגרמת על ידי דואר אלקטרוני או משתמש ספציפי. אז ניסיתי לצמצם את זה:
- האם זה קרס על מזהה דוא"ל או סוג מסוים?
- האם זה קרס עבור לקוח נתון?
- האם זה התרסק במרווח קבוע כלשהו?
אחרי שעות של זה, ובהיתי ביומנים יותר ממה שהייתי רוצה, בסופו של דבר, צמצמתי את זה ללקוח ספציפי. משם, שטח החיפוש הצטמצם לא מעט - ככל הנראה זה היה כלל חסימה או אימייל ספציפי שהשרת שלנו המשיך לנסות. למזלי, זה היה הראשון, וזו בעיה הרבה יותר קלה לניפוי באגים בהתחשב בכך שאנחנו חברה מאוד ממוקדת פרטיות ואינם מאחסנים או צופים בשום נתוני דוא"ל.
לפני שניכנס לבעיה המדויקת, בואו נדבר תחילה על אחת מהתכונות של Block Sender. בזמנו היו לי לקוחות רבים שביקשו חסימת תווים כלליים, מה שיאפשר להם לחסום סוגים מסוימים של כתובות דוא"ל לפי אותו דפוס. לדוגמה, אם תרצה לחסום את כל המיילים מכתובות דוא"ל שיווקיות, תוכל להשתמש בתו הכללי marketing@*
וזה יחסום את כל האימיילים מכל כתובת שהתחילה איתה marketing@
.
דבר אחד שלא חשבתי עליו הוא שלא כולם מבינים איך תווים כלליים עובדים. הנחתי שרוב האנשים ישתמשו בהם באותה דרך שאני עושה כמפתח, באמצעות אחד *
לייצג כל מספר של תווים. לרוע המזל, המשתמש הספציפי הזה הניח שאתה צריך להשתמש תו כללי אחד לכל דמות שרצית להתאים. במקרה שלהם, הם רצו לחסום את כל המיילים מדומיין מסוים (שזו תכונה מקורית שיש ל-Block Sender, אבל כנראה שהם לא הבינו זאת, וזו בעיה שלמה בפני עצמה). אז במקום להשתמש *@example.com
, הם השתמשו **********@example.com
.
POV: צופה במשתמשים שלך משתמשים באפליקציה שלך...
כדי לטפל בתווים כלליים בשרת העובד שלנו, אנו משתמשים בספריית Node.js שידוך, שעוזר בהתאמת גלוב על ידי הפיכתו לביטוי רגולרי. הספרייה הזו תסתובב אז **********@example.com
לתוך משהו כמו הביטוי הרגולרי הבא:
/[sS]*[sS]*[sS]*[sS]*[sS]*[sS]*[sS]*[sS]*[sS]*[sS]*@example.com/i
אם יש לך ניסיון עם regex, אתה יודע שהם יכולים להסתבך מאוד מהר מאוד, במיוחד ברמה החישובית. התאמת הביטוי לעיל לכל אורך סביר של טקסט הופכת ליקרה מאוד מבחינה חישובית, מה שבסופו של דבר קשר את ה-CPU בשרת העובד שלנו. זו הסיבה שהשרת היה קורס כל כמה דקות; זה יתקע בניסיון להתאים ביטוי רגולרי מורכב לכתובת דואר אלקטרוני. אז בכל פעם שהמשתמש הזה קיבל אימייל, בנוסף לכל הניסיונות החוזרים שבנינו כדי לטפל בכשלים זמניים, הוא היה קורס בשרת שלנו.
אז איך תיקנתי את זה? ברור שהתיקון המהיר היה למצוא את כל הבלוקים עם מספר תווים כלליים ברצף ולתקן אותם. אבל הייתי צריך גם לעשות עבודה טובה יותר בניקוי קלט המשתמש. כל משתמש יכול להזין ביטוי רגולרי ולהוריד את כל המערכת באמצעות א מתקפת ReDoS.
עיין במדריך המעשי והמעשי שלנו ללימוד Git, עם שיטות עבודה מומלצות, סטנדרטים מקובלים בתעשייה ודף רמאות כלול. תפסיק לגוגל פקודות Git ולמעשה ללמוד זה!
הטיפול במקרה הספציפי הזה היה די פשוט - הסר תווים כלליים עוקבים:
block = block.replace(/*+/g, '*')
אבל זה עדיין משאיר את האפליקציה פתוחה לסוגים אחרים של התקפות ReDoS. למזלנו יש מספר חבילות/ספריות שיעזרו לנו גם עם הסוגים האלה:
באמצעות שילוב של הפתרונות לעיל, ואמצעי הגנה אחרים, הצלחתי למנוע את זה מלהתרחש שוב. אבל זו הייתה תזכורת טובה שלעולם אינך יכול לסמוך על קלט משתמש, ותמיד עליך לחטא אותו לפני השימוש בו ביישום שלך. אפילו לא הייתי מודע לכך שזו בעיה פוטנציאלית עד שזה קרה לי, אז אני מקווה שזה יעזור למישהו אחר להימנע מאותה בעיה.
יש לך שאלות, הערות או רוצה לשתף סיפור משלך? הושט יד ב טויטר!
- הפצת תוכן ויחסי ציבור מופעל על ידי SEO. קבל הגברה היום.
- PlatoData.Network Vertical Generative Ai. העצים את עצמך. גישה כאן.
- PlatoAiStream. Web3 Intelligence. הידע מוגבר. גישה כאן.
- PlatoESG. פחמן, קלינטק, אנרגיה, סביבה, שמש, ניהול פסולת. גישה כאן.
- PlatoHealth. מודיעין ביוטכנולוגיה וניסויים קליניים. גישה כאן.
- מקור: https://stackabuse.com/behind-the-scenes-never-trust-user-input/
- :יש ל
- :הוא
- :לֹא
- $ למעלה
- 1
- 20
- 2019
- 2020
- 24
- 8
- a
- יכול
- אודות
- מֵעַל
- חֶשְׁבּוֹן
- למעשה
- הוסיף
- תוספת
- כתובת
- כתובות
- שוב
- נגד
- תעשיות
- להתיר
- לבד
- גם
- תמיד
- בין
- an
- ו
- כל
- האפליקציה
- בקשה
- ARE
- מאמר
- AS
- לשאול
- להניח
- At
- המתקפות
- לְהִמָנַע
- מודע
- קצה אחורי
- BE
- רזונת
- הופך להיות
- היה
- לפני
- מאחור
- מאחורי הקלעים
- להיות
- מוטב
- קצת
- לחסום
- חסימה
- אבני
- גבול
- לשבור
- נבנה
- אבל
- by
- CAN
- יכול לקבל
- אשר
- מקרה
- גרם
- גורם
- מסוים
- אופי
- תווים
- בדיקה
- קוד
- שילוב
- הערות
- חברה
- מורכב
- מסובך
- חישובית
- הקשר
- לתקן
- יכול
- יכולתי
- להתרסק
- התרסק
- מתרסק
- לִיצוֹר
- לקוח
- לקוחות
- נתונים
- עסק
- החליט
- פרס
- מפתח
- DID
- לא
- do
- תחום
- דון
- מטה
- ראוי
- כל אחד
- קל יותר
- אחר
- אמייל
- מיילים
- סוף
- הסתיים
- מסתיים
- זן
- שלם
- שגיאות
- במיוחד
- אֲפִילוּ
- בסופו של דבר
- כל
- כולם
- הכל
- דוגמה
- יקר
- ניסיון
- ביטוי
- כישלונות
- למדי
- רחוק
- מאפיין
- תכונות
- מעטים
- תרשים
- חשבתי
- סוף
- ראשון
- לסדר
- להתמקד
- בעקבות
- הבא
- בעד
- לשעבר
- החל מ-
- לקבל
- מקבל
- gif
- Git
- נתן
- טוב
- גדול
- מדריך
- היה
- לטפל
- מטפל
- ידות על
- קרה
- מתרחש
- יש
- לעזור
- עוזר
- אני מקווה
- שעות
- לרחף
- איך
- HTTPS
- i
- ID
- if
- in
- כלול
- קלט
- במקום
- אל תוך
- סוגיה
- בעיות
- IT
- עצמו
- עבודה
- רק
- שמר
- לדעת
- אחרון
- מאוחר יותר
- למד
- למידה
- אורך
- שיעורים
- לתת
- רמה
- LG
- סִפְרִיָה
- כמו
- סביר
- ll
- באופן מקומי
- רישום
- ארוך
- עוד
- נראה
- הרבה
- מאקרו
- עשוי
- באופן ידני
- רב
- שיווק
- להתאים
- תואם
- אולי
- me
- זכרון
- דקות
- טעויות
- מודרני
- טכנולוגיות מודרניות
- יותר
- רוב
- הרבה
- מספר
- צריך
- צר
- יליד
- נחוץ
- לעולם לא
- חדש
- תכונות חדשות
- הבא
- לא
- צומת
- Node.js
- מודיע
- מספר
- קטטה
- of
- on
- ONE
- לפתוח
- or
- אחר
- שלנו
- הַחוּצָה
- שֶׁלוֹ
- כְּאֵב
- חלק
- מסוים
- תבנית
- אֲנָשִׁים
- אפלטון
- מודיעין אפלטון
- אפלטון נתונים
- הודעות
- פוטנציאל
- מעשי
- למנוע
- כנראה
- בעיה
- תהליך
- הפקה
- מוצרים
- שאלות
- מָהִיר
- מהירות
- דַי
- אקראי
- RE
- לְהַגִיעַ
- הבין
- טעם
- סביר
- קיבלו
- מחדש
- regex
- רגיל
- תזכורת
- להסיר
- הסרת
- לייצג
- תקין
- טַבַּעַת
- כלל
- הפעלה
- ריצה
- s
- SaaS
- אמצעי הגנה
- אותו
- סצנות
- חיפוש
- נראה
- לִכאוֹרָה
- שולח
- סדרה
- שרת
- שרות
- Shadow
- שיתוף
- שיתוף
- גיליון
- צריך
- פָּשׁוּט
- since
- לִישׁוֹן
- So
- פתרונות
- כמה
- מישהו
- משהו
- מֶרחָב
- ספציפי
- דָרְבָּן
- Stackabuse
- תקנים
- החל
- עוד
- עצור
- חנות
- סיפור
- מערכת
- לקחת
- לדבר
- טכנולוגיות
- זמני
- נבדק
- בדיקות
- טֶקסט
- מֵאֲשֶׁר
- זֶה
- השמיים
- שֶׁלָהֶם
- אותם
- אז
- שם.
- אלה
- הֵם
- דבר
- דברים
- לחשוב
- זֶה
- זמן
- פִּי
- ל
- גַם
- מַעֲבָר
- ניסיתי
- סומך
- מנסה
- תור
- פנייה
- סוג
- סוגים
- מבין
- לצערי
- עד
- משודרג
- us
- להשתמש
- מְשׁוּמָשׁ
- משתמש
- משתמשים
- באמצעות
- שונים
- Ve
- מאוד
- באמצעות
- לצפיה
- הַמתָנָה
- רוצה
- רציתי
- היה
- לא היה
- צופה
- דֶרֶך..
- we
- אתרים
- שבועות
- טוֹב
- הלכתי
- היו
- מה
- מתי
- אשר
- כל
- למה
- ויקיפדיה
- רצון
- עם
- תיק עבודות
- עובד
- עובד
- היה
- כתיבה
- שנים
- אתה
- זפירנט