סייבר ופיתוח ווב מאובטח
מתחילים ובני נוער

SQL Injection לנוער: כשהקלט הופך בטעות לפקודה

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

עודכן: יולי 2026
כ-6 דקות קריאה
SQL Injection והגנה על קלט
נתיחת באג

החיפוש ביקש פריט; הקוד בנה פקודה חדשה

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

const query =
  "SELECT name, price FROM items " +
  "WHERE name = '" + search + "'";

db.prepare(query).all();

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

SQL Injection היא משפחה של תקלות שבהן קלט לא מהימן משנה את המבנה או המשמעות של שאילתה.

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

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

מסלול הנתונים

ארבע תחנות בין תיבת החיפוש לתוצאה

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

  1. 01

    הדפדפן אוסף קלט

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

  2. 02

    השרת מקבל בקשה

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

  3. 03

    מסד הנתונים מפרש שאילתה

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

  4. 04

    התוצאה חוזרת דרך השרת

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

התיקון: המבנה והערך נוסעים בשני מסלולים

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

const query =
  "SELECT name, price FROM items " +
  "WHERE name = ?";

db.prepare(query).all(search);
  1. 1

    הפקודה קבועה

    מילות SQL, שמות טבלאות ומבנה התנאים נכתבים מראש בקוד שהמפתח שולט בו.

  2. 2

    הערך עובר בנפרד

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

  3. 3

    מסד הנתונים יודע מהו מה

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

אימות קלט ופרמטרים אינם אותה בדיקה

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

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

1
האם הערך תקין למוצר?
שם פריט יכול להיות טקסט באורך מוגבל; כמות צריכה להיות מספר בטווח הגיוני. זו בדיקת צורה וכלל עסקי.
2
האם המשתמש רשאי לבצע את הפעולה?
גם מזהה מספרי תקין אינו נותן רשות לצפות בהזמנה של משתמש אחר. זו בדיקת זהות והרשאה.
3
האם הערך מופרד מהפקודה?
גם ערך שנראה תקין צריך להיקשר כפרמטר. זו ההגנה שמונעת ממנו לשנות את תחביר ה-SQL.
הגנה בשכבות

אין כפתור קסם אחד לאבטחת מסד נתונים

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

שאילתות עם פרמטרים

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

הרשאות מצומצמות למסד

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

טיפול בטוח בשגיאות

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

בדיקת הרשאות לכל פעולה

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

מעבדת 30 דקות, בלי לגעת באתר אמיתי

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

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

    בונים מאגר צעצוע

    יוצרים מקומית טבלת items עם שלושה שמות ומחירים בדויים. לא משתמשים בנתוני אנשים, בסיסמאות או באתר אמיתי.

  2. ב

    מתעדים התנהגות רגילה

    מחפשים red potion, ערך שלא קיים ומחרוזת עם גרש. רושמים מה היישום החזיר ומה הופיע ביומן השרת.

  3. ג

    מחליפים חיבור בפרמטר

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

  4. ד

    מסבירים את ההבדל

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

בדיקת הבנה

שלושה תיקונים להסברים שנשמעים משכנעים

״נמחק גרשיים מהקלט וזה מספיק״

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

״הטופס נמצא מאחורי כפתור, לכן אי אפשר לשנות את הבקשה״

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

״ORM פותר אוטומטית כל SQL Injection״

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

המשימה הבאה: ציירו את גבול האמון

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