התמודדות עם תווים מיוחדים ב PHP
בתכנות ישנם תווים מיוחדים כדוגמת גרש גרשיים שיכולים לגרום לנו בעיות בתכנות
להלן הרשימה של התווים המיוחדים והמקבילים שלהם: ( רוב הבעיות שלנו זה עם הגרש והגרשיים )
- & => &
- " => "
- ' => '
- < => <
- > => >
כאשר מקבלים תו מיוחד בקלט וצריך להכניס אותו לשאילתא או שמשתמשים במחרוזת עם תו מיוחד בשליחת GET עלולות להיווצר לנו בעיות של דף שקורס או אפילו בעיות אבטחה אני אנסה לעזור לכם להתמודד עם תווים מיוחדים ולהבין מה הבעיות בפוסט הזה
עלול גם להיווצר לנו גם בעיה במסד נתונים אם לא בחרנו קידוד מתאים utf8_general_ci ואז התווים המיוחדים לא נכנסים למסד כמו שצריך.
נתחיל לפרט את הבעיות ואת הפתרונות כמובן שלכל דבר יש יותר מפתרון אחד.
מניעת הכנסת קוד HTML או JS בקלט של משתמש
כדי למנוע ממשתמש להכניס קוד HTML לאתר שלנו כשאנחנו אנחנו משתמשים בפונקציה htmlspecialchars פונקציה מובנית ב PHP שהופכת תווים מיוחדים לתווים מקבילים
$str = "<b>exmple<b>"; echo htmlspecialchars($str); ------------------------------------- result ------------- <b>exmple</b>
הפונקציה הופכת את התווים המיוחדים למקבילים שלהם כמו בטבלה למעלה.
וכך משתמש שינסה להכניס באחד השדות שניתן למלא קלט שהוא קוד יקבל אוסף של שטויות, כמובן שיש עוד פתרונות כמו לחסום בוולידציה אפשרות של הכנסת קלט כזה וכו…
קבלת מחרוזת ב GET שמכילה גרש כתו מיוחד
כאשר אנחנו מקבלים בשליחת נתונים GET \ POST מחרוזת שמכילה תו מיוחד יתווסף אליו סלאש במידה ואנחנו רוצים להציג אותו במסך כמו שקיבלנו אנחנו צריכים להוריד את הסלאש ישנה פונקציה מובנית ב PHP שמורידה סלאשים
stripslashes($str)
ישנה גם פונקציה שמוסיפה אני מקווה שאני אספיק לדבר על זה בהמשך כי גם היא חשובה מאוד בנושא הזה
addslashes($str);
שאילתא שיש בה תווים מיוחדים
שאילתא שאנחנו מצפים לתו גרש או גרשיים ( או אפילו ליתר ביטחון) טוב להשים לה סלאשים כדי שהשאילתא לא תיפול וגם כדי שלא יהיו פריצות למסד נתונים הפונקציה
addslashes
פותרת את הבעיה יש פונקציות גם שלכל גרש שמים 2 לתחום אותו וככמו שאמרתי יש מלא פתרונות בכל ארגון בדרך כלל יש כללים ומסמכים ברורים לאיך להתמודד עם בעיות אבטחה מהסוג הזה שנקראות .sql injection
הכנסת מחרוזת עם תו גרש או גרשיים לתוך משתנה
כאשר אני רוצה להכניס מחרוזת מסויימת לתוך משתנה והיא מכילה תו גרש או גרשיים ואני תוחם את המחרוזת עם גרש או גרשיים אז אני מקבל שגיאה דוגמא :
$test = 'jos'l';
אני אקבל שגיאה ישנם כמה פתרונות כמו תמיד לבעיה אחד הפתרונות לתרום את המחרוזת עם גרשיים במקום עם גרש
פתרון שני להשים סלאש לפני גרש כך:
$test = 'jos\'ll'
הזכרנו קידוד בהתחלה אז ככה ב ie ואפילו בגרסה 9 שלו עדיין תומכים ב utf7 ואז ניתן לבצע פריצת xxs אפילו אם משתמשים בפונקציה
htmlspecialchars הפתרון הוא להכריח שימוש ב utf-8 כמו בדוגמא הבאה
<?php $_GET['password'] = 'asdf&ddddd"fancy˝quotes˝'; echo htmlspecialchars($_GET['password'], ENT_COMPAT | ENT_HTML401, 'UTF-8') . "\n"; // Output: asdf&ddddd"fancyË echo htmlentities($_GET['password'], ENT_COMPAT | ENT_HTML401, 'UTF-8') . "\n"; // Output: asdf&ddddd"fancyËquotes
וראיתי עוד פתרון להצהיר בכותרת של הדף שמשתמשים ב utf-8
header('Content-Type: text/html; charset=utf-8');
הזרקת SQL
אחת הפריצות הכי בעייתיות הן פריצות מסוג sql injection
אדגים את הבעיה ואראה פתרון
$pass= $_GET['pass']; $query = "SELECT * FROM some_tbl WHERE pass = '$pass' "; ------------------------------------------------------ $pass = "1234' OR 1=1 -- "; $query = "SELECT * FROM some_tbl WHERE pass = '$pass' ";
כפי שאנחנו רואים בקוד במקום להכניס סיסמה הפורץ מכניס קוד ( שאגב אפשר למנוע ממנו גם להכניס את התווים האלה מלכתכילה) והקוד הזה גורם לו תמיד לקבל את הנתונים מהטבלה.
הפתרון הכי טוב ומה שראיתי שהכי הרבה מציעים הוא להשתמש ב mySQLi ( לשימוש ב sql) או ב PDO (לשימוש בבסיס נתונים אחר)
דוגמא :
$stmt = $dbConnection->prepare('SELECT * FROM some_tbl WHERE name = ?');
$stmt->bind_param('s', $name);
$stmt->execute();
$result = $stmt->get_result();
while ($row = $result->fetch_assoc()) {
// do something with $row
}