SQL Injection – הזרקת נתונים ב- SQL

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 ומזינה את התו \ לפניהם וכך נמנע השימוש בתווים כחלק מהשאילתה. השימוש בפונקציה זו מומלץ מאד בכל אפליקציה כדי לשמור על המידע הנמצא במסד הנתונים לפני הרצת השאילתה.