
SQL Injection – הזרקת נתונים ב- SQL
הקדמה: SQLI – הזרקת נתונים עם SQL
בעולם האינטרנט של היום, אין כמעט אתר שלא משתמש במסדי נתונים כדי לאחסן ולארגן את המידע שהוא מכיל. מסדי נתונים אלו מהווים את המטרה הכי גדולה של ההאקרים של ימינו, משום שהם יכולים להכיל מידע רגיש ביותר כמו פרטים אישיים ואפילו מספרים של כרטיסי אשראי וחשבונות בנק.
אחת השיטות הנפוצות לפריצת מסד נתונים (והיותר פשוטות לביצוע) נקראת הזרקת נתונים (באנגלית SQL Injection).
פורץ המשתמש בשיטה זו, יכול (במקרה הטוב) להזין או לשנות נתונים שהוא לא אמור לשנות, כמו לשדרג את הפרופיל שלו, לפגוע בפרופילים אחרים וכו׳, או (במקרה היותר גרוע) להוציא מידע רגיש, כמו סיסמאות של משתמשים אחרים, כתובות דואר אלקטרוני או אפילו מספרים של כרטיסי אשראי. על ידי הזרקת נתונים, הפורץ יוצר לעצמו למעשה גישה חופשית ומלאה למסד הנתונים שלכם!
ההיסטוריה מלאה בדוגמאות של פריצות שכאלה, כמו לדוגמה הפריצה הגדולה לאתר של SONY לאחרונה, בה לפי ההערכות נגנבו מליוני מספרים של כרטיסי אשראי. פריצה זו נעשתה בשיטת SQL Injection.
גם הפריצה של ההאקר הסעודי לאתרים הישראליים, לפי ההערכות, נעשתה באותה שיטה.
ההבדל בין שני המקרים הוא שבמקרה של ההאקר הסעודי, האתרים לא היו מאובטחים והיוו מטרה קלה. במקרה של SONY, ההאקרים היו צריכים להיות מאד מתוחכמים בשביל לעשות זאת.
דוגמאות לפריצה בשיטת SQL Injection
הדוגמה הבאה מראה לכם מצב בו הקוד המוזן בשפת SQL אינו מוגן מפני סימנים מיוחדים על ידי מנגנון Escape Characters. שורת הקוד הבאה מגדירה את השאילתה למסד הנתונים:
SELECT * FROM `users` WHERE `name` = '$user_name'
המשתנה בשם $user_name מייצג את שדה הקלט אליו המשתמש או התוקף יכול להזין נתונים.
התוקף יכול להשתמש בשורת הקוד הבאה, ולהזינה במקום שם המשתמש:
' or '1' = '1
על ידי שימוש בקוד הנ"ל אנו משנים את השאילתה המקורית. להלן התוצאה:
SELECT * FROM `users` WHERE `name` = '' or '1' = '1'
לפי הגדרת השאילתה, מסד הנתונים בוחר את כל הפרטים (הסימן * אומר בחר הכל) של משתמש מסויים על פי התנאי המוגדר. כשהתנאי הוא אמת, מסד הנתונים יציג את הנתונים של אותו משתמש.
מכיוון שאחד תמיד שווה לאחד (1 = 1) התנאי יהיה תמיד אמת, ולכן כל הפרטים של כל המשתמשים באותה טבלה יוצגו לתוקף.
ניתן אפילו למחוק פיסות קוד על ידי שימוש בסימון של הערה:
' or '1' = '1' -- ' ' or '1' = '1' /* ' ' or '1' = '1' ({ '
על ידי שימוש באחד משלושת הסימנים המוגדרים בשפת SQL להערה, ניתן למחוק כל קוד הנמצא אחרי אותו סימון.
אבטחה מפני SQLI
הבעיה שלנו היא הכנסת תווים מסוכנים, כמו: ״ ׳ () {} [] <>
וכד׳. בשפת SQL קיימת פונקציה מובנית בדיוק בשביל זה. היא פשוט לוקחת את התווים המסוכנים ומזינה אותם כמו שהם לשדה הנתונים, במקום להתייחס אליהם כחלק מהשאילתה. הפונקציה נקראת mysql_real_escape_string
ומשתמשים בה כך:
$query = "SELECT * FROM `users` WHERE `name` = '$user_name' AND `password` = '$password'"; $user_name = mysql_real_escape_string($_POST[user_name]); $password = mysql_real_escape_string($_POST[password]); mysql_query($query);
הפונקציה הנ"ל לוקחת את התווים \x00, \n, \r, \, ', " \x1a
ומזינה את התו \
לפניהם וכך נמנע השימוש בתווים כחלק מהשאילתה. השימוש בפונקציה זו מומלץ מאד בכל אפליקציה כדי לשמור על המידע הנמצא במסד הנתונים לפני הרצת השאילתה.

היי,
יש לי שאלה חשובה האם מדובר כאן בהזרקת נתונים ואם כן מדוע?
string idText = userID.Text;
string nameText = userName.Text;
//–SqlCommand nameCommand = new SqlCommand("SELECT * FROM GradesTable1 WHERE Id=" + idText + " AND Name='" + nameText + "';", sqlConnection1);
אני שואל מפני שאינני מבין בתחום ושני מורים פרטיים אחד סיים ללמו מדעי המחשבו השני מסיים הנדסאות תוכנה – אמרו לי דברים שונים ואינני רוצה להאשים אף אחד מהם ויש לי מבחן בקרוב.
נץב סליחה על הבלאגן שבקוד.
מהקוד שהצגת לא ניתן לדעת אם מדובר בהזרקת נתונים כי הקלט לא מוגדר (userID.text). עם זאת לא נראה שיש escape לתווים מיוחדים ולכן ההזרקה אפשרית
היי יואב,
הנתונים של משתמש וסיסמא מתקבלים דרך הasp.net בקובץ של דף aspx
Textbox id=userId text= הסיסמא שהקליד וכך גם ב- userName.
נ.ב
לא הבנתי מה זה הescape.
תודה,
אלעד
היי,
למה לא המשכת ללמד,
אך משתמשים:
order by…
ועוד חומר על הנושא
מפאת קוצר בזמן לצערי… אם ביכולתך להוסיף חומר בנושא, אשמח
תודה רבה, חיפשתי חומר מפורט בצורה כזו שלא מועתק אחד לאחד מ"wikipedia"
סוף סוף! מישהו שמבין עניין… תודה!