הזרקת SQL

מתוך ויקיפדיה, האנציקלופדיה החופשית
קפיצה אל: ניווט, חיפוש

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

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

דוגמה לפרצה[עריכת קוד מקור | עריכה]

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

SQL = "SELECT * FROM users WHERE password='" & Request("password") & "'"


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

SQL = "SELECT * FROM users WHERE password='1234'"

ובהנחה שאין בטבלת users רשומה שבה העמודה password מכילה את הערך '1234', לא נוכל לקבל גישה.

אך על ידי הזרקת SQL יכול משתמש זדוני להכניס את הקלט הבא:

' OR 'a'='a

שייצר את שאילתת ה-SQL הבאה:

SQL = "SELECT * FROM users WHERE password='' OR 'a'='a'"

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

פתרון[עריכת קוד מקור | עריכה]

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

בדיקת תקינות הקלט[עריכת קוד מקור | עריכה]

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

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

שימוש במבנה קשיח יותר של שאילתא[עריכת קוד מקור | עריכה]

שפות התכנות השונות מציעות פתרון עדיף לבעיה, על ידי כך שהמתכנת יכול להכין שאילתא מובנית ולשים "שומרי מקום" (placeholder) במקומות שאליהן יוכנס אחר כך הנתון הנקלט מהמשתמש. לדוגמה במקום קטע הקוד הבא, הכתוב בשפת JAVA:

 
 Connection con = (acquire Connection)
 Statement stmt = con.createStatement();
 ResultSet rset = stmt.executeQuery("SELECT * FROM users WHERE name = '" + userName + "';");

ניתן לכתוב כך:

 
 Connection con = (acquire Connection)
 PreparedStatement pstmt = con.prepareStatement("SELECT * FROM users WHERE name = ?");
 pstmt.setString(1, userName);
 ResultSet rset = pstmt.executeQuery();

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

קישורים חיצוניים[עריכת קוד מקור | עריכה]