您的位置:首页 > 编程语言 > PHP开发

FaceBook源代码泄漏(预防PHP源代码泄漏的方法)

2007-08-13 05:09 417 查看

FaceBook源代码泄漏

TechCrunch的消息称,FaceBook源代码遭到泄漏,并且已经被发布到名叫 Facebook Secrets 博客。一般而言,源代码泄漏发生存在两种情况:其一是内部源代码开发者泄漏,另外一种就是利用程序的漏洞从而获取源代码。
登录该博客我们可以看到只是简单的几行代码,虽然不十分确定这就是FaceBook的源代码,然而让人担心的是成千上万用户的私人资料是否也安全呢?这对于Facebook来说无疑是致命的一击!

下面是该博客站点贴出的FaceBook首页源代码。


1. include_once $_SERVER['PHP_ROOT'].'/html/init.php';


2. include_once $_SERVER['PHP_ROOT'].'/lib/home.php';


3. include_once $_SERVER['PHP_ROOT'].'/lib/requests.php';


4. include_once $_SERVER['PHP_ROOT'].'/lib/feed/newsfeed.php';


5. include_once $_SERVER['PHP_ROOT'].'/lib/poke.php';


6. include_once $_SERVER['PHP_ROOT'].'/lib/share.php';


7. include_once $_SERVER['PHP_ROOT'].'/lib/orientation.php';


8. include_once $_SERVER['PHP_ROOT'].'/lib/feed/newsfeed.php';


9. include_once $_SERVER['PHP_ROOT'].'/lib/mobile/register.php';


10. include_once $_SERVER['PHP_ROOT'].'/lib/forms_lib.php';


11. include_once $_SERVER['PHP_ROOT'].'/lib/contact_importer/contact_importer.php';


12. include_once $_SERVER['PHP_ROOT'].'/lib/feed/util.php';


13. include_once $_SERVER['PHP_ROOT'].'/lib/hiding_prefs.php';


14. include_once $_SERVER['PHP_ROOT'].'/lib/abtesting.php';


15. include_once $_SERVER['PHP_ROOT'].'/lib/friends.php';


16. include_once $_SERVER['PHP_ROOT'].'/lib/statusupdates.php';


17.


18. // lib/display/feed.php has to be declared here for scope issues.


19. // This keeps display/feed.php cleaner and easier to understand.


20. include_once $_SERVER['PHP_ROOT'].'/lib/display/feed.php';


21. include_once $_SERVER['PHP_ROOT'].'/lib/monetization_box.php';


22.


23. // require login


24. $user = require_login();


25. print_time('require_login');


26. param_request(array( 'react' => $PARAM_EXISTS));


27.


28. // Check and fix broken emails


29. // LN - disabling due to excessive can_see dirties and sets when enabled.


30. //check_and_fix_broken_emails($user);


31.


32. // migrate AIM screenname from profile to screenname table if needed


33. migrate_screenname ($user);


34.


35. // homepage announcement variables


36. $HIDE_ANNOUNCEMENT_BIT = get_site_variable('HIDE_ANNOUNCEMENT_BIT');


37. $HIDE_INTRO_BITMASK = get_site_variable('HIDE_INTRO_BITMASK');


38.


39. // redirects


40. if (is_sponsor_user()) {


41. redirect('bizhome.php', 'www');


42. }


43.


44. include_once $_SERVER['PHP_ROOT'].'/lib/mesg.php';


45. include_once $_SERVER['PHP_ROOT'].'/lib/invitetool.php';


46. include_once $_SERVER['PHP_ROOT'].'/lib/grammar.php';


47. include_once $_SERVER['PHP_ROOT'].'/lib/securityq.php';


48. include_once $_SERVER['PHP_ROOT'].'/lib/events.php';


49. include_once $_SERVER['PHP_ROOT'].'/lib/rooster/stories.php';


50.


51. // todo: password confirmation redirects here (from html/reset.php),


52. // do we want a confirmation message?


53.


54. param_get_slashed(array(


55. 'feeduser' => $PARAM_INT, //debug: gets feed for user here


56. 'err' => $PARAM_STRING, // returning from a failed entry on an orientation form


57. 'error' => $PARAM_STRING, // an error can also be here because the profile photo upload code is crazy


58. 'ret' => $PARAM_INT,


59. 'success' => $PARAM_INT, // successful profile picture upload


60. 'jn' => $PARAM_INT, // joined a network for orientation


61. 'np' => $PARAM_INT, // network pending (for work/address network)


62. 'me' => $PARAM_STRING, // mobile error


63. 'mr' => $PARAM_EXISTS, // force mobile reg view


64. 'mobile' => $PARAM_EXISTS, // mobile confirmation code sent


65. 'jif' => $PARAM_EXISTS, // just imported friends


66. 'ied' => $PARAM_STRING, // import email domain


67. 'o' => $PARAM_EXISTS, // first time orientation, passed on confirm


68. 'verified' => $PARAM_EXISTS)); // verified mobile phone


69.


70. param_post(array(


71. 'leave_orientation' => $PARAM_EXISTS,


72. 'show_orientation' => $PARAM_INT, // show an orientation step


73. 'hide_orientation' => $PARAM_INT)); // skip an orientation step


74.


75. // homepage actions


76. if ($req_react && validate_expiring_hash($req_react, $GLOBALS['url_md5key'])) {


77. $show_reactivated_message = true;


78. } else {


79. $show_reactivated_message = false;


80. }


81. tpl_set('show_reactivated_message', $show_reactivated_message);


82.


83.


84. // upcoming events


85. events_check_future_events($user); // make sure big tunas haven't moved around


86. $upcoming_events = events_get_imminent_for_user($user);


87.


88. // this is all stuff that can be fetched together!


89. $upcoming_events_short = array();


90. obj_multiget_short(array_keys($upcoming_events), true, $upcoming_events_short);


91. $new_pokes = 0;


92. //only get the next N pokes for display


93. //where N is set in the dbget to avoid caching issues


94. $poke_stats = get_num_pokes($user);


95. get_next_pokes($user, true, $new_pokes);


96. $poke_count = $poke_stats['unseen'];


97.


98. $targeted_data = array();


99. home_get_cache_targeted_data($user, true, $targeted_data);


100. $announcement_data = array();


101. home_get_cache_announcement_data($user, true, $announcement_data);


102. $orientation = 0;


103. orientation_get_status($user, true, $orientation);


104. $short_profile = array();


105. profile_get_short($user, true, $short_profile);


106. // pure priming stuff


107. privacy_get_network_settings($user, true);


108. $presence = array();


109. mobile_get_presence_data($user, true, $presence);


110. feedback_get_event_weights($user, true);


111. // Determine if we want to display the feed intro message


112. $intro_settings = 0;


113. user_get_hide_intro_bitmask($user, true, $intro_settings);


114. $user_friend_finder = true;


115. contact_importer_get_used_friend_finder($user, true, $used_friend_finder);


116. $all_requests = requests_get_cache_data($user);


117. // FIXME?: is it sub-optimal to call this both in requests_get_cache_data and here?


118. $friends_status = statusupdates_get_recent($user, null, 3);


119. memcache_dispatch(); // populate cache data


120.


121. // Merman's Admin profile always links to the Merman's home


122. if (user_has_obj_attached($user)) {


123. redirect('mhome.php', 'www');


124. }


125.


126. if (is_array($upcoming_events)) {


127. foreach ($upcoming_events as $event_id => $data) {


128. $upcoming_events[$event_id]['name'] = txt_set($upcoming_events_short[$event_id]['name']);


129. }


130. }


131.


132. tpl_set('upcoming_events' , $upcoming_events);


133.


134. // disabled account actions


135. $disabled_warning = ((IS_DEV_SITE || IS_QA_SITE) && is_disabled_user($user));


136. tpl_set('disabled_warning', $disabled_warning);


137.


138. // new pokes (no more messages here, they are in the top nav!)


139. if (!user_is_guest($user)) {


140. tpl_set('poke_count' , $poke_count);


141. tpl_set('pokes' , $new_pokes);


142. }


143.


144. // get announcement computations


145. tpl_set('targeted_data' , $targeted_data);


146. tpl_set('announcement_data' , $announcement_data);


147.


148.


149. // birthday notifications


150. tpl_set('birthdays' , $birthdays = user_get_birthday_notifications($user, $short_profile));


151. tpl_set('show_birthdays' , $show_birthdays = (count($birthdays) || !$orientation));


152.


153. // user info


154. tpl_set('first_name' , user_get_first_name(txt_set($short_profile['id'])));


155. tpl_set('user' , $user);


156.


157. // decide if there are now any requests to show


158. $show_requests = false;


159. foreach ($all_requests as $request_category) {


160. if ($request_category) {


161. $show_requests = true;


162. break;


163. }


164. }


165. tpl_set('all_requests', $show_requests ? $all_requests : null);


166.


167. $permissions = privacy_get_reduced_network_permissions($user, $user);


168.


169. // status


170. $user_info = array('user' => $user,


171. 'firstname' => user_get_first_name($user),


172. 'see_all' => '/statusupdates/?ref=hp',


173. 'profile_pic' => make_profile_image_src_direct($user, 'thumb'),


174. 'square_pic' => make_profile_image_src_direct($user, 'square'));


175.


176. if (!empty($presence) && $presence['status_time'] > (time() - 60*60*24*7)) {


177. $status = array('message' => txt_set($presence['status']),


178. 'time' => $presence['status_time'],


179. 'source' => $presence['status_source']);


180. } else {


181. $status = array('message' => null, 'time' => null, 'source' => null);


182. }


183. tpl_set('user_info', $user_info);


184.


185. tpl_set('show_status', $show_status = !$orientation);


186. tpl_set('status', $status);


187. tpl_set('status_custom', $status_custom = mobile_get_status_custom($user));


188. tpl_set('friends_status', $friends_status);


189.


190. // orientation


191. if ($orientation) {


192. if ($post_leave_orientation) {


193. orientation_update_status($user, $orientation, 2);


194. notification_notify_exit_orientation($user);


195. dirty_user($user);


196. redirect('home.php');


197. } else if (orientation_eligible_exit(array('uid'=>$user)) == 2) {


198. orientation_update_status($user, $orientation, 1);


199. notification_notify_exit_orientation($user);


200. dirty_user($user);


201. redirect('home.php');


202. }


203. }


204.


205. // timezone - outside of stealth, update user's timezone if necessary


206. $set_time = !user_is_alpha($user, 'stealth');


207. tpl_set('timezone_autoset', $set_time );


208. if ($set_time) {


209. $daylight_savings = get_site_variable('DAYLIGHT_SAVINGS_ON');


210. tpl_set('timezone', $short_profile['timezone'] - ($daylight_savings ? 4 : 5) );


211. }


212.


213. // set next step if we can


214. if (!$orientation) {


215. user_set_next_step($user, $short_profile);


216. }


217.


218. // note: don't make this an else with the above statement, because then no news feed stories will be fetched if they're exiting orientation


219. if ($orientation) {


220. extract(orientation_get_const());


221.


222. require_js('js/dynamic_dialog.js');


223. require_js('js/suggest.js');


224. require_js('js/typeahead_ns.js');


225. require_js('js/suggest.js');


226. require_js('js/editregion.js');


227. require_js('js/orientation.js');


228. require_css('css/typeahead.css');


229. require_css('css/editor.css');


230.


231. if ($post_hide_orientation && $post_hide_orientation <= $ORIENTATION_MAX) {


232. $orientation['orientation_bitmask'] |= ($post_hide_orientation * $ORIENTATION_SKIPPED_MODIFIER);


233. orientation_update_status($user, $orientation);


234. } else if ($post_show_orientation && $post_show_orientation <= $ORIENTATION_MAX) {


235. $orientation['orientation_bitmask'] &= ~($post_show_orientation * $ORIENTATION_SKIPPED_MODIFIER);


236. orientation_update_status($user, $orientation);


237. }


238.


239. $stories = orientation_get_stories($user, $orientation);


240. switch ($get_err) {


241. case $ORIENTATION_ERR_COLLEGE:


242. $temp = array(); // the affil_retval_msg needs some parameters won't be used


243. $stories[$ORIENTATION_NETWORK]['failed_college']=affil_retval_msg($get_ret, $temp, $temp);


244. break;


245. case $ORIENTATION_ERR_CORP:


246. $temp = array();


247. // We special case the network not recognized error here, because affil_retval_msg is retarded.


248. $stories[$ORIENTATION_NETWORK]['failed_corp'] = ($get_ret == 70) ? 'The email you entered did not match any of our supported networks. ' .


249. 'Click here to see our supported list. ' .


250. 'Go here to suggest your network for the future.'


251. : affil_retval_msg($get_ret, $temp, $temp);


252. break;


253. }


254.


255. // photo upload error


256. if ($get_error) {


257. $stories[$ORIENTATION_ORDER[$ORIENTATION_PROFILE]]['upload_error'] = pic_get_error_text($get_error);


258. }


259. // photo upload success


260. else if ($get_success == 1) {


261. $stories[$ORIENTATION_ORDER[$ORIENTATION_PROFILE]]['uploaded_pic'] = true;


262. // join network success


263. } else if ($get_jn) {


264. $stories[$ORIENTATION_ORDER[$ORIENTATION_NETWORK]]['joined'] = array(


265. 'id' => $get_jn,


266. 'name' => network_get_name($get_jn));


267. // network join pending


268. } else if ($get_np) {


269.


270. $stories[$ORIENTATION_ORDER[$ORIENTATION_NETWORK]]['join_pending'] = array(


271. 'id' => $get_np,


272. 'email' => get_affil_email_conf($user, $get_np),


273. 'network' => network_get_name($get_np));


274. // just imported friend confirmation


275. } else if ($get_jif) {


276. $stories[$ORIENTATION_ORDER[$ORIENTATION_NETWORK]]['just_imported_friends'] = true;


277. $stories[$ORIENTATION_ORDER[$ORIENTATION_NETWORK]]['domain'] = $get_ied;


278. }


279.


280. // Mobile web API params


281. if ($get_mobile) {


282. $stories[$ORIENTATION_ORDER[$ORIENTATION_MOBILE]]['sent_code'] = true;


283. $stories[$ORIENTATION_ORDER[$ORIENTATION_MOBILE]]['view'] = 'confirm';


284. }


285. if ($get_verified) {


286. $stories[$ORIENTATION_ORDER[$ORIENTATION_MOBILE]]['verified'] = true;


287. }


288. if ($get_me) {


289. $stories[$ORIENTATION_ORDER[$ORIENTATION_MOBILE]]['error'] = $get_me;


290. }


291. if ($get_mr) {


292. $stories[$ORIENTATION_ORDER[$ORIENTATION_MOBILE]]['view'] = 'register';


293. }


294.


295. if (orientation_eligible_exit($orientation)) {


296. tpl_set('orientation_show_exit', true);


297. }


298. tpl_set('orientation_stories', $stories);


299.


300. //if in orientation, we hide all feed intros (all 1's in bitmask)


301. $intro_settings = -1;


302.


303. }


304. tpl_set('orientation', $orientation);


305.


306. // Rooster Stories


307. if (!$orientation &&


308. ((get_site_variable('ROOSTER_ENABLED') == 2) ||


309. (get_site_variable('ROOSTER_DEV_ENABLED') == 2))) {


310. $rooster_story_count = get_site_variable('ROOSTER_STORY_COUNT');


311. if (!isset($rooster_story_count)) {


312. // Set default if something is wrong with the sitevar


313. $rooster_story_count = 2;


314. }


315. $rooster_stories = rooster_get_stories($user, $rooster_story_count, $log_omissions = true);


316. if (!emptyempty($rooster_stories) && !emptyempty($rooster_stories['stories'])) {


317. // Do page-view level logging here


318. foreach($rooster_stories['stories'] as $story) {


319. rooster_log_action($user, $story, ROOSTER_LOG_ACTION_VIEW);


320. }


321. tpl_set('rooster_stories', $rooster_stories);


322. }


323. }


324.


325. // set the variables for the home announcement code


326. $hide_announcement_tpl = ($intro_settings | $HIDE_INTRO_BITMASK) & $HIDE_ANNOUNCEMENT_BIT;


327. // if on qa/dev site, special rules


328. $HIDE_INTRO_ON_DEV = get_site_variable('HIDE_INTRO_ON_DEV');


329. if ((IS_QA_SITE || IS_DEV_SITE) && !$HIDE_INTRO_ON_DEV) {


330. $hide_announcement_tpl = 0;


331. }


332.


333. tpl_set('hide_announcement', $hide_announcement_tpl);


334. if($is_candidate = is_candidate_user($user)) {


335. tpl_set('hide_announcement', false);


336. }


337. $home_announcement_tpl = !$hide_announcement_tpl || $is_candidate ? home_get_announcement_info($user) : 0;


338. tpl_set('home_announcement', $home_announcement_tpl);


339. tpl_set('hide_announcement_bit', $HIDE_ANNOUNCEMENT_BIT);


340.


341. $show_friend_finder = !$orientation && contact_importer_enabled($user) && !user_get_hiding_pref($user, 'home_friend_finder');


342. tpl_set('show_friend_finder', $show_friend_finder);


343. if ($show_friend_finder && (user_get_friend_count($user) > 20)) {


344. tpl_set('friend_finder_hide_options', array('text'=>'close',


345. 'onclick'=>"return clearFriendFinder()"));


346. } else {


347. tpl_set('friend_finder_hide_options', null);


348. }


349.


350. $account_info = user_get_account_info($user);


351. $account_create_time = $account_info['time'];


352.


353. tpl_set('show_friend_finder_top',


354. !$used_friend_finder);


355.


356. tpl_set('user', $user);


357.


358.


359. // MONETIZATION BOX


360. $minimize_monetization_box = user_get_hiding_pref($user, 'home_monetization');


361. $show_monetization_box = (!$orientation &&


362. get_site_variable('HOMEPAGE_MONETIZATION_BOX'));


363. tpl_set('show_monetization_box', $show_monetization_box);


364. tpl_set('minimize_monetization_box', $minimize_monetization_box);


365.


366. if ($show_monetization_box) {


367. $monetization_box_data = monetization_box_user_get_data($user);


368. txt_set('monetization_box_data', $monetization_box_data);


369. }


370.


371.


372. // ORIENTATION


373. if ($orientation) {


374. $network_ids = id_get_networks($user);


375. $network_names = multiget_network_name($network_ids);


376. $in_corp_network = in_array($GLOBALS['TYPE_CORP'], array_map('extract_network_type', $network_ids));


377. $show_corp_search = $in_corp_network ||


378. get_age(user_get_basic_info_attr($user, 'birthday')) >= 21;


379. $pending_hs = is_hs_pending_user($user);


380. $hs_id = null;


381. $hs_name = null;


382. if ($pending_hs) {


383. foreach (id_get_pending_networks($user) as $network) {


384. if (extract_network_type($network['network_key']) == $GLOBALS['TYPE_HS']) {


385. $hs_id = $network['network_key'];


386. $hs_name = network_get_name($hs_id);


387. break;


388. }


389. }


390. }


391. //$orientation_people = orientation_get_friend_and_inviter_ids($user);


392. $orientation_people = array('friends' => user_get_all_friends($user),


393. 'pending' => array_keys(user_get_friend_requests($user)),


394. 'inviters'=> array(), // wc: don't show inviters for now


395. );


396. $orientation_info = array_merge($orientation_people,


397. array('network_names' => $network_names,


398. 'show_corp_search' => $show_corp_search,


399. 'pending_hs' => array('hs_id'=>$hs_id,


400. 'hs_name'=>$hs_name),


401. 'user' => $user,


402. ));


403. tpl_set('orientation_info', $orientation_info);


404.


405. tpl_set('simple_orientation_first_login', $get_o); // unused right now


406. }


407.


408.


409. // Roughly determine page length for ads


410. // first, try page length using right-hand panel


411. $ads_page_length_data = 3 + // 3 for profile pic + next step


412. ($show_friend_finder ? 1 : 0) +


413. ($show_status ? ($status_custom ? count($friends_status) : 0) : 0) +


414. ($show_monetization_box ? 1 : 0) +


415. ($show_birthdays ? count($birthdays) : 0) +


416. count($new_pokes);


417.


418. // page length using feed stories


419. if ($orientation) {


420. $ads_page_length_data = max($ads_page_length_data, count($stories) * 5);


421. }


422. tpl_set('ads_page_length_data', $ads_page_length_data);


423.


424. $feed_stories = null;


425. if (!$orientation) { // if they're not in orientation they get other cool stuff


426. // ad_insert: the ad type to try to insert for the user


427. // (0 if we don't want to try an insert)


428. $ad_insert = get_site_variable('FEED_ADS_ENABLE_INSERTS');


429.


430. $feed_off = false;


431.


432. if (check_super($user) && $get_feeduser){


433. $feed_stories = user_get_displayable_stories($get_feeduser, 0, null, $ad_insert);


434. } else if (can_see($user, $user, 'feed')) {


435. $feed_stories = user_get_displayable_stories($user, 0, null, $ad_insert);


436. } else {


437. $feed_off = true;


438. }


439.


440. // Friend's Feed Selector - Requires dev.php constant


441. if (is_friendfeed_user($user)) {


442. $friendfeed = array();


443. $friendfeed['feeduser'] = $get_feeduser;


444. $friendfeed['feeduser_name'] = user_get_name($get_feeduser);


445. $friendfeed['friends'] = user_get_all_friends($user);


446. tpl_set('friendfeed', $friendfeed);


447. }


448.


449. $feed_stories = feed_adjust_timezone($user, $feed_stories);


450.


451. tpl_set('feed_off', $feed_off ? redirect('privacy.php?view=feeds', null, false) : false);


452. }


453. tpl_set('feed_stories', $feed_stories);


454.


455. render_template($_SERVER['PHP_ROOT'].'/html/home.phpt');



--------------------------------------

上午从TC看到FaceBook源代码遭泄漏,刚才去看TC的该页面,已经做了两点更新,下面跟大家分享一下:其一是FaceBook的Brandee Barker在评论留言中解释了一下造成此事的原因,另一件就是该文章作者Nik Cubrilovic在自己的博客上给出了预防PHP源代码泄漏的方法。

先说说第一件:FB官方给出的解释是,少数用户利用某台服务器的配置错误将源码泄漏出来,并且现在已经修复了此错误,且声明这不是安全缺口所以对用 私人数据并不会造成影响。不管是服务器配置错误或者符合超载,看来造成此事的原因是apache和mod_php将未经解释的源代码直接输出。(原文)

Some of Facebook’s source code was exposed to a small number of users due to a bug on a single server that was misconfigured and then fixed immediately. It was not a security breach and did not compromise user data in any way. The reprinting of this code violates several laws and we ask that people not distribute it further.

第二件Nik在博客上写了四条预防PHP源代码泄漏的方法:

1)使用mod_security过滤输出严防泄漏 Use mod_security to filter output and prevent leakage (例如)


PHP代码




1. SecFilterOutput On


2. SecFilterSelective OUTPUT "<?php" log,deny





2)不要将关键敏感代码放到根目录中 Code should live outside of the web root (例如)


PHP代码




1. index.php:


2.


3. <?php


4. include('../realroot/index.php');


5. ?>





3)更改默认的文件类型 Change the default file type (例如对http.conf做如下修改)


PHP代码




1. httpd.conf:


2.


3. DefaultType application/x-httpd-php





4)绝对禁止访问根目录 Deny all outside of the webroot (假设你的根目录是 ‘www’ ,例如)


PHP代码




1. http.conf: (or .htaccess)


2.


3. <directory />


4. Order Deny,Allow


5. Deny from all


6. Options None


7. AllowOverride None


8.


9. <directory /www>


10. Order Allow,Deny


11. Allow from all


12. </directory>



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息