Logo

רד-בורד: ארכיון

ראשי > אבטחת מידע > הגנה מפני SQL injection Attacks

08/12/2004 22:00:59 Cyber Knight
הגנה מפני SQL injection Attacks
מהו injection SQL ?
אם אתה מעצב אתר ברשת או שכבר יש לך אתר ברשת , בודאי יטרידו אותך התקפות אפשריות מצד משתמשים נוכלים. כמעט תמיד מפתחי האתרים מתמקדים בנושאי הביטחון כאשר הם בוחרים את מערכת ההפעלה ושרת ה- WEB עליהם ירוץ האתר, אך לא רק נושאים אלו צריכים לקחת בחשבון כאשר מגנים על האתר, הקוד הנפוץ המשמש לאתרי רשת מבוססי מידע מכיל בד"כ חורים אשר לא נופלים מחומרתם מהחורים אשר עלולים להתגלות בשרת ה- WEB.
ניצול לרעה של חור בקוד מעצב האתר נקרא SQL injection attack.

SQL injection היא טכניקה המאפשרת לתוקף להריץ פקודות SQL לא מורשות, ע"י ניצול נתוני קלט אשר תקינותם לא נבדקת ביישומי רשת הבונים שאילתות SQL דינאמיות.
להלן דוגמא נפוצה לכך:
טופס משמש לקליטת שם משתמש וסיסמה של מבקר באתר על מנת לאפשר גישה לדפי מידע מסוימים, הטופס מעביר את הנתונים שהתקבלו ל-ASP script לעיבוד הנתונים.
Script העיבוד בונה שאילתת SQL מהקלט על מנת להחליט אם שם המשתמש והסיסמה מתאימים ומאפשרים גישה למידע.

בתרחיש כזה, ניתן לבנות שני דפים , דף HTML להתחברות למערכת (login) ודף ASP אשר מבצע את וידוא אמיתות הנתונים (כלומר בדוגמא שלנו מחפש את שם המשתמש והסיסמה שהקיש במסד-הנתונים) .
קוד של שני דפים אלו יכול להראות כך:
Login.htm
קוד:
<form action="ExecLogin.asp" method="post">
Username: <input type="text" name="txtUsername"><br>
Password: <input type="password" name="txtPassword"><br>
<input type="submit">
</form>

ExecLogin.asp
קוד:
<%
Dim p_strUsername, p_strPassword, objRS, strSQL

p_strUsername = Request.Form("txtUsername")
p_strPassword = Request.Form("txtPassword")

strSQL = "SELECT * FROM tblUsers " & _
"WHERE Username=’" & p_strUsername & _
"’ and Password=’" & p_strPassword & "’"

Set objRS = Server.CreateObject("ADODB.Recordset")
objRS.Open strSQL, "DSN=..."

If (objRS.EOF) Then
Response.Write "Invalid login."
Else
Response.Write "You are logged in as " & objRS("Username")
End If

Set objRS = Nothing
%>

במבט ראשון , לא נראה שהקוד ב- ExecLogin.asp מכיל חורי אבטחה כלשהם. המשתמש אינו יכול להתחבר למערכת ללא שם משתמש וסיסמה מתאימים.
אולם, קוד זה אינו מוגן, והוא מתאים בדיוק ל- SQL injection attack.
למעשה הפגיעות של הקוד נובעת מכך ששאילתת ה- SQL נבנית ישירות מקלט המשתמש , דבר המאפשר לתוקף לקבוע את תוכן השאילתה שתבוצע.

דוגמא לפגיעות זו תהיה אם המשתמש יזין את המחרוזת הבאה לתוך שדה שם המשתמש\סיסמה : ’ or ’’=’ .
השאילתה שתבוצע תהיה אם כן :
SELECT * FROM tblUsers WHERE Username=’’ or ’’=’’ and Password = ’’ or ’’=’’

שאילתה זו תחזיר את כל הרשומות מהטבלה tblUsers וה- ASP script יחבר את התוקף למערכת בתור המשתמש אשר מופיע ברשומה הראשונה שבטבלה זו.

סוג נוסף של SQL injection stack מתקיים כאשר מקבלים מחרוזת כפרמטר המשמש להפקת דפי רשת דינאמיים.
להלן דוגמא לדף ASP אשר מקבל ID מהמחרוזת ומפיק באופן דינאמי את תוכן הדף בהתבסס על ה- ID.
קוד:
<%
Dim p_lngID, objRS, strSQL
p_lngID = Request("ID")

strSQL = "SELECT * FROM tblArticles WHERE ID=" & p_lngID

Set objRS = Server.CreateObject("ADODB.Recordset")
objRS.Open strSQL, "DSN=..."

If (Not objRS.EOF) Then Response.Write objRS("ArticleContent")

Set objRS = Nothing
%>

בנסיבות רגילות script זה היה מציג את תוכן הכתבה אשר ה- ID הועבר ע"י המחרוזת.
לדוגמא הדף יכול להיקרא:
http://www.example.com/article.asp?ID=1055 , ולכן יוצג התוכן של כתבה 1055.
כמו בדוגמא של ההתחברות למערכת שראינו לעיל , קוד זה חושף את עצמו ל – SQL injection attack, משתמש עוין יכול להחליף ID לא מזיק של כתבה בפקודת SQL מזיקה ע"י כך שישלח ל- ID מלל כמו : 0 or 1=1 , כלומר :
or 1=1 http://www.example.com/article.asp?ID=0.



שאילתת SQL זו תחזיר את כל הכתבות מהטבלה, מכיוון שהיא תראה כך:
קוד:
SELECT * FROM tblArticles WHERE ID=0 or 1=1

כמובן שדוגמא זו אינה נראית מסוכנת במיוחד, אבל התוקף יוכל אז לתמרן את היישום בצורה שתפגע בו באופן קטלני, ע"י החדרת פקודות הרסניות , כמו משפטי DELETE.
כל זה יכול להתבצע ע"י תמרון פשוט של המחרוזת המשמשת לשאילתה !
לדוגמא:
כל אחד יכול לקרוא לדף עם מחרוזת השאילתה הבאה:
http://www.exemple.com/Article.asp?ID=1055; DELETE FROM tblArticles

ההשלכות של SQL injection
ההשלכות המלאות של SQL injection תלויות בסביבה ובתצורה שבה עובדים.
לדוגמא, אם הקישור למסד הנתונים מתבצע בהרשאות של DBO (Data Base Operator) ניתן יהיה לבצע פעולות רבות במסד הנתונים, כגון: מחיקת כל הטבלאות במסד-הנתונים , יצירת טבלאות חדשות וכו’.
אם הקישור למסד-הנתונים הוא במושגים של SA (System Administrator), ניתן יהיה לשלוט בכל שרת ה-SQL, דבר אשר יאפשר בתצורה המתאימה גם ליצור חשבונות משתמשים אשר יוכלו לשלוט בשרת ה- Windows אשר משמש כ- host למסד-הנתונים.

הגנת יישומים מפני SQL injection

הדבר הראשון אותו יש לעשותה הוא להגן על שאילתות ה- SQL ע"י מימוש טכניקות "ניקוי" לכל הקלט אשר מתקבל מכל- object ASP request (Request, Request.QueryString, Request.Form, Request.Cookies ו- Request.ServerVariables).
טכניקות ה"ניקוי" מגוונות, ותלויות ב- DBMS (Data Base Management System) בו משתמשים, טכניקות לדוגמא ל- MS SQL Server יוצגו בהמשך.
בדוגמא של מסך הכניסה למערכת (login Page) ה- ASP script ציפה ששני משתנים (txtUserName ו- txtPassword) מסוג מחרוזת יועברו אליו, כשגרש יחיד ( ’ ) משולב במחרוזת , הוא מאפשר למשתמש לשלוט בפקודה שמתבצעת. כדי להתגבר על איום SQL injection מסוג זה, נמנע הופעת גרש יחיד במחרוזת הקלט ע"י שימוש בפונקצית Replace כך:
p_strUsername = Replace(Request.Form("txtUsername"), "’", "’’")
p_strPassword = Replace(Request.Form("txtPassword"), "’", "’’")
כלומר נחליף כל גרש יחיד בזוג גרשיים (למעשה הייצוג הטקסטואלי של גרש יחיד ב- SQL נכתב כשני גרשיים, כמו שבשפת C כדי לכתוב "\" במחרוזת, נרשום "\\").


בדוגמא השנייה שראינו , ה- script ציפה למשתנה (ID) מסוג מספר גדול (Long) , פקודת SQL לא מורשית יכולה להתבצע ע"י שרשור קוד SQL לפרמטר ה- ID . כדי להתגבר על איום מסוג זה , פשוט נגביל את הקלט לסוג מספר גדול ע"י שימוש ב- CLng כך:
p_lngID = CLng(Request("ID"))
אם המשתמש ינסה להעביר מחרוזת כפרמטר , פונקצית CLng תגרום לתקלה.

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

לבסוף, בכדי להגביל את טווח הפגיעה של SQL injection attack, יש להגביל את ההרשאות לחשבון מסד הנתונים בו משתמש יישום ה- Web. היישום בד"כ אינו צריך הרשאות DBA או SA.
ככל שניתנות פחות הרשאות למסד הנתונים הסיכון לפגיעה בנתונים קטן משמעותית.
מומלץ ליצור חשבונות נפרדים לכל רכיב ביישום המתקשר למסד-הנתונים בכדי לבודד את המפגעים האפשריים. לדוגמא, ממשק התצוגה של אתר ברשת דורש הגבלות רבות (המתבטאות בהרשאות נמוכות) יותר בגישה למסד-הנתונים מאשר מערכת פנימית לניהול תכני האתר.
08/12/2004 23:44:34 BoyBear
כבר מצאו ששיטות של עריכת הנתונים שמקבלים מהלקוח הם לא שיטות יעילות וטובות להגנה נגד SQL injection.

לדוגמא: אפשר ע"י עריכת ה string להציף את השרת sql או להכניס תמיד אשר מחליפים את ה ’ לדוגמא chr(%25) .

הפתרון הכי יעיל כיום כנגד SQL injection זה ליצור Procedure שבו אתה מגדיר את אורך הערך שמתקבל,סוג הערך וכו’...
08/12/2004 23:55:51 -Hawk-
לפי מה שאני שמעתי יש מלא מלא דרכים לניצול SQL INJECTION ולא רק בלוגין
אם בא לך להראות עוד מקומות לדוגמא
אני ישמח
09/12/2004 00:00:00 cp77fk4r
הוקי, אין קשר.. בלוגין (מבוססת SQL) משתמשים בשאילתת SQL בדיוק כמו בכל מקום אחר, ואפשר לנצל את הפרצות האלה בכל מקום שקיימת שאילתת SQL שלא מאובטחת מספיק.

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

נכון, זה קצת יותר עבודה, וזה משגע תשכל- אבל אין מה לעשות.
09/12/2004 00:22:33 BoyBear
CP זה כל הקטע שב Procedure זה לא בעיה לעשות את זה פשוט כותבים לו את סוג הערך שצריך לקבל,מספר המקסימלי של התווים בערך שצריך לקבל,והתווים שמותרים בערך וזהו...זה כמו לכתוב שאילתת SQL רגילה פשוט המתכנתים לא רגילים לזה
09/12/2004 01:10:19 HLL
F000000000000000000000000D
תביאו לי חומר להזריייייייייייק עכשיווווווו

איזה טופיק כיפי ..

אגב בקשר לתגובה של CP
זה לא כזה בעייה כל מה שצריך לדאוג זה שעל מספרים יהיה INTVAL
ועל שדות טקסט יהיה addshaslehs
(או איך שלא רושמים את זה )
(הכוונה כמובן ל PHP אבל אפשר ליישם את זה כמובן גם בכל שפת צד שרת אחרת)
09/12/2004 03:31:45 cp77fk4r
לאו דווקא צד שרת, אפשר להשתמש בSQL גם מVB, וגם מאוד הרבה מאוד שפות תיכנות.

וחח, "עוד חומר להזריק" ;)

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

ושוב, Cyber Knight, יפה ששמת פה טקסט, כל הכבוד, אבל גם פה, תשים קרדיט למחבר הטקסט, ואם המחבר הוא אתה- תשים את הקרדיט לך, לא טוב שיסתובבו פה טקסטים ללא מחבר, זה רק גורם לבעיות...[ההודעה נערכה על-ידי cp77fk4r ב-09/12/2004 14:58:30]
09/12/2004 14:57:49 cp77fk4r
אגב, אני חושב שיש כאן טעות קטנה-

נכתב בתחילת הטקסט
"ניצול לרעה של חור בקוד מעצב האתר נקרא SQL injection attack."

אני לא יודע למה הכותב מתכוון "בקוד מעצב האתר"- אבל אם אמורים להבין את זה כמו שאני חושב שאני מבין את זה, צריך היה לכתןב
"ניצול לרעה של חור בקוד הטופס מידע שמבוסס שאילתות SQL דינאמיות, נקרא SQL Inj"...[ההודעה נערכה על-ידי cp77fk4r ב-09/12/2004 14:58:21]
15/12/2004 23:02:33 Exodus
this was my absolute php answer for sql,xss threats
קוד:
function bugtraq()
{
func_get_args();
$v=func_get_arg(0);
$ptrn=array(
chr(60),
chr(62),
chr(39),
chr(34),
chr(59));
for($n=0;$n!=sizeof($ptrn);$n++)
{
if(preg_match("/$ptrn[$n]/",$v))
{
return 1; # eeww go away you creep...
}
}
return 0; # alright u can pass...
}



[ההודעה נערכה על-ידי Exodus ב-15/12/2004 23:06:11][ההודעה נערכה על-ידי Exodus ב-15/12/2004 23:51:31]
16/12/2004 00:51:51 cp77fk4r
יפה אקסי, הרבה משתמשים בזה, אבל הכי טוב זה שגם השאילתות עצמן (כשמדובר בSql) עצמן- ולא רק הטופס יהיו מוגנים, ככה אפשר לישון בשקט.
16/12/2004 14:36:47 Exodus
with this function you can filter any
input
עמודים: 1