PageRenderTime 77ms CodeModel.GetById 40ms RepoModel.GetById 1ms app.codeStats 0ms

/xoops_trust_path/modules/protector/class/protector.php

https://github.com/nouphet/momoxo
PHP | 1123 lines | 823 code | 194 blank | 106 comment | 246 complexity | 16a861c1dcf521e846fe02afe2bcc8a0 MD5 | raw file
Possible License(s): AGPL-1.0, LGPL-2.1
  1. <?php
  2. class Protector {
  3. var $mydirname ;
  4. var $_conn = null ;
  5. var $_conf = array() ;
  6. var $_conf_serialized = '' ;
  7. var $_bad_globals = array() ;
  8. var $message = '' ;
  9. var $warning = false ;
  10. var $error = false ;
  11. var $_doubtful_requests = array() ;
  12. var $_bigumbrella_doubtfuls = array() ;
  13. var $_dblayertrap_doubtfuls = array() ;
  14. var $_dblayertrap_doubtful_needles = array(
  15. 'information_schema' ,
  16. 'select' ,
  17. "'" ,
  18. '"' ,
  19. ) ;
  20. var $_logged = false ;
  21. var $_done_badext = false ;
  22. var $_done_intval = false ;
  23. var $_done_dotdot = false ;
  24. var $_done_nullbyte = false ;
  25. var $_done_contami = false ;
  26. var $_done_isocom = false ;
  27. var $_done_union = false ;
  28. var $_done_dos = false ;
  29. var $_safe_badext = true ;
  30. var $_safe_contami = true ;
  31. var $_safe_isocom = true ;
  32. var $_safe_union = true ;
  33. var $_spamcount_uri = 0 ;
  34. var $_should_be_banned_time0 = false ;
  35. var $_should_be_banned = false ;
  36. var $_dos_stage = null ;
  37. var $ip_matched_info = null ;
  38. var $last_error_type = 'UNKNOWN' ;
  39. // Constructor
  40. function Protector()
  41. {
  42. $this->mydirname = 'protector' ;
  43. // Preferences from configs/cache
  44. $this->_conf_serialized = @file_get_contents( $this->get_filepath4confighcache() ) ;
  45. $this->_conf = @unserialize( $this->_conf_serialized ) ;
  46. if( empty( $this->_conf ) ) $this->_conf = array() ;
  47. if( ! empty( $this->_conf['global_disabled'] ) ) return true ;
  48. // die if PHP_SELF XSS found (disabled in 2.53)
  49. // if( preg_match( '/[<>\'";\n ]/' , @$_SERVER['PHP_SELF'] ) ) {
  50. // $this->message .= "Invalid PHP_SELF '{$_SERVER['PHP_SELF']}' found.\n" ;
  51. // $this->output_log( 'PHP_SELF XSS' ) ;
  52. // die( 'invalid PHP_SELF' ) ;
  53. // }
  54. // sanitize against PHP_SELF/PATH_INFO XSS (disabled in 3.33)
  55. // $_SERVER['PHP_SELF'] = strtr( @$_SERVER['PHP_SELF'] , array( '<' => '%3C' , '>' => '%3E' , "'" => '%27' , '"' => '%22' ) ) ;
  56. // if( ! empty( $_SERVER['PATH_INFO'] ) ) $_SERVER['PATH_INFO'] = strtr( @$_SERVER['PATH_INFO'] , array( '<' => '%3C' , '>' => '%3E' , "'" => '%27' , '"' => '%22' ) ) ;
  57. $this->_bad_globals = array( 'GLOBALS' , '_SESSION' , 'HTTP_SESSION_VARS' , '_GET' , 'HTTP_GET_VARS' , '_POST' , 'HTTP_POST_VARS' , '_COOKIE' , 'HTTP_COOKIE_VARS' , '_SERVER' , 'HTTP_SERVER_VARS' , '_REQUEST' , '_ENV' , '_FILES' , 'xoopsDB' , 'xoopsUser' , 'xoopsUserId' , 'xoopsUserGroups' , 'xoopsUserIsAdmin' , 'xoopsConfig' , 'xoopsOption' , 'xoopsModule' , 'xoopsModuleConfig' ) ;
  58. $this->_initial_recursive( $_GET , 'G' ) ;
  59. $this->_initial_recursive( $_POST , 'P' ) ;
  60. $this->_initial_recursive( $_COOKIE , 'C' ) ;
  61. }
  62. function _initial_recursive( $val , $key )
  63. {
  64. if( is_array( $val ) ) {
  65. foreach( $val as $subkey => $subval ) {
  66. // check bad globals
  67. if( in_array( $subkey , $this->_bad_globals , true ) ) {
  68. $this->message .= "Attempt to inject '$subkey' was found.\n" ;
  69. $this->_safe_contami = false ;
  70. $this->last_error_type = 'CONTAMI' ;
  71. }
  72. $this->_initial_recursive( $subval , $key . '_' . base64_encode( $subkey ) ) ;
  73. }
  74. } else {
  75. // check nullbyte attack
  76. if( @$this->_conf['san_nullbyte'] && strstr( $val , chr(0) ) ) {
  77. $val = str_replace( chr(0) , ' ' , $val ) ;
  78. $this->replace_doubtful( $key , $val ) ;
  79. $this->message .= "Injecting Null-byte '$val' found.\n" ;
  80. $this->output_log( 'NullByte' , 0 , false , 32 ) ;
  81. // $this->purge() ;
  82. }
  83. // register as doubtful requests against SQL Injections
  84. if( preg_match( '?[\s\'"`/]?' , $val ) ) {
  85. $this->_doubtful_requests["$key"] = $val ;
  86. }
  87. }
  88. }
  89. static function &getInstance()
  90. {
  91. static $instance ;
  92. if( ! isset( $instance ) ) {
  93. $instance = new Protector() ;
  94. }
  95. return $instance ;
  96. }
  97. function updateConfIntoDb( $name , $value )
  98. {
  99. $constpref = '_MI_' . strtoupper( $this->mydirname ) ;
  100. $db =& Database::getInstance() ;
  101. $db->queryF( "UPDATE `".$db->prefix("config")."` SET `conf_value`='".addslashes($value)."' WHERE `conf_title` like '".$constpref."%' AND `conf_name`='".addslashes($name)."' LIMIT 1" ) ;
  102. $this->updateConfFromDB() ;
  103. }
  104. function updateConfFromDb()
  105. {
  106. $constpref = '_MI_' . strtoupper( $this->mydirname ) ;
  107. if( empty( $this->_conn ) ) return false ;
  108. $result = @mysql_query( "SELECT `conf_name`,`conf_value` FROM `".XOOPS_DB_PREFIX."_config` WHERE `conf_title` like '".$constpref."%'" , $this->_conn ) ;
  109. if( ! $result || mysql_num_rows( $result ) < 5 ) {
  110. return false ;
  111. }
  112. $db_conf = array() ;
  113. while( list( $key , $val ) = mysql_fetch_row( $result ) ) {
  114. $db_conf[ $key ] = $val ;
  115. }
  116. $db_conf_serialized = serialize( $db_conf ) ;
  117. // update config cache
  118. if( $db_conf_serialized != $this->_conf_serialized ) {
  119. $fp = fopen( $this->get_filepath4confighcache() , 'w' ) ;
  120. fwrite( $fp , $db_conf_serialized ) ;
  121. fclose( $fp ) ;
  122. $this->_conf = $db_conf ;
  123. }
  124. return true ;
  125. }
  126. function setConn( $conn )
  127. {
  128. $this->_conn = $conn ;
  129. }
  130. function getConf()
  131. {
  132. return $this->_conf ;
  133. }
  134. function purge( $redirect_to_top = false )
  135. {
  136. // clear all session values
  137. if( isset( $_SESSION ) ) foreach( $_SESSION as $key => $val ) {
  138. $_SESSION[ $key ] = '' ;
  139. if( isset( $GLOBALS[ $key ] ) ) $GLOBALS[ $key ] = '' ;
  140. }
  141. if( ! headers_sent() ) {
  142. // clear typical session id of PHP
  143. setcookie( 'PHPSESSID' , '' , time() - 3600 , '/' , '' , 0 ) ;
  144. if( isset( $_COOKIE[ session_name() ] ) ) {
  145. setcookie( session_name() , '' , time() - 3600 , '/' , '' , 0 ) ;
  146. }
  147. // clear autologin cookie
  148. $xoops_cookie_path = defined('XOOPS_COOKIE_PATH') ? XOOPS_COOKIE_PATH : preg_replace( '?http://[^/]+(/.*)$?' , "$1" , XOOPS_URL ) ;
  149. if( $xoops_cookie_path == XOOPS_URL ) $xoops_cookie_path = '/' ;
  150. setcookie('autologin_uname', '', time() - 3600, $xoops_cookie_path, '', 0);
  151. setcookie('autologin_pass', '', time() - 3600, $xoops_cookie_path, '', 0);
  152. }
  153. if( $redirect_to_top ) {
  154. header( 'Location: '.XOOPS_URL.'/' ) ;
  155. exit ;
  156. } else {
  157. $ret = $this->call_filter( 'prepurge_exit' ) ;
  158. if( $ret == false ) {
  159. die( 'Protector detects attacking actions' ) ;
  160. }
  161. }
  162. }
  163. function output_log( $type = 'UNKNOWN' , $uid = 0 , $unique_check = false , $level = 1 )
  164. {
  165. if( $this->_logged ) return true ;
  166. if( ! ( $this->_conf['log_level'] & $level ) ) return true ;
  167. if( empty( $this->_conn ) ) {
  168. $this->_conn = @mysql_connect( XOOPS_DB_HOST , XOOPS_DB_USER , XOOPS_DB_PASS ) ;
  169. if( ! $this->_conn ) die( 'db connection failed.' ) ;
  170. if( ! mysql_select_db( XOOPS_DB_NAME , $this->_conn ) ) die( 'db selection failed.' ) ;
  171. }
  172. $ip = @$_SERVER['REMOTE_ADDR'] ;
  173. $agent = @$_SERVER['HTTP_USER_AGENT'] ;
  174. if( $unique_check ) {
  175. $result = mysql_query( 'SELECT ip,type FROM '.XOOPS_DB_PREFIX.'_'.$this->mydirname.'_log ORDER BY timestamp DESC LIMIT 1' , $this->_conn ) ;
  176. list( $last_ip , $last_type ) = mysql_fetch_row( $result ) ;
  177. if( $last_ip == $ip && $last_type == $type ) {
  178. $this->_logged = true ;
  179. return true ;
  180. }
  181. }
  182. mysql_query( "INSERT INTO ".XOOPS_DB_PREFIX."_".$this->mydirname."_log SET ip='".addslashes($ip)."',agent='".addslashes($agent)."',type='".addslashes($type)."',description='".addslashes($this->message)."',uid='".intval($uid)."',timestamp=NOW()" , $this->_conn ) ;
  183. $this->_logged = true ;
  184. return true ;
  185. }
  186. function write_file_bwlimit( $expire )
  187. {
  188. $expire = min( intval( $expire ) , time() + 300 ) ;
  189. $fp = @fopen( $this->get_filepath4bwlimit() , 'w' ) ;
  190. if( $fp ) {
  191. @flock( $fp , LOCK_EX ) ;
  192. fwrite( $fp , $expire . "\n" ) ;
  193. @flock( $fp , LOCK_UN ) ;
  194. fclose( $fp ) ;
  195. return true ;
  196. } else {
  197. return false ;
  198. }
  199. }
  200. function get_bwlimit()
  201. {
  202. list( $expire ) = @file( Protector::get_filepath4bwlimit() ) ;
  203. $expire = min( intval( $expire ) , time() + 300 ) ;
  204. return $expire ;
  205. }
  206. function get_filepath4bwlimit()
  207. {
  208. return XOOPS_TRUST_PATH . '/modules/protector/configs/bwlimit' . substr( md5( XOOPS_ROOT_PATH . XOOPS_DB_USER . XOOPS_DB_PREFIX ) , 0 , 6 ) ;
  209. }
  210. function write_file_badips( $bad_ips )
  211. {
  212. asort( $bad_ips ) ;
  213. $fp = @fopen( $this->get_filepath4badips() , 'w' ) ;
  214. if( $fp ) {
  215. @flock( $fp , LOCK_EX ) ;
  216. fwrite( $fp , serialize( $bad_ips ) . "\n" ) ;
  217. @flock( $fp , LOCK_UN ) ;
  218. fclose( $fp ) ;
  219. return true ;
  220. } else {
  221. return false ;
  222. }
  223. }
  224. function register_bad_ips( $jailed_time = 0 , $ip = null )
  225. {
  226. if( empty( $ip ) ) $ip = @$_SERVER['REMOTE_ADDR'] ;
  227. if( empty( $ip ) ) return false ;
  228. $bad_ips = $this->get_bad_ips( true ) ;
  229. $bad_ips[ $ip ] = $jailed_time ? $jailed_time : 0x7fffffff ;
  230. return $this->write_file_badips( $bad_ips ) ;
  231. }
  232. function get_bad_ips( $with_jailed_time = false )
  233. {
  234. list( $bad_ips_serialized ) = @file( Protector::get_filepath4badips() ) ;
  235. $bad_ips = empty( $bad_ips_serialized ) ? array() : @unserialize( $bad_ips_serialized ) ;
  236. if( ! is_array( $bad_ips ) || isset( $bad_ips[0] ) ) $bad_ips = array() ;
  237. // expire jailed_time
  238. $pos = 0 ;
  239. foreach( $bad_ips as $bad_ip => $jailed_time ) {
  240. if( $jailed_time >= time() ) break ;
  241. $pos ++ ;
  242. }
  243. $bad_ips = array_slice( $bad_ips , $pos ) ;
  244. if( $with_jailed_time ) {
  245. return $bad_ips ;
  246. } else {
  247. return array_keys( $bad_ips ) ;
  248. }
  249. }
  250. function get_filepath4badips()
  251. {
  252. return XOOPS_TRUST_PATH . '/modules/protector/configs/badips' . substr( md5( XOOPS_ROOT_PATH . XOOPS_DB_USER . XOOPS_DB_PREFIX ) , 0 , 6 ) ;
  253. }
  254. function get_group1_ips( $with_info = false )
  255. {
  256. list( $group1_ips_serialized ) = @file( Protector::get_filepath4group1ips() ) ;
  257. $group1_ips = empty( $group1_ips_serialized ) ? array() : @unserialize( $group1_ips_serialized ) ;
  258. if( ! is_array( $group1_ips ) ) $group1_ips = array() ;
  259. if( $with_info ) {
  260. $group1_ips = array_flip( $group1_ips ) ;
  261. }
  262. return $group1_ips ;
  263. }
  264. function get_filepath4group1ips()
  265. {
  266. return XOOPS_TRUST_PATH . '/modules/protector/configs/group1ips' . substr( md5( XOOPS_ROOT_PATH . XOOPS_DB_USER . XOOPS_DB_PREFIX ) , 0 , 6 ) ;
  267. }
  268. function get_filepath4confighcache()
  269. {
  270. return XOOPS_TRUST_PATH . '/modules/protector/configs/configcache' . substr( md5( XOOPS_ROOT_PATH . XOOPS_DB_USER . XOOPS_DB_PREFIX ) , 0 , 6 ) ;
  271. }
  272. function ip_match( $ips )
  273. {
  274. foreach( $ips as $ip => $info ) {
  275. if( $ip ) {
  276. switch( substr( $ip , -1 ) ) {
  277. case '.' :
  278. // foward match
  279. if( substr( @$_SERVER['REMOTE_ADDR'] , 0 , strlen( $ip ) ) == $ip ) {
  280. $this->ip_matched_info = $info ;
  281. return true ;
  282. }
  283. break ;
  284. case '0' :
  285. case '1' :
  286. case '2' :
  287. case '3' :
  288. case '4' :
  289. case '5' :
  290. case '6' :
  291. case '7' :
  292. case '8' :
  293. case '9' :
  294. // full match
  295. if( @$_SERVER['REMOTE_ADDR'] == $ip ) {
  296. $this->ip_matched_info = $info ;
  297. return true ;
  298. }
  299. break ;
  300. default :
  301. // perl regex
  302. if( @preg_match( $ip , @$_SERVER['REMOTE_ADDR'] ) ) {
  303. $this->ip_matched_info = $info ;
  304. return true ;
  305. }
  306. break ;
  307. }
  308. }
  309. }
  310. $this->ip_matched_info = null ;
  311. return false ;
  312. }
  313. function deny_by_htaccess( $ip = null )
  314. {
  315. if( empty( $ip ) ) $ip = @$_SERVER['REMOTE_ADDR'] ;
  316. if( empty( $ip ) ) return false ;
  317. if( ! function_exists( 'file_get_contents' ) ) return false ;
  318. $target_htaccess = XOOPS_ROOT_PATH.'/.htaccess' ;
  319. $backup_htaccess = XOOPS_ROOT_PATH.'/uploads/.htaccess.bak' ;
  320. $ht_body = file_get_contents( $target_htaccess ) ;
  321. // make backup as uploads/.htaccess.bak automatically
  322. if( $ht_body && ! file_exists( $backup_htaccess ) ) {
  323. $fw = fopen( $backup_htaccess , "w" ) ;
  324. fwrite( $fw , $ht_body ) ;
  325. fclose( $fw ) ;
  326. }
  327. // if .htaccess is broken, restore from backup
  328. if( ! $ht_body && file_exists( $backup_htaccess ) ) {
  329. $ht_body = file_get_contents( $backup_htaccess ) ;
  330. }
  331. // new .htaccess
  332. if( $ht_body === false ) {
  333. $ht_body = '' ;
  334. }
  335. if( preg_match( "/^(.*)#PROTECTOR#\s+(DENY FROM .*)\n#PROTECTOR#\n(.*)$/si" , $ht_body , $regs ) ) {
  336. if( substr( $regs[2] , - strlen( $ip ) ) == $ip ) return true ;
  337. $new_ht_body = $regs[1] . "#PROTECTOR#\n" . $regs[2] . " $ip\n#PROTECTOR#\n" . $regs[3] ;
  338. } else {
  339. $new_ht_body = "#PROTECTOR#\nDENY FROM $ip\n#PROTECTOR#\n" . $ht_body ;
  340. }
  341. // error_log( "$new_ht_body\n" , 3 , "/tmp/error_log" ) ;
  342. $fw = fopen( $target_htaccess , "w" ) ;
  343. @flock( $fw , LOCK_EX ) ;
  344. fwrite( $fw , $new_ht_body ) ;
  345. @flock( $fw , LOCK_UN ) ;
  346. fclose( $fw ) ;
  347. return true ;
  348. }
  349. function getDblayertrapDoubtfuls()
  350. {
  351. return $this->_dblayertrap_doubtfuls ;
  352. }
  353. function _dblayertrap_check_recursive( $val )
  354. {
  355. if( is_array( $val ) ) {
  356. foreach( $val as $subval ) {
  357. $this->_dblayertrap_check_recursive( $subval ) ;
  358. }
  359. } else {
  360. if( strlen( $val ) < 6 ) return ;
  361. $val = get_magic_quotes_gpc() ? stripslashes( $val ) : $val ;
  362. foreach( $this->_dblayertrap_doubtful_needles as $needle ) {
  363. if( stristr( $val , $needle ) ) {
  364. $this->_dblayertrap_doubtfuls[] = $val ;
  365. }
  366. }
  367. }
  368. }
  369. function dblayertrap_init( $force_override = false )
  370. {
  371. if( ! empty( $GLOBALS['xoopsOption']['nocommon'] ) || defined( '_XCORE_PREVENT_EXEC_COMMON_' ) || defined( '_XCORE_PREVENT_LOAD_CORE_' ) ) return ; // skip
  372. $this->_dblayertrap_doubtfuls = array() ;
  373. $this->_dblayertrap_check_recursive( $_GET ) ;
  374. $this->_dblayertrap_check_recursive( $_POST ) ;
  375. $this->_dblayertrap_check_recursive( $_COOKIE ) ;
  376. if( empty( $this->_conf['dblayertrap_wo_server'] ) ) {
  377. $this->_dblayertrap_check_recursive( $_SERVER ) ;
  378. }
  379. if( ! empty( $this->_dblayertrap_doubtfuls ) || $force_override ) {
  380. @define( 'XOOPS_DB_ALTERNATIVE' , 'ProtectorMysqlDatabase' ) ;
  381. require_once dirname(dirname(__FILE__)).'/class/ProtectorMysqlDatabase.class.php' ;
  382. }
  383. }
  384. function _bigumbrella_check_recursive( $val )
  385. {
  386. if( is_array( $val ) ) {
  387. foreach( $val as $subval ) {
  388. $this->_bigumbrella_check_recursive( $subval ) ;
  389. }
  390. } else {
  391. if( preg_match( '/[<\'"].{15}/s' , $val , $regs ) ) {
  392. $this->_bigumbrella_doubtfuls[] = $regs[0] ;
  393. }
  394. }
  395. }
  396. function bigumbrella_init()
  397. {
  398. $this->_bigumbrella_doubtfuls = array() ;
  399. $this->_bigumbrella_check_recursive( $_GET ) ;
  400. $this->_bigumbrella_check_recursive( @$_SERVER['PHP_SELF'] ) ;
  401. if( ! empty( $this->_bigumbrella_doubtfuls ) ) {
  402. ob_start( array( $this , 'bigumbrella_outputcheck' ) ) ;
  403. }
  404. }
  405. function bigumbrella_outputcheck( $s )
  406. {
  407. if( defined( 'BIGUMBRELLA_DISABLED' ) ) return $s ;
  408. if( function_exists( 'headers_list' ) ) {
  409. foreach( headers_list() as $header ) {
  410. if( stristr( $header , 'Content-Type:' ) && ! stristr( $header , 'text/html' ) ) {
  411. return $s ;
  412. }
  413. }
  414. }
  415. if( ! is_array( $this->_bigumbrella_doubtfuls ) ) {
  416. return "bigumbrella injection found." ;
  417. }
  418. foreach( $this->_bigumbrella_doubtfuls as $doubtful ) {
  419. if( strstr( $s , $doubtful ) ) {
  420. return "XSS found by Protector." ;
  421. }
  422. }
  423. return $s ;
  424. }
  425. function intval_allrequestsendid()
  426. {
  427. global $HTTP_GET_VARS , $HTTP_POST_VARS , $HTTP_COOKIE_VARS ;
  428. if( $this->_done_intval ) return true ;
  429. else $this->_done_intval = true ;
  430. foreach( $_GET as $key => $val ) {
  431. if( substr( $key , -2 ) == 'id' && ! is_array( $_GET[ $key ] ) ) {
  432. $newval = preg_replace( '/[^0-9a-zA-Z_-]/' , '' , $val ) ;
  433. if( isset( $_REQUEST[ $key ] ) && $_REQUEST[ $key ] == $_GET[ $key ] ){
  434. $_REQUEST[ $key ] = $newval ;
  435. }
  436. $_GET[ $key ] = $HTTP_GET_VARS[ $key ] = $newval ;
  437. }
  438. }
  439. foreach( $_POST as $key => $val ) {
  440. if( substr( $key , -2 ) == 'id' && ! is_array( $_POST[ $key ] ) ) {
  441. $newval = preg_replace( '/[^0-9a-zA-Z_-]/' , '' , $val ) ;
  442. if( isset( $_REQUEST[ $key ] ) && $_REQUEST[ $key ] == $_POST[ $key ] ){
  443. $_REQUEST[ $key ] = $newval ;
  444. }
  445. $_POST[ $key ] = $HTTP_POST_VARS[ $key ] = $newval ;
  446. }
  447. }
  448. foreach( $_COOKIE as $key => $val ) {
  449. if( substr( $key , -2 ) == 'id' && ! is_array( $_COOKIE[ $key ] ) ) {
  450. $newval = preg_replace( '/[^0-9a-zA-Z_-]/' , '' , $val ) ;
  451. if( isset( $_REQUEST[ $key ] ) && $_REQUEST[ $key ] == $_COOKIE[ $key ] ){
  452. $_REQUEST[ $key ] = $newval ;
  453. }
  454. $_COOKIE[ $key ] = $HTTP_COOKIE_VARS[ $key ] = $newval ;
  455. }
  456. }
  457. return true ;
  458. }
  459. function eliminate_dotdot()
  460. {
  461. global $HTTP_GET_VARS , $HTTP_POST_VARS , $HTTP_COOKIE_VARS ;
  462. if( $this->_done_dotdot ) return true ;
  463. else $this->_done_dotdot = true ;
  464. foreach( $_GET as $key => $val ) {
  465. if( is_array( $_GET[ $key ] ) ) continue ;
  466. if( substr( trim( $val ) , 0 , 3 ) == '../' || strstr( $val , '../../' ) ) {
  467. $this->last_error_type = 'DirTraversal' ;
  468. $this->message .= "Directory Traversal '$val' found.\n" ;
  469. $this->output_log( $this->last_error_type , 0 , false , 64 ) ;
  470. $sanitized_val = str_replace( chr(0) , '' , $val ) ;
  471. if( substr( $sanitized_val , -2 ) != ' .' ) $sanitized_val .= ' .' ;
  472. $_GET[ $key ] = $HTTP_GET_VARS[ $key ] = $sanitized_val ;
  473. if( $_REQUEST[ $key ] == $_GET[ $key ] ){
  474. $_REQUEST[ $key ] = $sanitized_val ;
  475. }
  476. }
  477. }
  478. /* foreach( $_POST as $key => $val ) {
  479. if( is_array( $_POST[ $key ] ) ) continue ;
  480. if( substr( trim( $val ) , 0 , 3 ) == '../' || strstr( $val , '../../' ) ) {
  481. $this->last_error_type = 'ParentDir' ;
  482. $this->message .= "Doubtful file specification '$val' found.\n" ;
  483. $this->output_log( $this->last_error_type , 0 , false , 128 ) ;
  484. $sanitized_val = str_replace( chr(0) , '' , $val ) ;
  485. if( substr( $sanitized_val , -2 ) != ' .' ) $sanitized_val .= ' .' ;
  486. $_POST[ $key ] = $HTTP_POST_VARS[ $key ] = $sanitized_val ;
  487. if( $_REQUEST[ $key ] == $_POST[ $key ] ){
  488. $_REQUEST[ $key ] = $sanitized_val ;
  489. }
  490. }
  491. }
  492. foreach( $_COOKIE as $key => $val ) {
  493. if( is_array( $_COOKIE[ $key ] ) ) continue ;
  494. if( substr( trim( $val ) , 0 , 3 ) == '../' || strstr( $val , '../../' ) ) {
  495. $this->last_error_type = 'ParentDir' ;
  496. $this->message .= "Doubtful file specification '$val' found.\n" ;
  497. $this->output_log( $this->last_error_type , 0 , false , 128 ) ;
  498. $sanitized_val = str_replace( chr(0) , '' , $val ) ;
  499. if( substr( $sanitized_val , -2 ) != ' .' ) $sanitized_val .= ' .' ;
  500. $_COOKIE[ $key ] = $HTTP_COOKIE_VARS[ $key ] = $sanitized_val ;
  501. if( $_REQUEST[ $key ] == $_COOKIE[ $key ] ){
  502. $_REQUEST[ $key ] = $sanitized_val ;
  503. }
  504. }
  505. }*/
  506. return true ;
  507. }
  508. function &get_ref_from_base64index( &$current , $indexes )
  509. {
  510. foreach( $indexes as $index ) {
  511. $index = base64_decode( $index ) ;
  512. if( ! is_array( $current ) ) return false ;
  513. $current =& $current[ $index ] ;
  514. }
  515. return $current ;
  516. }
  517. function replace_doubtful( $key , $val )
  518. {
  519. global $HTTP_GET_VARS , $HTTP_POST_VARS , $HTTP_COOKIE_VARS ;
  520. $index_expression = '' ;
  521. $indexes = explode( '_' , $key ) ;
  522. $base_array = array_shift( $indexes ) ;
  523. switch( $base_array ) {
  524. case 'G' :
  525. $main_ref =& $this->get_ref_from_base64index( $_GET , $indexes ) ;
  526. $xcore_ref =& $this->get_ref_from_base64index( $HTTP_GET_VARS , $indexes ) ;
  527. break ;
  528. case 'P' :
  529. $main_ref =& $this->get_ref_from_base64index( $_POST , $indexes ) ;
  530. $xcore_ref =& $this->get_ref_from_base64index( $HTTP_POST_VARS , $indexes ) ;
  531. break ;
  532. case 'C' :
  533. $main_ref =& $this->get_ref_from_base64index( $_COOKIE , $indexes ) ;
  534. $xcore_ref =& $this->get_ref_from_base64index( $HTTP_COOKIE_VARS , $indexes ) ;
  535. break ;
  536. default :
  537. exit ;
  538. }
  539. if( ! isset( $main_ref ) ) exit ;
  540. $request_ref =& $this->get_ref_from_base64index( $_REQUEST , $indexes ) ;
  541. if( $request_ref !== false && $main_ref == $request_ref ) {
  542. $request_ref = $val ;
  543. }
  544. $main_ref = $val ;
  545. $xcore_ref = $val ;
  546. }
  547. function check_uploaded_files()
  548. {
  549. if( $this->_done_badext ) return $this->_safe_badext ;
  550. else $this->_done_badext = true ;
  551. // extensions never uploaded
  552. $bad_extensions = array( 'php' , 'phtml' , 'phtm' , 'php3' , 'php4' , 'cgi' , 'pl' , 'asp' ) ;
  553. // extensions needed image check (anti-IE Content-Type XSS)
  554. $image_extensions = array( 1 => 'gif', 2 => 'jpg', 3 => 'png', 4 => 'swf', 5 => 'psd', 6 => 'bmp', 7 => 'tif', 8 => 'tif', 9 => 'jpc', 10 => 'jp2', 11 => 'jpx', 12 => 'jb2', 13 => 'swc', 14 => 'iff', 15 => 'wbmp', 16 => 'xbm' ) ;
  555. foreach( $_FILES as $_file ) {
  556. if( ! empty( $_file['error'] ) ) continue ;
  557. if( ! empty( $_file['name'] ) && is_string( $_file['name'] ) ) {
  558. $ext = strtolower( substr( strrchr( $_file['name'] , '.' ) , 1 ) ) ;
  559. if( $ext == 'jpeg' ) $ext = 'jpg' ;
  560. else if( $ext == 'tiff' ) $ext = 'tif' ;
  561. else if( $ext == 'swc' ) $ext = 'swf' ;
  562. // anti multiple dot file (Apache mod_mime.c)
  563. if( count( explode( '.' , str_replace( '.tar.gz' , '.tgz' , $_file['name'] ) ) ) > 2 ) {
  564. $this->message .= "Attempt to multiple dot file {$_file['name']}.\n" ;
  565. $this->_safe_badext = false ;
  566. $this->last_error_type = 'UPLOAD' ;
  567. }
  568. // anti dangerous extensions
  569. if( in_array( $ext , $bad_extensions ) ) {
  570. $this->message .= "Attempt to upload {$_file['name']}.\n" ;
  571. $this->_safe_badext = false ;
  572. $this->last_error_type = 'UPLOAD' ;
  573. }
  574. // anti camouflaged image file
  575. if( in_array( $ext , $image_extensions ) ) {
  576. $image_attributes = @getimagesize( $_file['tmp_name'] ) ;
  577. if( $image_attributes === false && is_uploaded_file( $_file['tmp_name'] ) ) {
  578. // open_basedir restriction
  579. $temp_file = XOOPS_ROOT_PATH.'/uploads/protector_upload_temporary'.md5( time() ) ;
  580. move_uploaded_file( $_file['tmp_name'] , $temp_file ) ;
  581. $image_attributes = @getimagesize( $temp_file ) ;
  582. @unlink( $temp_file ) ;
  583. }
  584. $imagetype = intval( $image_attributes[2] ) ;
  585. if( $imagetype == IMAGETYPE_SWC ) $imagetype = IMAGETYPE_SWF ;
  586. if( $image_attributes === false || $image_extensions[ $imagetype ] != $ext ) {
  587. $this->message .= "Attempt to upload camouflaged image file {$_file['name']}.\n" ;
  588. $this->_safe_badext = false ;
  589. $this->last_error_type = 'UPLOAD' ;
  590. }
  591. }
  592. }
  593. }
  594. return $this->_safe_badext ;
  595. }
  596. function check_contami_systemglobals()
  597. {
  598. /* if( $this->_done_contami ) return $this->_safe_contami ;
  599. else $this->_done_contami = true ; */
  600. /* foreach( $this->_bad_globals as $bad_global ) {
  601. if( isset( $_REQUEST[ $bad_global ] ) ) {
  602. $this->message .= "Attempt to inject '$bad_global' was found.\n" ;
  603. $this->_safe_contami = false ;
  604. $this->last_error_type = 'CONTAMI' ;
  605. }
  606. }*/
  607. return $this->_safe_contami ;
  608. }
  609. function check_sql_isolatedcommentin( $sanitize = true )
  610. {
  611. if( $this->_done_isocom ) return $this->_safe_isocom ;
  612. else $this->_done_isocom = true ;
  613. foreach( $this->_doubtful_requests as $key => $val ) {
  614. $str = $val ;
  615. while( $str = strstr( $str , '/*' ) ) { /* */
  616. $str = strstr( substr( $str , 2 ) , '*/' ) ;
  617. if( $str === false ) {
  618. $this->message .= "Isolated comment-in found. ($val)\n" ;
  619. if( $sanitize ) $this->replace_doubtful( $key , $val . '*/' ) ;
  620. $this->_safe_isocom = false ;
  621. $this->last_error_type = 'ISOCOM' ;
  622. }
  623. }
  624. }
  625. return $this->_safe_isocom ;
  626. }
  627. function check_sql_union( $sanitize = true )
  628. {
  629. if( $this->_done_union ) return $this->_safe_union ;
  630. else $this->_done_union = true ;
  631. foreach( $this->_doubtful_requests as $key => $val ) {
  632. $str = str_replace( array( '/*' , '*/' ) , '' , preg_replace( '?/\*.+\*/?sU' , '' , $val ) ) ;
  633. if( preg_match( '/\sUNION\s+(ALL|SELECT)/i' , $str ) ) {
  634. $this->message .= "Pattern like SQL injection found. ($val)\n" ;
  635. if( $sanitize ) $this->replace_doubtful( $key , preg_replace( '/union/i' , 'uni-on' , $val ) ) ;
  636. $this->_safe_union = false ;
  637. $this->last_error_type = 'UNION' ;
  638. }
  639. }
  640. return $this->_safe_union ;
  641. }
  642. function check_dos_attack( $uid = 0 , $can_ban = false )
  643. {
  644. global $xoopsDB ;
  645. if( $this->_done_dos ) return true ;
  646. $ip = @$_SERVER['REMOTE_ADDR'] ;
  647. $uri = @$_SERVER['REQUEST_URI'] ;
  648. $ip4sql = addslashes( $ip ) ;
  649. $uri4sql = addslashes( $uri ) ;
  650. if( empty( $ip ) || $ip == '' ) return true ;
  651. // gargage collection
  652. $result = $xoopsDB->queryF( "DELETE FROM ".$xoopsDB->prefix($this->mydirname."_access")." WHERE expire < UNIX_TIMESTAMP()" ) ;
  653. // for older versions before updating this module
  654. if( $result === false ) {
  655. $this->_done_dos = true ;
  656. return true ;
  657. }
  658. // sql for recording access log (INSERT should be placed after SELECT)
  659. $sql4insertlog = "INSERT INTO ".$xoopsDB->prefix($this->mydirname."_access")." SET ip='$ip4sql',request_uri='$uri4sql',expire=UNIX_TIMESTAMP()+'".intval($this->_conf['dos_expire'])."'" ;
  660. // bandwidth limitation
  661. if( @$this->_conf['bwlimit_count'] >= 10 ) {
  662. $result = $xoopsDB->query( "SELECT COUNT(*) FROM ".$xoopsDB->prefix($this->mydirname."_access") ) ;
  663. list( $bw_count ) = $xoopsDB->fetchRow( $result ) ;
  664. if( $bw_count > $this->_conf['bwlimit_count'] ) {
  665. $this->write_file_bwlimit( time() + $this->_conf['dos_expire'] ) ;
  666. }
  667. }
  668. // F5 attack check (High load & same URI)
  669. $result = $xoopsDB->query( "SELECT COUNT(*) FROM ".$xoopsDB->prefix($this->mydirname."_access")." WHERE ip='$ip4sql' AND request_uri='$uri4sql'" ) ;
  670. list( $f5_count ) = $xoopsDB->fetchRow( $result ) ;
  671. if( $f5_count > $this->_conf['dos_f5count'] ) {
  672. // delayed insert
  673. $xoopsDB->queryF( $sql4insertlog ) ;
  674. // extends the expires of the IP with 5 minutes at least (pending)
  675. // $result = $xoopsDB->queryF( "UPDATE ".$xoopsDB->prefix($this->mydirname."_access")." SET expire=UNIX_TIMESTAMP()+300 WHERE ip='$ip4sql' AND expire<UNIX_TIMESTAMP()+300" ) ;
  676. // call the filter first
  677. $ret = $this->call_filter( 'f5attack_overrun' ) ;
  678. // actions for F5 Attack
  679. $this->_done_dos = true ;
  680. $this->last_error_type = 'DoS' ;
  681. switch( $this->_conf['dos_f5action'] ) {
  682. default :
  683. case 'exit' :
  684. $this->output_log( $this->last_error_type , $uid , true , 16 ) ;
  685. exit ;
  686. case 'none' :
  687. $this->output_log( $this->last_error_type , $uid , true , 16 ) ;
  688. return true ;
  689. case 'biptime0' :
  690. if( $can_ban ) $this->register_bad_ips( time() + $this->_conf['banip_time0'] ) ;
  691. break ;
  692. case 'bip' :
  693. if( $can_ban ) $this->register_bad_ips() ;
  694. break ;
  695. case 'hta' :
  696. if( $can_ban ) $this->deny_by_htaccess() ;
  697. break ;
  698. case 'sleep' :
  699. sleep( 5 ) ;
  700. break ;
  701. }
  702. return false ;
  703. }
  704. // Check its Agent
  705. if( trim( $this->_conf['dos_crsafe'] ) != '' && preg_match( $this->_conf['dos_crsafe'] , @$_SERVER['HTTP_USER_AGENT'] ) ) {
  706. // welcomed crawler
  707. $this->_done_dos = true ;
  708. return true ;
  709. }
  710. // Crawler check (High load & different URI)
  711. $result = $xoopsDB->query( "SELECT COUNT(*) FROM ".$xoopsDB->prefix($this->mydirname."_access")." WHERE ip='$ip4sql'" ) ;
  712. list( $crawler_count ) = $xoopsDB->fetchRow( $result ) ;
  713. // delayed insert
  714. $xoopsDB->queryF( $sql4insertlog ) ;
  715. if( $crawler_count > $this->_conf['dos_crcount'] ) {
  716. // call the filter first
  717. $ret = $this->call_filter( 'crawler_overrun' ) ;
  718. // actions for bad Crawler
  719. $this->_done_dos = true ;
  720. $this->last_error_type = 'CRAWLER' ;
  721. switch( $this->_conf['dos_craction'] ) {
  722. default :
  723. case 'exit' :
  724. $this->output_log( $this->last_error_type , $uid , true , 16 ) ;
  725. exit ;
  726. case 'none' :
  727. $this->output_log( $this->last_error_type , $uid , true , 16 ) ;
  728. return true ;
  729. case 'biptime0' :
  730. if( $can_ban ) $this->register_bad_ips( time() + $this->_conf['banip_time0'] ) ;
  731. break ;
  732. case 'bip' :
  733. if( $can_ban ) $this->register_bad_ips() ;
  734. break ;
  735. case 'hta' :
  736. if( $can_ban ) $this->deny_by_htaccess() ;
  737. break ;
  738. case 'sleep' :
  739. sleep( 5 ) ;
  740. break ;
  741. }
  742. return false ;
  743. }
  744. return true ;
  745. }
  746. //
  747. function check_brute_force()
  748. {
  749. global $xoopsDB ;
  750. $ip = @$_SERVER['REMOTE_ADDR'] ;
  751. $uri = @$_SERVER['REQUEST_URI'] ;
  752. $ip4sql = addslashes( $ip ) ;
  753. $uri4sql = addslashes( $uri ) ;
  754. if( empty( $ip ) || $ip == '' ) return true ;
  755. $victim_uname = empty( $_COOKIE['autologin_uname'] ) ? $_POST['uname'] : $_COOKIE['autologin_uname'] ;
  756. // some UA send 'deleted' as a value of the deleted cookie.
  757. if( $victim_uname == 'deleted' ) return ;
  758. $mal4sql = addslashes( "BRUTE FORCE: $victim_uname" ) ;
  759. // gargage collection
  760. $result = $xoopsDB->queryF( "DELETE FROM ".$xoopsDB->prefix($this->mydirname."_access")." WHERE expire < UNIX_TIMESTAMP()" ) ;
  761. // sql for recording access log (INSERT should be placed after SELECT)
  762. $sql4insertlog = "INSERT INTO ".$xoopsDB->prefix($this->mydirname."_access")." SET ip='$ip4sql',request_uri='$uri4sql',malicious_actions='$mal4sql',expire=UNIX_TIMESTAMP()+600" ;
  763. // count check
  764. $result = $xoopsDB->query( "SELECT COUNT(*) FROM ".$xoopsDB->prefix($this->mydirname."_access")." WHERE ip='$ip4sql' AND malicious_actions like 'BRUTE FORCE:%'" ) ;
  765. list( $bf_count ) = $xoopsDB->fetchRow( $result ) ;
  766. if( $bf_count > $this->_conf['bf_count'] ) {
  767. $this->register_bad_ips( time() + $this->_conf['banip_time0'] ) ;
  768. $this->last_error_type = 'BruteForce' ;
  769. $this->message .= "Trying to login as '".addslashes($victim_uname)."' found.\n" ;
  770. $this->output_log( 'BRUTE FORCE' , 0 , true , 1 ) ;
  771. $ret = $this->call_filter( 'bruteforce_overrun' ) ;
  772. if( $ret == false ) exit ;
  773. }
  774. // delayed insert
  775. $xoopsDB->queryF( $sql4insertlog ) ;
  776. }
  777. function _spam_check_point_recursive( $val )
  778. {
  779. if( is_array( $val ) ) {
  780. foreach( $val as $subval ) {
  781. $this->_spam_check_point_recursive( $subval ) ;
  782. }
  783. } else {
  784. // http_host
  785. $path_array = parse_url( XOOPS_URL ) ;
  786. $http_host = empty( $path_array['host'] ) ? 'www.xoops.org' : $path_array['host'] ;
  787. // count URI up
  788. $count = -1 ;
  789. foreach( preg_split( '#https?\:\/\/#i' , $val ) as $fragment ) {
  790. if( strncmp( $fragment , $http_host , strlen( $http_host ) ) !== 0 ) {
  791. $count ++ ;
  792. }
  793. }
  794. if( $count > 0 ) $this->_spamcount_uri += $count ;
  795. // count BBCode likd [url=www....] up (without [url=http://...])
  796. $this->_spamcount_uri += count( preg_split( '/\[url=(?!http|\\"http|\\\'http|'.$http_host.')/i' , $val ) ) - 1 ;
  797. }
  798. }
  799. function spam_check( $points4deny , $uid )
  800. {
  801. $this->_spamcount_uri = 0 ;
  802. $this->_spam_check_point_recursive( $_POST ) ;
  803. if( $this->_spamcount_uri >= $points4deny ) {
  804. $this->message .= @$_SERVER['REQUEST_URI']." SPAM POINT: $this->_spamcount_uri\n" ;
  805. $this->output_log( 'URI SPAM' , $uid , false , 128 ) ;
  806. $ret = $this->call_filter( 'spamcheck_overrun' ) ;
  807. if( $ret == false ) exit ;
  808. }
  809. }
  810. function check_manipulation()
  811. {
  812. if( $_SERVER['SCRIPT_FILENAME'] == XOOPS_ROOT_PATH.'/index.php' ) {
  813. $root_stat = stat( XOOPS_ROOT_PATH ) ;
  814. $index_stat = stat( XOOPS_ROOT_PATH.'/index.php' ) ;
  815. $finger_print = $root_stat['mtime'] .':'. $index_stat['mtime'] .':'. $index_stat['ino'] ;
  816. if( empty( $this->_conf['manip_value'] ) ) {
  817. $this->updateConfIntoDb( 'manip_value' , $finger_print ) ;
  818. } else if( $finger_print != $this->_conf['manip_value'] ) {
  819. // Notify if finger_print is ident from old one
  820. $ret = $this->call_filter( 'postcommon_manipu' ) ;
  821. if( $ret == false ) die( 'Protector detects site manipulation.' ) ;
  822. $this->updateConfIntoDb( 'manip_value' , $finger_print ) ;
  823. }
  824. }
  825. }
  826. function disable_features()
  827. {
  828. global $HTTP_POST_VARS , $HTTP_GET_VARS , $HTTP_COOKIE_VARS ;
  829. // disable "Notice: Undefined index: ..."
  830. $error_reporting_level = error_reporting( 0 ) ;
  831. //
  832. // bit 1 : disable XMLRPC , criteria bug
  833. //
  834. if( $this->_conf['disable_features'] & 1 ) {
  835. // zx 2005/1/5 disable xmlrpc.php in root
  836. if( /* ! stristr( $_SERVER['SCRIPT_NAME'] , 'modules' ) && */ substr( @$_SERVER['SCRIPT_NAME'] , -10 ) == 'xmlrpc.php' ) {
  837. $this->output_log( 'xmlrpc' , 0 , true , 1 ) ;
  838. exit ;
  839. }
  840. // security bug of class/criteria.php 2005/6/27
  841. if( $_POST['uname'] === '0' || $_COOKIE['autologin_pass'] === '0' ) {
  842. $this->output_log( 'CRITERIA' ) ;
  843. exit ;
  844. }
  845. }
  846. //
  847. // bit 11 : XSS+CSRFs in XOOPS < 2.0.10
  848. //
  849. if( $this->_conf['disable_features'] & 1024 ) {
  850. // root controllers
  851. if( ! stristr( @$_SERVER['SCRIPT_NAME'] , 'modules' ) ) {
  852. // zx 2004/12/13 misc.php debug (file check)
  853. if( substr( @$_SERVER['SCRIPT_NAME'] , -8 ) == 'misc.php' && ( $_GET['type'] == 'debug' || $_POST['type'] == 'debug' ) && ! preg_match( '/^dummy_[0-9]+\.html$/' , $_GET['file'] ) ) {
  854. $this->output_log( 'misc debug' ) ;
  855. exit ;
  856. }
  857. // zx 2004/12/13 misc.php smilies
  858. if( substr( @$_SERVER['SCRIPT_NAME'] , -8 ) == 'misc.php' && ( $_GET['type'] == 'smilies' || $_POST['type'] == 'smilies' ) && ! preg_match( '/^[0-9a-z_]*$/i' , $_GET['target'] ) ) {
  859. $this->output_log( 'misc smilies' ) ;
  860. exit ;
  861. }
  862. // zx 2005/1/5 edituser.php avatarchoose
  863. if( substr( @$_SERVER['SCRIPT_NAME'] , -12 ) == 'edituser.php' && $_POST['op'] == 'avatarchoose' && strstr( $_POST['user_avatar'] , '..' ) ) {
  864. $this->output_log( 'edituser avatarchoose' ) ;
  865. exit ;
  866. }
  867. }
  868. // zx 2005/1/4 findusers
  869. if( substr( @$_SERVER['SCRIPT_NAME'] , -24 ) == 'modules/system/admin.php' && ( $_GET['fct'] == 'findusers' || $_POST['fct'] == 'findusers' ) ) {
  870. foreach( $_POST as $key => $val ) {
  871. if( strstr( $key , "'" ) || strstr( $val , "'" ) ) {
  872. $this->output_log( 'findusers' ) ;
  873. exit ;
  874. }
  875. }
  876. }
  877. // preview CSRF zx 2004/12/14
  878. // news submit.php
  879. if( substr( @$_SERVER['SCRIPT_NAME'] , -23 ) == 'modules/news/submit.php' && isset( $_POST['preview'] ) && strpos( @$_SERVER['HTTP_REFERER'] , XOOPS_URL.'/modules/news/submit.php' ) !== 0 ) {
  880. $HTTP_POST_VARS['nohtml'] = $_POST['nohtml'] = 1 ;
  881. }
  882. // news admin/index.php
  883. if( substr( @$_SERVER['SCRIPT_NAME'] , -28 ) == 'modules/news/admin/index.php' && ( $_POST['op'] == 'preview' || $_GET['op'] == 'preview' ) && strpos( @$_SERVER['HTTP_REFERER'] , XOOPS_URL.'/modules/news/admin/index.php' ) !== 0 ) {
  884. $HTTP_POST_VARS['nohtml'] = $_POST['nohtml'] = 1 ;
  885. }
  886. // comment comment_post.php
  887. if( isset( $_POST['com_dopreview'] ) && ! strstr( substr( @$_SERVER['HTTP_REFERER'] , -16 ) , 'comment_post.php' ) ) {
  888. $HTTP_POST_VARS['dohtml'] = $_POST['dohtml'] = 0 ;
  889. }
  890. // disable preview of system's blocksadmin
  891. if( substr( @$_SERVER['SCRIPT_NAME'] , -24 ) == 'modules/system/admin.php' && ( $_GET['fct'] == 'blocksadmin' || $_POST['fct'] == 'blocksadmin') && isset( $_POST['previewblock'] ) /* && strpos( $_SERVER['HTTP_REFERER'] , XOOPS_URL.'/modules/system/admin.php' ) !== 0 */ ) {
  892. die( "Danger! don't use this preview. Use 'altsys module' instead.(by Protector)" ) ;
  893. }
  894. // tpl preview
  895. if( substr( @$_SERVER['SCRIPT_NAME'] , -24 ) == 'modules/system/admin.php' && ( $_GET['fct'] == 'tplsets' || $_POST['fct'] == 'tplsets') ) {
  896. if( $_POST['op'] == 'previewpopup' || $_GET['op'] == 'previewpopup' || isset( $_POST['previewtpl'] ) ) {
  897. die( "Danger! don't use this preview.(by Protector)" ) ;
  898. }
  899. }
  900. }
  901. // restore reporting level
  902. error_reporting( $error_reporting_level ) ;
  903. }
  904. function call_filter( $type , $dying_message = '' )
  905. {
  906. require_once dirname(__FILE__).'/ProtectorFilter.php' ;
  907. $filter_handler =& ProtectorFilterHandler::getInstance() ;
  908. $ret = $filter_handler->execute( $type ) ;
  909. if( $ret == false && $dying_message ) {
  910. die( $dying_message ) ;
  911. }
  912. return $ret ;
  913. }
  914. }
  915. ?>