הבלוג של ינון פרק

טיפים קצרים וחדשות למתכנתים

תוך כמה זמן זה יהיה מוכן?

04/06/2018

מה אתם עונים כששואלים אתכם כמה זמן ייקח לכם לפתח פיצ'ר מסוים? הנה כמה רעיונות:

  1. תוך שבוע יש משהו באוויר. אחרי זה ייקח עוד שבועיים-שלושה לייצב את זה ולסיים את כל הפיצ'רים.

  2. תוך שבועיים, אבל לא בטוח שעם כל הפיצ'רים.

  3. תוך שובעיים (אבל אם תשלם יותר אוכל לסיים גם תוך שבוע).

  4. מאמין שייקח שבועיים אבל קשה לדעת. בוא נתחיל ונדבר על זה שוב בעוד שבוע.

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

  6. ייקח לפחות חודש לכתוב את הקוד ולתקן את כל הדברים שאשבור בדרך (כי בפיצ'ר הקודם דילגנו על בדיקות אוטומטיות).

  7. תוך שעתיים הכל באוויר (ולכו חפשו אותי אחרי שהכל יישבר).

מי הזיז את הבדיקה שלי

03/06/2018

זוכרים את הבדיקה האוטומטית ההיא שממש התאמצתם לכתוב? זאת שכוללת Mocking למלא מחלקות במערכת ועבדה ממש טוב פעם אבל האמת שאם נהיה כנים כבר כמה זמן שהיא מכשילה לכם את חבילת הבדיקות?

או הבדיקה ההיא שרצה מול שירות רשת חיצוני שעובד רוב הזמן חוץ מימי שלישי ואז צריך לזכור שכשבדיקה נכשלת ביום שלישי לא לשבור את הראש על זה כי זה נורמלי? (הי כתבנו את זה ב Wiki לא קראת?)

או הבדיקה שממש כמעט עובדת כי באמצע שכתבת אותה פתאום צץ משהו חשוב ובאמת עוד יומיים-שלושה גג השבוע אני מסיים את העבודה עליה?

נראה לי שכדאי למחוק אותן.

אמינות היא התכונה הכי חשוב של בדיקות אוטומטיות. ואם על הבדיקות האוטומטיות אתם לא יכולים לסמוך אז מה כבר נשאר?

ממה אנחנו מפחדים? סיווג בעיות אבטחת מידע

02/06/2018

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

המשך קריאה

ביטויים רגולאריים FTW

31/05/2018

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

"יש מתכנתים שחושבים- יש לי בעיה, אשתמש בביטוי רגולארי לפתור אותה. עכשיו יש להם שתי בעיות".

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

המשך קריאה

שתי מחשבות על GDPR

30/05/2018

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

שתי נקודות ששווה להכיר אם אתם מתכוונים להכניס גולשים מאירופה בתקופה הקרובה:

המשך קריאה

סיכום סדנא: מתקפת Hash Length Extension

29/05/2018

אתמול התקיימה סדנת אבטחת מידע בנושא מתקפה קצת מוזרה שנקראת Hash Length Extension. אחד המופעים הראשונים של המתקפה היה כש Flickr העלו API הפגיע למתקפה זו ב 2009. בסדנא דיברנו על המתקפה ואיך להשתמש נכון בפונקציות Hash ואם אתם מנויים מוזמנים לצפות בהקלטה. למי שלא אסכם כאן את עיקרי הדברים.

המשך קריאה

געגועים לטכנולוגיות משעממות

28/05/2018

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

אבל מאז קרו שני דברים: הראשון שריילס התחילה לעבוד הרבה יותר טוב. אני מתכוון שטויות שהיו קיימות בפריימוורק ב 2007 הן עכשיו בקושי צל של זיכרון רחוק. רעיון הזוי אחד כזה שאני זוכר היה הבחירה ליצור באופן אוטומטי ומובלע את המיפוי בין URL לבין פונקציה שמטפלת בו (מה שנקרא טבלת הניתוב או Routes). זה יצר המון בעיות אבטחה בגלל מתכנתים שלא שמו לב שפונקציה פנימית שלהם חשופה לעולם החיצון. גם מנגנון ה ORM השתפר פלאים וכמובן היכולת לשלב את Rails עם ספריות אחרות.

הדבר השני הוא שספריות קוד שאינן ריילס, כולל בשפות אחרות, התחילו להעתיק את היכולות החדשניות שריילס הביאה לשולחן. ספריית Django של פייתון, הספריה sails.js של node וכמובן play ב Java. ריילס נהיה משעמם כי החדשנות שלו ניצחה והוא הפך מספריה לתפיסת עולם.

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

(עוד) בעיה עם קוד

27/05/2018

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

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

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

בואו נכתוב DSL בפייתון

26/05/2018

המונח DSL או Domain Specific Language מתיחס לשפה פשוטה שאנחנו ממציאים כדי לתאר בעיות בתחום מסוים. השפה הרבה יותר מוגבלת משפת תכנות רגילה אבל זה גם בדיוק היתרון שלה - את הבעיות מאותו Domain השפה יודעת לתאר בצורה הרבה יותר מדויקת משפות כלליות.

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

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

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

add x 20
add y 50
add z x
add z y
sub z 2
print z

התוכנית כוללת 3 פקודות: add, sub ו print. כל פקודה מקבלת שם של אוגר כפרמטר ראשון וערך כפרמטר שני. הפקודה add מוסיפה את הערך לאוגר, הפקודה sub מחסירה את הערך מהאוגר ו print מדפיסה את ערך האוגר. בסיום תוכנית הדוגמא נקבל את הפלט 68.

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

הקוד עבור המחלקות לפקודות השונות:


class Cmd:
    def __init__(self, args):
        self.args = args

    def get_int_or_value(self, name, mem):
        if name in string.ascii_letters:
            return mem[name]
        else:
            return int(name)

class CmdAdd(Cmd):
    def run(self, mem):
        reg, arg = self.args
        mem[reg] += self.get_int_or_value(arg, mem)

class CmdPrint(Cmd):
    def run(self, mem):
        arg = self.args[0]
        print(self.get_int_or_value(arg, mem))

class CmdSub(Cmd):
    def run(self, mem):
        reg, arg = self.args
        mem[reg] -= self.get_int_or_value(arg, mem)

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

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

COMMANDS = {
        'add': CmdAdd,
        'print': CmdPrint,
        'sub': CmdSub,
        }

ונרצה לייצר מחלקה של Parser שתרוץ על הקלט ותייצר את האוביקטים המתאימים לטיפול בכל שורה:

class MyParser:
    def __init__(self, fname):
        self.fname = fname
        self.memory = defaultdict(int)

    def parse(self, line):
        cmd_name, *args = line.split()
        return COMMANDS[cmd_name](args)

    def run(self):
        with open(self.fname) as f:
            for line in f:
                cmd = self.parse(line.strip())
                cmd.run(self.memory)

p = MyParser('dsldemo.txt')
p.run()

כמה נקודות לשים לב אליהן בתוכנית:

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

  2. קל מאוד לשנות את מבנה הקלט באמצעות שינוי הקוד ב MyParser. מוזמנים כתרגיל לנסות לעבור למבנה קלט כזה:

x += 20
y += 50
z += x
z += y
z -= 2
z

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

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

אם זה עובד אל תגעו?

25/05/2018

מתי בפעם האחרונה התקנתם עדכון קושחה ל Router שלכם? או החלפתם Router רק כי הוא היה ישן מדי (אבל עדיין עבד?).

מחקר של קספרסקי שפורסם היום חושף דלת אחורית בנתבים ישנים של D-Link. הנתב נקרא DIR-620 והפירצה די חמורה: היא מאפשרת לכל אחד ברשת להשתלט על הנתב שלכם באמצעות שם משתמש וסיסמא סודיים ששמורים בקושחה של הנתב ולא ניתנים לשינוי דרך הממשק.

די-לינק מצדם הודיעו שאינם מתכוונים לשחרר כלל עדכון קושחה כי הנתב ישן מדי (הוא אכן מיוצר מ 2010). וזאת בעצם הבעיה הקשה שיש לנו עם אבטחת מידע והתקני חומרה: מצד אחד ראוטר מ 2010 לא נתפס כפריט פרהיסטורי במיוחד אם הוא עובד. מצד שני מבחינת היצרנים ככל שהפריט ישן יותר כך יש פחות סיכוי לשדרוגים ותקלות אבטחה חמורות נשארות ללא טיפול.

קישור לפרסום המקורי: https://www.bleepingcomputer.com/news/security/backdoor-account-found-in-d-link-dir-620-routers/