עבר עריכה לאחרונה בתאריך 07.03.11 בשעה 19:55:21 על-ידי Ice Cold (מנהל הפורום)
קיבצתי את כל הרעיונות שלכם, להודעה אחת מסודרת, אתם מוזמנים להמשיך ולהוסיף. orzilca כתב:
לעשות וידוא input
כל מידע שמשתמש יכול להכניס באתר
או כל משתנה שאפשר לשנות בכתובת (לדוגמא: index.php?p=main)
צריך לוודא שהוא באמת מה שהוא אמור ליהיות (מספר, טקסט וכו')
ולהוסיף לו גם mysql_real_escape_string.. (זה בשביל למנוע sql injection)ו Ice Cold הוסיף:
mysql_real_escape_string לא ממש מומלץ...
ידעת שהוא מתחבר ל-DATABASE בשביל זה? זה בזבוז משאבים... יש לי קלאס דיי בסיסי שאני משתמש בו (גם כן של orzilca )
בגדול זה קלאס שאין בו תועלת מיוחדת
כל מה שהוא עושה זה להשתלט על הדיווח שגיאות של ה-PHP ולהציג את השגיאות בצורה קצת יותר מסודרת
ומאפשר לכבות את הדיווח ארורים עם משתנה
אלה המשתנים הקבועים של המחלקה
define("ERROR_REPORTING", true); define("ERROR_REPORTING_OFF_MSG", "אירעה שגיאה, איתכם הסליחה."); define("ERROR_CSS","background: #e5c0c0; border-color: #000; border: 1px solid; width: 600px; height: auto; margin: auto; padding: 2px; direction: ltr; text-align: left; clear: both; font: normal 90%/1.5em 'Trebuchet MS',Tahoma, sans-serif;");
|
וזאת המחלקה..
class error { private static $debugLevel; #initialize error handling function __construct() { self::$debugLevel = ERROR_REPORTING; // Error reporting level error_reporting (E_ALL); // Take over from PHP error & exception handling set_error_handler(array($this, 'error_handler')); set_exception_handler(array($this, 'error_handler')); } //--__construct #prints Error function error_handler($error_level, $error_message, $file, $line) { switch ($error_level) { case E_NOTICE: case E_USER_NOTICE: $error_type = 'Notice'; break; case E_WARNING: case E_USER_WARNING: $error_type = 'Warning'; break; case E_ERROR: case E_USER_ERROR: $error_type = 'Fatal Error'; $EXIT = TRUE; break; default: $error_type = 'Unknown'; $EXIT = TRUE; break; } if (self::$debugLevel) { echo "<p style='".ERROR_CSS."'>"; echo "<b>$error_type: </b>$error_message<br/>"; echo "<b>File: </b>$file<br/>"; echo "<b>Line: </b>$line<br />"; echo "</p>"; //exit; //stop program } else { echo "<p style='".ERROR_CSS."'>".ERROR_REPORTING_OFF_MSG."</p>"; //exit; //stop program }
} //-- errorHandler() end. #manualy print error public static function trigger ( $error_string ) { trigger_error( $error_string ); } //-- trigger() end. #deinitialize public static function deinitialize() { self::$debugLevel = null; restore_error_handler(); restore_exception_handler(); } //-- DeInitialize() end. }
|
CaTz כתב:
פונקציה שמעיפה כל שדה HTML
כדי למנוע XSS, פשוט מאוד strip_tags
עושה עבודה מעולה!
כמובן כאשר אני מוציא מידע מהבסיס נתונים אני מעביר את המשתנה דרך פונקציית
htmlentities
כדי להמיר תווים מיוחדים לערך הHTMLי שליהם...
Sql injection אני מונע עם mysql_real_escape_string
כמו כן כל שאילתה שאני כותב עוטפת את המשתנה שאני מקבל מהמשתמש עם גרש משני הצדדים. כך זה מחייב את המזריק להשתמש עם גרש כדי לצאת מהמסגרת אבל הפונקציה של הreal_escape שמה מבריח גרש לפני כל גרש וככה נמנעת ההזרקה.
כמו כן כל שגיאה שמוצגת למשתמש אני מעיף עם error_reporting(0)
בראש העמוד, אבל אני בכל מקרה שומר לוגים לכל שגיאה שנוצרת גם כזו שנוצרת בmysql את זה אני עושה עם פונקציה שקימבנתי הנה משהו כזה:function userErrorHandler($errno, $errmsg, $filename, $linenum) { define("SQLErr",1986); // timestamp for the error entry. $dt = date('H:i:s d-m-Y (T)'); // define an assoc array of error string // in reality the only entries we should // consider are E_WARNING, E_NOTICE, E_USER_ERROR, // E_USER_WARNING and E_USER_NOTICE. $errortype = array ( E_ERROR => 'Error', E_WARNING => 'Warning', E_PARSE => 'Parsing Error', E_NOTICE => 'Notice', E_CORE_ERROR => 'Core Error', E_CORE_WARNING => 'Core Warning', E_COMPILE_ERROR => 'Compile Error', E_COMPILE_WARNING => 'Compile Warning', E_USER_ERROR => 'User Error', E_USER_WARNING => 'User Warning', E_USER_NOTICE => 'User Notice', E_STRICT => 'Runtime Notice', SQLErr => 'SQL Error' ); // set of errors for which a var trace will be saved. $user_errors = array(E_USER_ERROR, E_USER_WARNING, E_WARNING, SQLErr); if (in_array($errno, $user_errors)) { $err = "<errorentry>\n"; $err .= "\t<datetime>" .$dt. "</datetime>\n"; $err .= "\t<errornum>" .$errno. "</errornum>\n"; $err .= "\t<errortype>" .$errortype. "</errortype>\n"; $err .= "\t<errormsg>" .$errmsg. "</errormsg>\n"; $err .= "\t<scriptname>" .$filename. "</scriptname>\n"; $err .= "\t<scriptlinenum>" .$linenum. "</scriptlinenum>\n"; $err .= "\t<userip>" .$_SERVER. "</userip>\n"; $err .= "</errorentry>\n\n"; // save to the error log file, and e-mail me if there is a critical user error. error_log($err, 3, '../error_log.log'); if ($errno == E_USER_ERROR) { mail('[email protected]', 'Critical User Error', $err); } } } //Get sql function exe_query($string, $debug=0) { global $user_id; if ($debug == 1) { print $string; } $result = mysql_query($string); if ($result == false) { if($user_id==1) echo mysql_error(); //$debug = debug_backtrace(); userErrorHandler('1986', mysql_error()."\n\tQuery: $string", $_SERVER, $debug); } return $result; }
|
הפונקציה הראשונה מטפלת בשמירת השגיאות
ככה אני קורא לה
$old_error_handler = set_error_handler('userErrorHandler');
והפונקציה השנייה מאפשרת לי לעשות Debug קל יותר (סימון 1 במשתנה)
וגם שומרת לי שגיאות מהmysql.
מקווה שעזרתי. akoka כתב:
מומלץ לשמור בPHP על Type safety כמה שהשפה מאפשרת, לדוגמא אם יש לנו מחלקה שאנחנו מעבירים אליה מערך, אז לא מספיק לעשות דבר כזה:
זה תיכנות לא נכון פשוט.
הדרך הנכונה היא:
השיטה הזאת עובדת גם לגבי מחלקות, אם אנחנו רוצים להעביר לפונקציה טיפוס מסויים ממחלקה כול מה שצריך לעשות זה בארגומנט לכתוב
classname $arg
הקשר לאבטחה הוא די ישיר, אם אנחנו מעבירים משתנה בGET ורוצים לדאוג שלא יכניסו לנו שם תווים מיותרים אז יש דרך נחמדה לגרום לזה שהמשתנה יוכל לקבל רק int.
ככה שהבדיקות היחידות שאנחנו צריכים לעשות הם נומריות, ואין צורך לסנן תווים מיוחדים.
עוד טיפ אממ, תשתדלו לבדוק את הטפסים שלכם גם בJS וגם בPHP. MoonHunter כתב:
PHP Input Filter- Filter out unwanted PHP/JS/HTML Tags
חובה להשתמש בכל מה שקשור לפלט:
http://www.phpclasses.org/browse/package/2189.html
lior066 כתב:
גדול אז כמה דברים שלמדתי עם השנים:
א. בחיים לא להישען על ואלידציה דרך הקליינט, בחיים ( דיי ברור ), תמיד לבצע ואלידציה חוזרת בשרת, כמה שזה מעצבן לכתוב קוד שהוא כמעט כפול אבל למען התקינות והאבטחה יש לעשות את זה.
ב. לחסום גישה למקומות שאמורות להיות חסומים, כמה שזה מפתיע המון אנשים לא חוסמים את הגישה אלא מראים רק דף שגיאות , ברגע שה"פורץ" לכאורה יודע על קוץ מסויים במערכת בתיקיה מסויימת שלא מוגנת, הוא ינצל אותה ( אני עושה את זה מידי פעם לאתרים לשלוף מהם קצת מידע, נהייתי האקר לא קטן )ג. חלוקת רמות אבטחה וקבוצות אבטחה.
ב ASP.NET יש משהו נורא חמוד שאני דיי אוהב שנקרא ROLES שזה תפקידים,
עכשיו בעיקרון אני יכול לחסום תיקיה לכניסה נגיד ADMIN ואם הלקוח לא יהיה מחובר בתור ה ROLE המסויים הוא לא יכול אפילו לדעת שהיא קיימת, אני יכול לעשות העברה של כל התיקיות שמנסות בחזרה לאינדקס, ככה שאם פורץ מסויים ינסה למצוא דף LOGIN ל ADMIN הוא לא יכול, מה שיפה שבכניסה רגילה המערכת יכולה לזהות אם אתה שייך לאותה קבוצת משתמשים ולתת לך גישה לתיקיה, כל זה בלי קודים מסויימים, בלי בדיקות, בלי כלום, אשף אחד פשוט שמאבטח את כל התיקה.
ד. לבדוק הראשאות, לבדוק הרשאות, לבדוק הרשאות! , לפני כל פעולה שאתם עושים, אם צריך הרשאות לזה לבדוק הרשאות !!!! לפני !!!! שנכנסים בכלל לפונקציה. תמיד להחזיר RETURN אם אין הרשאות.
ה. שימוש בפרוצדורות עדיפה של שימוש בשאילתות , פרוצדורות מאובטחות מבחינת SQL ( לפחות ב SQLSERVER ) אז עדיף להשתמש איתם איפה שאפשר, אני בעיקרון משתמש ב LINQ אז אני לא אמור לחשוש בנוגע ל SQLINJECTION כי ההגנה כבר מוטבעת, בכל אופן כמו שנאמר, לתת לכל משתנה סוג כלשהו, כדי לוודות באמת שזה הסוג הנכון שלא ינסו לעשות INJECTION לאיזה משהו בגלל שהטיפוס לא נכון, לפחות להפיל אותם בטיפוס.
ו.הודעות מפחידות לזיהוי ניסיונות פריצה, כידוע אולי 90 אחוז מהניסיונות פריצה הם דרך ילדודס קטנים ש"מנסים" דברים על האתר שלכם.
אם זיהתם ניסיון פריצה כמו במחרוזת חיפוש כלשהיא מצאתם "SELECT * " או דברים כאלה ( עדיף לעטוף את הפונקציה פעם אחת ולהשתמש בה ) להראות הודעה מפחיד כמו ( ה IP שלך נשמר במערכת של האתר, המערכת זיהתה ניסיון פריצה למערכת, הודעה אוטומטית נשלחה לספקית האינטרנט שלך הממקמת אותך באתר בשעה XYZ עם מחרוזות החיפוש הלא חוקיות בניסיון פריצה ).
ז.להגדיל את ההגנה לסיסמאות, אני יודע שזה יכול להיות מעצבן, אבל אתם לא תאמינו איזה קל זה לפרוץ חשבונות שהם עם אותו שם וסיסמא! זה פשוט מאוד.
לתת הרחבה של הסיסמא נגיד למינימום 6 ספרות + אות אחד. משהו בסיגנון ( אם זה חשוב לכם, הסבירות לאבד פה לקוחות היא ריאליסטית לגמרי אני לדוגמא שוכח סיסמאות שהם לא הברירת מחדל שלי, ומשתדל שלא להירשם לדברים כאלה, אבל זה השיקולים שלכם...)
ח.טוב, אז לא מזמן פרצתי לאיזה אתר דיי מוכר, לא אתן את שמו ונכנסתי למסד נתונים שלו , ולמרבה הפתעתי.. הסיסמאות לא מוצפנות!
חברה מספיק שהאתר שלכם סובל מחוסר אבטחה אין פה שום צורך לדפוק גם את המשתמשים שנרשמו אליכם!!!
יש לי טיפ טוב פה , ממש ממש טוב!
תצפינו ב MD5! ! ! ! !
אז ככה, כשאתם רושמים אנשים לאתר , תוסיפו למחרוזת של הסיסמא 5 תווים קבועים שישארו לכם בקוד נגיד !#&&^ עכשיו במידה שהפריצה היא רק ל DB הפורץ יקבל מאגר של סיסמאות בהצפנה, באותו הרגע הוא ילך לאתרים של RAINBOW ( אתרים שמפצחים סיסמאות של MD5 ) אבל הוא לא יצליח לפרוץ אפילו לא סיסמא אחת! כי היא מוגנת בעוד 5 תווים שהם WILDCARD ככה שההגנה על הסיסמא היא הכי מקסימלית שיכולה להיות ( לא לשכוח להוסיף את זה במחרוזת ה LOGIN שלכם, כדי לשרשר את זה לסיסמא של הלקוח )
ט. לא להראות USERID בשום מקום, ואם כן, לנסות לקבוע USERID לא כמספר
ב SQLSERVER יש מה שנקרא UniqIdentifer מה שנותן GUID שזה מחרוזת של אם אני לא טועה 15 תווים מבוססים על זמן וכל מיני דברים כאלה, מה שזה נותן לכם הוא היכולת להימנע מסריקה של לקוחות או ניסיון לפרוץ דרך ID כלשהו.
י.לא לחשוף גישה ל ADMIN דרך האתר הרגיל , לשמור אותו במועדפים או משהו.
טוב זהו לבינתיים כואבת לי היד!
DerExploizer כתב:
קווים כלליים:
1. תמיד לשדרג את גירסת ההפעלה של הסרבר.
2. תמיד לשדרג את גירסת השרתmysql, postgresql, mssql
3. לבטל הרשאות שלא צריך בשרת.
4. תמיד לשדרג את גירסת הphp או asp
5. תמיד להיות מעודכן עם גירסת הphpmyadmin אם קיימת.
6. לעולם לא ליצור תיקיות בשרת בשם admin, Admin, ADMIN וכו'
7. לעולם לא ליצור דפים בשרת בשם admin.php, admin.asp, Admin.php וכו'
8. תמיד לבדוק פרמטרים של get בצד השרת ולא רק בצד הלקוח עם ג'אווה סקריפט!
שאין במקרה תווים כמו: ",:/.\' וכו' שבוודאי יגרמו לsql injection.
יש עוד הרבה אני אמשיך לכתוב.
שוב תודה רבה לכל הכותבים, אתם יותר ממוזמנים לכתוב לתרום לכולנו מידיעותיכם!
שנה טובה!
