ABA


"איך מאבטחים ושומרים על אתר אינטרנט? |סיכום ל28/09/2009|"
גירסת הדפסה        
קבוצות דיון בניית אתרים נושא #15339 מנהל    סגן המנהל    מפקח   Winner    צל"ש   מומחה  
אשכול מספר 15339
asco88 
חבר מתאריך 17.6.04
26757 הודעות
   19:55   28.09.09   
אל הפורום  
  איך מאבטחים ושומרים על אתר אינטרנט? |סיכום ל28/09/2009|  
 
עבר עריכה לאחרונה בתאריך 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 כמה שהשפה מאפשרת, לדוגמא אם יש לנו מחלקה שאנחנו מעבירים אליה מערך, אז לא מספיק לעשות דבר כזה:


function a($arr)
{
}


זה תיכנות לא נכון פשוט.
הדרך הנכונה היא:

function a(array $arr)
{
}


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

classname $arg

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

$number = (int)$_GET;


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

עוד טיפ אממ, תשתדלו לבדוק את הטפסים שלכם גם ב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.
יש עוד הרבה אני אמשיך לכתוב.


שוב תודה רבה לכל הכותבים, אתם יותר ממוזמנים לכתוב לתרום לכולנו מידיעותיכם!
שנה טובה!


                                שתף        
מכתב זה והנלווה אליו, על אחריות ועל דעת הכותב בלבד

  האשכול     מחבר     תאריך כתיבה     מספר  
  יופי של אשכול! כל הכבוד. Sn00py  10.10.09 13:17 1
  באמת כל הכבוד! אשכול מושקע מאוד. דוקטור חייק  16.10.09 10:33 2
  בקשר למה שאייסקולד אמר, שמשון פישטונה 17.12.09 15:36 3
     לאחר בדיקה קצרה, שמשון פישטונה 18.12.09 14:58 4
  אין עליכם !! כבוד כבוד כבוד LoVe2KiLL 02.01.10 02:08 5
  יפה מאוד :) ronen333  12.03.10 17:14 6
  כל הכבוד על היוזמה אבל באמת שזה לא רציני. MoonHunter 19.03.10 23:39 7

       
Sn00py 
חבר מתאריך 1.8.02
2954 הודעות
   13:17   10.10.09   
אל הפורום  
  1. יופי של אשכול! כל הכבוד.  
בתגובה להודעה מספר 0
 
  

\x6C\x65\x65\x74\x68\x61\x78\x30
\x72\x3A\x2D\x29
tresp4sser


                                                         (ניהול: מחק תגובה)
מכתב זה והנלווה אליו, על אחריות ועל דעת הכותב בלבד
דוקטור חייק  לחץ כאן להצגת דירוג המשתמש
חבר מתאריך 14.12.06
40783 הודעות, 13 פידבק
   10:33   16.10.09   
אל הפורום  
  2. באמת כל הכבוד! אשכול מושקע מאוד.  
בתגובה להודעה מספר 0
 


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

   15:36   17.12.09   
אל הפורום  
  3. בקשר למה שאייסקולד אמר,  
בתגובה להודעה מספר 0
 
   אני לא שמעתי על זה שהmysql_real_escape מתחבר למסד נתונים, זה גם נשמע קצת תמוהה, כי אני לא מבין מה הצורך בלהתחבר למסד, זה סה"כ עושה סוג של מודיפיקציה למחרוזת שמכניסים למסד.

אבל במידה והוא צודק, אז תמיד אפשר להשתמש בaddslashes.

ד"א כרגע מי שמשתמש בmagic_quotes_gpc כדי למנוע את זה צריך לדעת שבגירסא 6 של PHP האופציה הזאת הוסרה, ואת ההגנה תצטרכו לבצע ידנית.

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


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

   14:58   18.12.09   
אל הפורום  
  4. לאחר בדיקה קצרה,  
בתגובה להודעה מספר 3
 
   mysql_real_escape_string לא מתחבר למסד נתונים, הוא דורש שיהיה חיבור קיים כבר.

אני חושב שזה משהו בסיסי שקיים כבר כשמתעסקים עם sql injection.


                                                         (ניהול: מחק תגובה)
מכתב זה והנלווה אליו, על אחריות ועל דעת הכותב בלבד
LoVe2KiLL
חבר מתאריך 6.7.04
13401 הודעות
   02:08   02.01.10   
אל הפורום  
  5. אין עליכם !! כבוד כבוד כבוד  
בתגובה להודעה מספר 0
 


                                                         (ניהול: מחק תגובה)
מכתב זה והנלווה אליו, על אחריות ועל דעת הכותב בלבד
ronen333 
חבר מתאריך 20.2.03
6069 הודעות
   17:14   12.03.10   
אל הפורום  
  6. יפה מאוד :)  
בתגובה להודעה מספר 0
 
  


                                                         (ניהול: מחק תגובה)
מכתב זה והנלווה אליו, על אחריות ועל דעת הכותב בלבד
MoonHunter
חבר מתאריך 1.8.02
680 הודעות
   23:39   19.03.10   
אל הפורום  
  7. כל הכבוד על היוזמה אבל באמת שזה לא רציני.  
בתגובה להודעה מספר 0
 
  


                                                         (ניהול: מחק תגובה)
מכתב זה והנלווה אליו, על אחריות ועל דעת הכותב בלבד

תגובה מהירה  למכתב מספר: 
 
___________________________________________________________________

___________________________________________________________________
למנהלים:  נעל | תייק בארכיון | מחק | העבר לפורום אחר | מחק תגובות | עגן אשכול
       



© כל הזכויות שמורות ל-רוטר.נט בע"מ rotter.net