• בלוג
  • איך לא לייצר סיסמה אקראית

איך לא לייצר סיסמה אקראית

25/04/2023

ביקשתי מ Chat GPT לכתוב פונקציית פייתון שמחזירה סיסמה אקראית מתוך אורך ורשימה של תווים בסיסמה. זאת היתה התוצאה:

import random

def generate_password(length, symbols):
    password = ''
    for i in range(length):
        password += random.choice(symbols)
    return password

בפרומפט הבא ביקשתי ממנו לכתוב גירסה מאובטחת של אותו הקוד, וקיבלתי את זה:

import string
import random

def generate_password(length):
    chars = string.ascii_letters + string.digits + string.punctuation
    while True:
        password = ''.join(random.choice(chars) for _ in range(length))
        if (any(c.islower() for c in password)
            and any(c.isupper() for c in password)
            and any(c.isdigit() for c in password)
            and any(c in string.punctuation for c in password)):
            return password

אז נכון גם הרבה מתכנתים אנושיים שאני מכיר היו משתמשים ב random.choice במקום ב os.urandom בלי לשים לב, ואולי גם אתם כתבתם קוד כזה בעבר. בכל מקרה אלה כמה סיבות בגללן אני משתדל לא לכתוב כך, גם במערכות שאינן קריטיות לאבטחה של אף אחד:

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

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

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

  4. קוד נכון מאפשר כלים אוטומטיים - קיימים כלי ניתוח אוטומטיים היכולים לזהות חולשות בקוד. כשאני מקפיד להשתמש בכלים מאובטחים בכל המערכת, יהיה לי יותר קל לשלב את אותם כלים. כשהקוד שלי מלא בקוד לא מאובטח (גם אם בהקשרים לא קריטיים) אותם כלים פשוט יזרקו יותר מדי False Positives ויהיה קשה למצוא את הבעיות האמיתיות בקוד.

שורה תחתונה ובשביל העתיד, זו גירסה של הפונקציה שלא קיבלתי מ Chat GPT שמשתמשת ב os.urandom כדי לבחור סמלים לסיסמה בסדר אקראי ממש:

import os

def make_random_password(length=12, symbols='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789@$^_+&'):
    password = []
    for i in map(lambda x: int(len(symbols)*x/255.0), os.urandom(length)):
        password.append(symbols[i])
    return ''.join(password)