2. מי? מה? מתי?
אבטחה ב- ,webוב- PHPבמיוחד, היא נושא טעון •
מצד אחד, ה- webמכיל הרבה מאוד מידע, שחלק גדול ממנו הוא
רגיש / אישי / בעל ערך )כזה שמשתלם לגנוב אותו(
מצד שני, ה- webהוא סוג של ”מערב פרוע“ שבו אין חוקים והכל
יכול לקרות
PHP היא אחת השפות הפופולריות ביותר ב- ,webבייחוד אצל
מתכנתים מתחילים שפחות מודעים לסכנות
רוב האפליקציות שנכתבות ב- PHPהם תוכנה חופשית. לכן, קל יותר
לאתר פרצות אבטחה
בעבר, היו מספר נסיונות )לא מאוד מוצלחים( לפתור בעיות אבטחה
ברמת השפה
8002 ,91 | J an PHPואבטחה 2 |
4. מה זה אבטחה ובשביל מה זה טוב?
בשביל לפתור בעיות אבטחה, חשוב קודם כל להבין מה זה •
בדיוק ”בעיות אבטחה“:
אובדן פוטנציאלי של מידע רגיש
אובדן פוטנציאלי של שעות עבודה
אובדן פוטנציאלי של uptime
== אובדן פוטנציאלי של רווח
אבטחה היא אוסף של אמצעים שעלינו לנקות ע“מ למנוע •
או לצמצם אובדן פוטנציאלי של רווח
8002 ,91 | J an PHPואבטחה 4 |
5. גישה נכונה לאבטחת אפליקציות ווב
אפליקציה לעולם לא תהיה מאובטחת ב-%001 •
וגם אם כן, זו תהיה טעות קונספטואלית לחשוב ככה...
גישת עומק – נקיטה של מספר אמצעים חופפים כדי להשיג •
אבטחה טובה יותר
מודעות למה שאנחנו לא מודעים אליו •
היכולת לתקן פרצות אבטחה עתידיות יותר חשובה מקוד %001
מאובטח
• == ארכיטקטורה יותר חשובה מאבטחה!
8002 ,91 | J an PHPואבטחה 5 |
6. לעולם אסור לבטוח במידע חיצוני!
אבל מה זה בדיוק מידע חיצוני? •
GET, POST, COOKIE
FILES, SERVER
,ENVבסיס נתונים, קבצים על הדיסק
“אם יש ספק – אין ספק!“
מה עושים עם מידע חיצוני? •
סינון – ,filteringבדיקת תקינות - validation
• רשימה לבנה – – whitelistingלדוגמה HTML Tagsמותרים
• רשימה שחורה – – blacklistingלדוגמה מילים אסורות בפורום
חילוּף - התאמה לפורמט נדרש - escaping
8002 ,91 | J an PHPואבטחה 6 |
8. display_errors
בפיתוח: On •
קוד נקי לחלוטין משגיאות
הודעות NOTICEמעידות לעיתים קרובות על ”חורי
אבטחה“ )לדוגמה: הודעות על משתנים לא מאותחלים(
בזמן ריצה: Off •
מניעה של זליגת מידע פנימי אל המבקרים באתר
זה לא נראה טוב ;-(
8002 ,91 | J an PHPואבטחה 8 |
9. register_globals
כאשר פועל, PHPירשום משתנים ב- global scopeבאופן •
אוטומטי לכל משתנה GET, POST, COOKIEוכו'.
לא נמצא בשימוש רב בשנים האחרונות )מכובה כברירת •
מחדל מאז 2.4( אבל עדיין אפשר למצוא אפליקציות
ש“סומכות“ על .register_globals
פותח פרצות אבטחה פוטניאליות רבות – מאפשר ”הזרקה“ •
של משתנים לתוך ה- global namespace
אם חייבים להתשמש – חובה לאתחל את כל המשתנים
)(! E_NOTICE
הרגל רע גם מסיבות אחרות: •
קוד לא נייד )(portable
Deprecated ב- 0.6 PHP
8002 ,91 | J an PHPואבטחה 9 |
10. magic_quotes_gpc
אם מופעל, PHPיוסיף לוכסן ) (backslashלפני כל גרש )'(, •
גרשיים )”(, לוכסן אחורי )( ו- nullשנכנסים ב- GET, POST
ו- .COOKIE
“פיצ'ר“ שהיה אמור למנוע SQL Injectionsברמת השפה •
בפועל, מספק פתרון חלקי ביותר •
אין תמיכה בקידודים שונים
אין תמיכה בכל בסיסי הנתונים השונים
תמיד עדיף להשתמש בפונקציית escapingייעודית
יש עוד סיבות לכבות חוץ מאבטחה •
רע מבחינת ביצועים
לא פורטבילי, ייבוטל ב- 0.6 PHP
בקיצור, לא להתבסס על magic_quotes_gpc •
8002 ,91 | J an PHPואבטחה 01 |
11. *_allow_url
allow_url_fopen •
מאפשרת פתיחה של קבצים מרוחקים בעזרת ה- stream wrappers
הנתמכים )בד"כ HTTP, FTP, SSHוכו'( בפונקציות התומכות בכך
) ,fopen, file_get_contentsועוד רבות(.
פועל כברירת מחדל, כדאי בהחלט לכבות אם לא צריך
allow_url_include •
מאפשרת הרצה של קוד PHPמרוחק דרך stream wrappers
קיים מאז 2.5 PHP
כבוי כברירת מחדל
Code injection waiting to happen
איזה סיבה לעזאזל יש למישהו להפעיל דבר כזה?!?!
8002 ,91 | J an PHPואבטחה 11 |
18. SQL Injection
הזרקה של קוד לקלט מתוך ידיעה שהקלט יישלך לבסיס •
הנתונים ויפורש שם כקוד SQL
יכול להוות בסיס לפעילויות שונות, לדוגמה: •
עקיפה של סיסמאות ושינוי הרשאות
שינוי נתונים
השחתה של בסיס הנתונים )(DOS
מחיקה של בסיס הנתונים )(DOS
בעיה נפוצה מאוד – הרבה מאוד אפליקציות ווב מעבירות •
קלט מהמשתמש אל בסיס הנתונים
8002 ,91 | J an PHPואבטחה 81 |
19. – דוגמהSQL Injection
ללא חילוף / בדיקהSQL -שליחה של מידע חיצוני כחלק מ •
$username = $_POST['username'];
$password = $_POST['password'];
$sql = "SELECT 1 FROM users " .
"WHERE user = '$username' AND password = MD5('$password')";
$res = mysql_query($sql);
:ניתן להכניס את הקלט הבא ע“מ לנצל את הפרצה •
: עקיפה של מנגנון הסיסמה
username=' OR '' = '
password=') OR MD5('') = MD5('
, שינוי נתוניםDOS , ניתן לבצע גם השחתה של בסיס הנתונים
.וסיסמאות ועוד
| J an 19, 2008 ואבטחהPHP | 19
20. SQL Injection
:כמו כל התקפות ההזרקה, קל מאוד למנוע בעזרת חילוף •
ייעודיות של בסיס הנתוניםescaping פונקציות
mysql_real_escape_string •
pg_escape_string •
'• וכו
Casting to integer / float
PDO-<quote()
! לא טוב מספיקaddslashes()
Prepared Statements •
PDO, MySQLi
בהרבה מקרים עדיף גם מבחינת ביצועים
| J an 19, 2008 ואבטחהPHP | 20
21. – קוד תקיןSQL Injection
mysql – חילוף •
$con = mysql_connect('....');
$username = mysql_real_escape_string($_POST['username']);
$password = mysql_real_escape_string($_POST['password']);
$sql = "SELECT 1 FROM users " .
"WHERE user = '$username' AND password = MD5('$password')";
$res = mysql_query($sql);
PDO – חילוף •
$pdo = new PDO("mysql:dbname=mydb", 'user', 'password');
$username = $pdo->quote($_POST['username']);
$password = $pdo->quote($_POST['password']);
| J an 19, 2008 ואבטחהPHP | 21
22. – קוד תקיןSQL Injection
Integer -המרה ל •
$user_id = (int) $_GET['user_id'];
$sql = "SELECT * FROM users WHERE id = $user_id";
Prepared statement - PDO •
$pdo = new PDO("mysql:dbname=mydb", 'user', 'password');
$stmt = $pdo->prepare(
"SELECT 1 FROM users " .
"WHERE user = :username AND password = MD5(:password)"
);
$result = $stmt->execute(array(
'username' => $username,
'password' => $password)
);
| J an 19, 2008 ואבטחהPHP | 22
23. Shell Command Injection
הזרקה של קוד אל "מערכת ההפעלה" תוך ניצול של •
פקודות PHPשמריצות פקודות מערכת
אופרטור (``) backtick
משפחת )(exec
לא נפוץ מאוד – אבל חשוב מאוד להיזהר כאשר מכניסים •
פרמטרים לתוך פקודות אלו, מפני שהסכנות גדולות מאוד
8002 ,91 | J an PHPואבטחה 32 |
24. - דוגמהShell Injection
שימוש במידע חיצוני בפקודות מערכת •
// Get a listing of a public directory
$folder = $_GET['path'];
echo '<pre>';
passthru("ls -l /ftp/public/$folder");
echo '</pre>';
:ניתן להכניס את הקלט הבא ע“מ לנצל את הפרצה •
: מחיקה של כל הקבצים שיש לשרת גישה אליהם
path=foo; rm -rf /
:Denial of Service
path=foo; sleep 315360000
...בעיקרון ניתן להריץ כמעט כל פקודת מערכת
| J an 19, 2008 ואבטחהPHP | 24
25. Shell Command Injection
כמו כל התקפות ההזרקה, קל מאוד למנוע בעזרת פונקציות •
חילוף ייעודיות:
escapeshellarg()
escapeshellcmd()
ההבדל ביניהם – השניה לא מחליפה רווחים
אם מכניסים קלט מהמשתמש לתוך פקודות מערכת, כדאי •
מאוד להשתמש ב- whitelist filteringובווידוא שהקלט
תקין
8002 ,91 | J an PHPואבטחה 52 |
28. PHP Code Injection
הזרקה של קוד PHPלתוך התוכנית •
פונקציות שצריך לשים אליהם לב: •
קריאות ל- includeאו requireעם שם קובץ משתנה
• רגיש בעיקר כש- allow_url_include=On
eval()
preg_replace() עם /e
create_function()
כאשר משתמשים בפונקציות אלו עם משתנים מבחוץ, חשוב מאוד
לבצע validationו- white-list filtering
8002 ,91 | J an PHPואבטחה 82 |
29. - PHP Code Injectionדוגמה
קריאת קבצים ע“י ניצול include •
;]'$tpl = $_GET['template
;include 'templates/' . $tpl
ניתן להכניס את הקלט הבא ע“מ לנצל את הפרצה: •
קבלת רשימה של כל המשתמשים במערכת ההפעלה:
template=../../../../../../../../etc/passwd
אם allow_url_includeמופעל, קוד זה מאפשר •
הרצה של קוד PHPשרירותי על השרת
8002 ,91 | J an PHPואבטחה 92 |
30. – קוד תקיןPHP Code Injection
:המנעות ע“י סינון לפי רשימה לבנה •
$templates = array(
'blue' => 'templates/blue.phtml',
'aqua' => 'templates/aqua.phtml',
'ugly' => 'templates/ugly.phtml'
);
$tpl = (isset($templates[$_GET['template']]) ?
$templates[$_GET['template']] : 'templates/blue.phtml');
include $tpl;
באופן כללי רצוי להנע לחלוטין משימוש במידע חיצוני כחלק •
' וכוinclude, eval מפקודות כמו
| J an 19, 2008 ואבטחהPHP | 30
31. סיכום – התקפות הזרקה
התקפות הזרקה הם כנראה הנפוצות ביותר ב- web •
החדשות הטובות: יחסית קל לאתר ולפתור אותן
כל התקפות ההזרקה דומות באופיין, וגם באופן הטיפול בהן •
"דע מאין בא ה- dataולאן הוא הולך“ •
האם אפשר לבטוח במקור הנתונים?
מה הפורמט הבטוח שבו אפשר להשתמש בנתונים?
טיפול בהתקפות הזרקה ע“י סינון קלט טוב רק במקרים •
מסוימים
בד“כ חילוף ) (output escapingעדיף
8002 ,91 | J an PHPואבטחה 13 |