Pastebin launched a little side project called HostCabi.net, check it out ;-)Don't like ads? PRO users don't see any ads ;-)
Guest

osC_Sec

By: a guest on Mar 11th, 2012  |  syntax: PHP  |  size: 53.74 KB  |  hits: 43  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. <?php
  2.  
  3.   /**
  4.    * @package osC_Sec Security Class for Oscommerce / Digistore
  5.    * @author Te Taipo <rohepotae@gmail.com>
  6.    * @copyright (c) Hokioi-IT
  7.    * @license http://opensource.org/licenses/gpl-license.php GNU Public License
  8.    * @version $Id: osC_Sec.php 5.0.2
  9.    * @see readme.htm
  10.    * @link http://addons.oscommerce.com/info/8283/
  11.    **/
  12.  
  13.   # switch off server error 'notices'
  14.  error_reporting( 6135 );
  15.  
  16.   # set the POSIX locale
  17.  setlocale( LC_CTYPE, "C" );
  18.  
  19.   # make sure $_SERVER[ "REQUEST_URI" ] is set
  20.  fix_server_vars();
  21.  
  22.   # prevent direct viewing of osC_Sec.php
  23.  if ( false !== strpos( strtolower( $_SERVER[ "SCRIPT_NAME" ] ), osCSec_selfchk() ) ) senda404Header();
  24.  
  25.   # include the settings file osc.php
  26.  if ( file_exists( rtrim( dirname( __file__ ), '/\\' ) . DIRECTORY_SEPARATOR . 'osc.php' ) ) {
  27.      require_once( rtrim( dirname( __file__ ), '/\\' ) . DIRECTORY_SEPARATOR . 'osc.php' );
  28.   } else {
  29.      # if osc.php missing
  30.     $osC_Sec = new osC_Sec();
  31.      $osC_Sec->Sentry( $timestampOffset=0,$nonGETPOSTReqs=0,$spiderBlock=0,$banipaddress=0,$useIPTRAP=0,
  32.                        $ipTrapBlocked="",$emailenabled=0,$youremail="",$fromemail="",$disable_tellafriend=NULL );
  33.   }
  34.  
  35.   class osC_Sec {
  36.    
  37.     var $_fullreport = true;
  38.    
  39.     function Sentry( $timestampOffset=0,$nonGETPOSTReqs=0,$spiderBlock=0,$banipaddress=0,$useIPTRAP=0,
  40.                      $ipTrapBlocked="",$emailenabled=0,$youremail="",$fromemail="",$disable_tellafriend=NULL ) {
  41.      
  42.       global $PHP_SELF;
  43.       $this->_nonGETPOSTReqs = ( bool )$this->fINT( $nonGETPOSTReqs );
  44.       $this->_banipaddress = ( bool )$this->fINT( $banipaddress );
  45.       $this->_useIPTRAP = ( bool )$this->fINT( $useIPTRAP );
  46.       $this->_emailenabled = ( bool )$this->fINT( $emailenabled );
  47.       $this->_currentVersion = "5.0.2";
  48.       $spiderBlock = ( bool )$this->fINT( $spiderBlock );
  49.       $this->_whitelistpattern = "[^\w\s\p{L}\d\r?,=@%:{}\/.-]";
  50.      
  51.       $this->_disable_tellafriend = 0;
  52.       if ( isset( $disable_tellafriend ) ) $this->_disable_tellafriend = ( bool )$this->fINT( $disable_tellafriend );
  53.  
  54.       $this->setIPTrapBlocked( $ipTrapBlocked );
  55.  
  56.       if ( false !== ( bool )$this->fINT( $this->_emailenabled ) ) {
  57.           $this->_youremail = $youremail;
  58.           $this->_fromemail = $fromemail;
  59.           $this->_timestampOffset = $this->fINT( $timestampOffset );
  60.       }
  61.      
  62.       # if open_basedir is not set in php.ini then set it in the local scope
  63.      # only available for version 2.3.1 of osCommerce
  64.      $this->setOpenBaseDir();
  65.      
  66.       # check settings are correct
  67.      $this->chkSetup();
  68.  
  69.       # reliably set $PHP_SELF as a filename
  70.      $PHP_SELF = $this->phpSelfFix();
  71.  
  72.       # prevent the version of php being discovered
  73.      $this->x_powered_by();
  74.      
  75.       # ban bad harvesting spiders
  76.      if ( false !== $spiderBlock ) $this->badArachnid();
  77.  
  78.       # set the host address to be used in the email notification and htaccess
  79.      if ( ( false !== $this->_emailenabled )
  80.          || ( false !== $this->_banipaddress ) ) {
  81.          $this->_httphost = preg_replace( "/^(?:([^\.]+)\.)?domain\.com$/", "\1", $_SERVER[ "SERVER_NAME" ] );
  82.       }
  83.       # set the path to the htaccess in the root catalog
  84.      if ( $this->_banipaddress ) $this->_htaccessfile = $this->strCharsfrmStr( $this->getDir() . ".htaccess", "//", "/" );
  85.      
  86.       # set the path to the IP_Trapped.txt file
  87.      if ( $this->_useIPTRAP ) $this->_ipTrappedURL = $this->strCharsfrmStr( $this->getDir() . "banned/IP_Trapped.txt", "//", "/" );
  88.  
  89.       # if ip address already in the trapped banlist, redirect to blocked.php
  90.      if ( false !== $this->ipTrapped() ) {
  91.           header( "Location: " . $this->_ipTrapBlocked );
  92.           exit;
  93.       }
  94.       # prevent non-standard requests:
  95.      $this->checkReqType();
  96.      
  97.       # check for the specific attempt to exploit osCommerce / Digistore
  98.      # no requests are exempt from this filter
  99.      $this->osCAdminLoginBypass();
  100.      
  101.       # prevent tell_a_friend.php spam
  102.      # by disabling guest emailing
  103.      $this->disable_tellafriend();
  104.      
  105.       # check for database injection attempts
  106.      $this->dbShield();
  107.  
  108.       # check _GET requests against the blacklist
  109.      $this->getShield();
  110.  
  111.       # run through $_COOKIE checking against blacklists
  112.      $this->cookieShield();
  113.  
  114.       # PHP5 with register_long_arrays off? From SoapCMS Core Security Class
  115.      if ( @phpversion() >= "5.0.0"
  116.             && ( !ini_get( "register_long_arrays" )
  117.             || @ini_get( "register_long_arrays" ) == "0"
  118.             || strtolower( @ini_get( "register_long_arrays" ) ) == "off" ) ) {
  119.  
  120.             $HTTP_POST_VARS = $_POST;
  121.             $HTTP_GET_VARS = $_GET;
  122.             $HTTP_SERVER_VARS = $_SERVER;
  123.             $HTTP_COOKIE_VARS = $_COOKIE;
  124.             $HTTP_ENV_VARS = $_ENV;
  125.             $HTTP_POST_FILES = $_FILES;
  126.  
  127.             # _SESSION is the only superglobal which is conditionally set
  128.            if ( isset( $_SESSION ) ) $HTTP_SESSION_VARS = $_SESSION;
  129.       }
  130.  
  131.       # merge $_REQUEST with cleaned _GET and _POST excluding _COOKIE data
  132.      $_REQUEST = array_merge( $_GET, $_POST );
  133.  
  134.     } // end of Sentry function
  135.  
  136.     /**
  137.      * banChecker()
  138.      *
  139.      * @return
  140.      */
  141.     function banChecker( $r = "", $t = false ) {
  142.         if ( false !== $this->byPass() && false !== ( bool )$t ) {
  143.             return $this->tinoRahui( $r );
  144.         } else {
  145.             return false;
  146.         }
  147.     }
  148.  
  149.     /**
  150.      * osCEmailer()
  151.      *
  152.      * @return
  153.      */
  154.     function osCEmailer( $r, $fullreport = true ) {
  155.          # disable the emailer if htaccess not writable when .htaccess banning is enabled
  156.         if ( false !== $this->_banipaddress ) {
  157.             if ( !$this->hCoreFileChk( $this->_htaccessfile ) ) return;
  158.          }
  159.  
  160.          # send the notification
  161.         if ( (( false !== $this->_banipaddress ) || (false !== $this->_useIPTRAP ) )
  162.                                                      && ( false !== $this->_emailenabled ) ) {
  163.          if ( ( false !== $this->_banipaddress ) && ( $this->hCoreFileChk( $this->_htaccessfile ) ) ) {
  164.              $banAction = "htaccess banned";
  165.          } elseif ( ( false !== $this->_useIPTRAP ) ) {
  166.              $banAction = "IP Trap banned";
  167.          }
  168.          if ( !isset( $this->_timestampOffset ) ) $this->_timestampOffset = 0;
  169.          $timestamp = gmdate( "D, d M Y H:i:s", time() + ( $this->_timestampOffset * 3600 ) );
  170.          $to = $this->_youremail;
  171.          $subject = $this->_httphost . " " . ( substr( $r, 0, 60 ) ) . "...";
  172.          $body = "This IP [ " . $this->getRealIP() . " ] has been " . $banAction . " on the http://" . $this->_httphost .
  173.              " website by osC_Sec.php version " . $this->_currentVersion . "\n\nREASON FOR BAN: " . $r . "\n\nTime of ban: " .
  174.              $timestamp . "\n";
  175.          $body .= "\n.------------[ ALL \$_GET VARIABLES ]-------------\n#\n";
  176.          if ( !empty( $_GET ) ) {
  177.              $sDimGET = $this->array_flatten( $_GET, true );
  178.              foreach ( $sDimGET as $k => $v ) {
  179.                  if ( empty( $v ) ) $v = "NULL";
  180.                  if ( !is_array( $k ) && !is_array( $v ) ) $body .= "# - " . $k . " = " . htmlspecialchars( $v ) . "\n";
  181.              }
  182.          } else {
  183.              $body .= "# - No \$_GET data\n";
  184.          }
  185.          $body .= "#\n`--------------------------------------------------------\n";
  186.          $body .= "\n.---------[ ALL \$_POST FORM VARIABLES ]-------\n#\n";
  187.          if ( ( isset( $_POST ) ) && ( $_SERVER[ "REQUEST_METHOD" ] == "POST" ) ) {
  188.              $sDimPOST = $this->array_flatten( $_POST, true );
  189.              foreach ( $sDimPOST as $k => $v ) {
  190.                  if ( empty( $v ) ) $v = "NULL";
  191.                  if ( !is_array( $k ) && !is_array( $v ) ) $body .= "# - " . $k . " = " . htmlspecialchars( $v ) . "\n";
  192.              }
  193.          } else {
  194.              $body .= "# - No POST form data\n";
  195.          }
  196.          $body .= "#\n`--------------------------------------------------------\n";
  197.          $body .= "\n.------------[ \$_SERVER VARIABLES ]--------------\n#\n";
  198.          if ( false !== $fullreport ) {
  199.              $sDimSERVER = $this->array_flatten( $_SERVER, true );
  200.              foreach ( $sDimSERVER as $k => $v ) {
  201.                  if ( empty( $v ) ) $v = "NULL";
  202.                  if ( !is_array( $k ) && !is_array( $v ) ) $body .= "# - " . $k . " = " . htmlspecialchars( $v ) . "\n";
  203.              }
  204.          } else {
  205.              # short report
  206.             $serverVars = new ArrayIterator( array( "HTTP_HOST", "HTTP_USER_AGENT", "SERVER_ADDR", "REMOTE_ADDR",
  207.                  "DOCUMENT_ROOT", "SCRIPT_FILENAME", "REQUEST_METHOD", "REQUEST_URI", "SCRIPT_NAME", "QUERY_STRING",
  208.                  "HTTP_X_CLUSTER_CLIENT_IP", "HTTP_X_FORWARDED_FOR", "HTTP_X_ORIGINAL_URL", "ORIG_PATH_INFO",
  209.                  "HTTP_X_REWRITE_URL", "HTTP_CLIENT_IP", "HTTP_PROXY_USER", "REDIRECT_URL", "SERVER_SOFTWARE" ) );
  210.              while ( $serverVars->valid() ) {
  211.                  if ( array_key_exists( $serverVars->current(), $_SERVER ) && !empty( $_SERVER[$serverVars->current()] ) ) {
  212.                      $body .= "# - \$_SERVER[ \"" . $serverVars->current() . "\" ] = " . $_SERVER[$serverVars->current()] .
  213.                          "\n";
  214.                  }
  215.                  $serverVars->next();
  216.              }
  217.  
  218.          }
  219.  
  220.          $body .= "# - \$PHP_SELF filename ( osC_Sec ) = " . $this->phpSelfFix() . "\n";
  221.          $body .= "#\n`--------------------------------------------------------\n\n";
  222.          $body .= "OTHER INFO\n";
  223.          $body .= $this->_htaccessfile;
  224.          $body .= "\n";
  225.          $body .= "is htaccess writeable = " . ( $this->hCoreFileChk( $this->_htaccessfile ) );
  226.          $body .= "\n\nResolve IP address: http://en.utrace.de/?query=" . $this->getRealIP() . "\n";
  227.          $body .= "Search Project Honeypot: http://www.projecthoneypot.org/ip_" . $this->getRealIP() . "\n\n";
  228.          $body .= "This email was generated by osC_Sec. To disable email notifications," .
  229.              " open osc.php file, and in the Settings section change \$emailenabled" . " = 1 to \$emailenabled = 0\n\n";
  230.          $body .= "Keep up with the latest version of osC_Sec.php at http://addons.oscommerce.com/info/8283 and http://goo.gl/dQ3jH\n";
  231.          $body .= "See discussions at http://www.digistore.co.nz/forum/viewtopic.php?f=10&t=7" .
  232.              " or email rohepotae@gmail.com with any suggestions.\n\n";
  233.          $from = "From: " . $this->_fromemail;
  234.          ( mail( $to, $subject, $body, $from ) );
  235.       }
  236.       return;
  237.     }
  238.     /**
  239.      * senda403Header()
  240.      *
  241.      * @return
  242.      */
  243.     function senda403Header() {
  244.         $header = array( "HTTP/1.1 403 Access Denied", "Status: 403 Access Denied by osC_Sec", "Content-Length: 0" );
  245.         foreach ( $header as $sent ) {
  246.             header( $sent );
  247.         }
  248.         die();
  249.     }
  250.  
  251.     /**
  252.      * tinoRahui()
  253.      *
  254.      * @return
  255.      */
  256.     function tinoRahui( $r ) {
  257.         if ( false === $this->byPass() ) return;
  258.         if ( ( $this->_banipaddress ) && ( $this->hCoreFileChk( $this->_htaccessfile ) ) ) {
  259.             # send an email
  260.            if ( false !== $this->_emailenabled ) $this->osCEmailer( $r, $this->_fullreport );
  261.             # add ip to htaccess
  262.            $this->htaccessbanip( $this->getRealIP() );
  263.             # call an access denied header
  264.            $this->senda403Header();
  265.             return;
  266.         } elseif ( ( false !== $this->_useIPTRAP ) && ( $this->hCoreFileChk( $this->_ipTrappedURL ) ) ) {
  267.             # send an email
  268.            $this->osCEmailer( $r, $this->_fullreport );
  269.             # add ip to iptrap ban file
  270.            $this->ipTrapban( $this->getRealIP() );
  271.             # redirect to blocked.php
  272.            header( "Location: " . $this->_ipTrapBlocked );
  273.             exit;
  274.         } elseif ( ( false !== $this->_banipaddress ) && ( !$this->hCoreFileChk( $this->_htaccessfile ) ) ) {
  275.             # if non-wrtiable htaccess then call an access denied header
  276.            $this->senda403Header();
  277.             return;
  278.         } elseif ( ( false !== $this->_useIPTRAP ) && ( !$this->hCoreFileChk( $this->_ipTrappedURL ) ) ) {
  279.             # if non-wrtiable iptrap file then call an access denied header
  280.            header( "Location: " . $this->_ipTrapBlocked );
  281.             exit;
  282.         } elseif ( ( false === $this->_banipaddress ) && ( false === $this->_useIPTRAP ) ) {
  283.             # if no banip or iptrap then call an access denied header
  284.            $this->senda403Header();
  285.             return;
  286.         }
  287.     }
  288.     /**
  289.      * osCAdminLoginBypass()
  290.      * @return
  291.      */
  292.     function osCAdminLoginBypass() {
  293.       # $this->byPass() is not called here
  294.      if ( false !== getenv( 'REQUEST_URI' ) ) {
  295.          $thenode = getenv( 'REQUEST_URI' );
  296.       } else {
  297.          $thenode = $_SERVER[ "REQUEST_URI" ];
  298.       }
  299.       if ( false !== strpos( $thenode, "php/login" ) ) {
  300.          $r = "osC_Sec detected an attempt to exploit the admin login bypass exploit. ";
  301.          $this->banChecker( $r, true );
  302.          return;
  303.       }
  304.     }
  305.     /**
  306.      * disable_tellafriend()
  307.      * @return
  308.      */
  309.     function disable_tellafriend() {
  310.       if ( false === $this->_disable_tellafriend ) return;
  311.       $PHP_SELF = $this->phpSelfFix();
  312.       $errlevel = ini_get( 'error_reporting' );
  313.       if ( false === strpos( $PHP_SELF, "tell_a_friend.php" ) ) {
  314.            return;
  315.       } elseif ( false !== strpos( $PHP_SELF, "tell_a_friend.php" )
  316.         && ( "POST" == $_SERVER[ "REQUEST_METHOD" ] )
  317.         && isset( $_GET[ "products_id" ] ) ) {
  318.            $r = "osC_Sec detected an attempt to send spam via the tell_a_friend.php file. ";
  319.            $this->banChecker( $r, true );
  320.            return;
  321.       } elseif ( false !== strpos( $PHP_SELF, "tell_a_friend.php" )
  322.         && isset( $_GET[ "products_id" ] ) ) {
  323.            error_reporting( 0 );
  324.            header( "Location: ./index.php" );
  325.            return error_reporting( $errlevel );
  326.       }
  327.     }
  328.     /**
  329.      * databaseShield()
  330.      * @return
  331.      */
  332.     function dbShield() {
  333.       if ( false === $this->byPass() || empty( $_SERVER[ "QUERY_STRING" ] ) ) return;
  334.  
  335.       $_query = stripslashes( $_SERVER[ "QUERY_STRING" ] );
  336.  
  337.       if ( ( "POST" !== $_SERVER[ "REQUEST_METHOD" ] ) && $this->notemptisarr( $_GET ) ) {
  338.          if ( false !== $this->injectionMatch( strtolower( $_query ) ) ) {
  339.                $r = "osC_Sec detected a database injection attempt: [ " . $_query . " ]. ";
  340.                $this->banChecker( $r, true );
  341.                return;
  342.          }
  343.       }
  344.     }
  345.  
  346.     /**
  347.      * getShield()
  348.      *
  349.      * @return
  350.      */
  351.     function getShield() {
  352.         if ( false === $this->byPass() ) return;
  353.         $reqvar_blacklist = array(
  354.         "php/login", "eval(base64_decode(", "asc%3Deval", "asc%3Deval", "eval%28", "eval%2528", "eval(", "fromCharCode", "; base64",
  355.         "base64,","_START_", "onerror=alert(", "mysql_query", "../cmd", "rush=", "pwtoken_get", "EXTRACTVALUE(", "phpinfo(", "%000",
  356.         "php_uname", "%3Cform", "passthru(", "sha1(", "sha2(", "<%3Fphp", "}%00.", "%%", "/iframe", "\$_GET", "ob_starting",
  357.         "%20and%201=1", "document.cookie(", "document.write(", "onload%3d", "onunload%3d", "PHP_SELF", "shell_exec", "\$_SERVER", "substr(",
  358.         "\$_POST", "\$_SESSION", "\$_REQUEST",  "\$_ENV", "GLOBALS[", "\$HTTP_", ".php/admin", "mosConfig_", "%3C@replace(",
  359.         "hex_ent", "inurl:", "replace(", "/iframe>", "return%20clk", "login.php?action=backupnow", "php/password_for", "@@datadir",
  360.         "unhex(", "error_reporting(", "HTTP_CMD", "=alert(", "version()", "localhost", "})%3B", "/FRAMESET", "Set-Cookie",
  361.         "%27%a0%6f%72%a0%31%3d%31", "%bf%5c%27", "%bf%27", "%ef%bb%bf", "%8c%5c", "%a3%27", "%20regexp%20", "JHs=", "HTTP/1.", "{\$_",
  362.         "<script>" );
  363.  
  364.         $injectattempt = false;
  365.         $sqlfilematchlist = "access_|access.|\balias\b|apache|bin|\bboot\b|config|\benviron\b|error_|error.|etc|httpd|.log|_log|
  366.                             \.(?:js|txt|exe|ht|ini|bat)|\blib\b|log|\bproc\b|\bsql\b|tmp|\busr\b|\bvar\b|(?:uploa|passw)d";
  367.         $sqlfilematchlist = preg_replace( "/[\s]/i", "", $sqlfilematchlist );
  368.        
  369.         if ( false !== getenv( 'REQUEST_URI' ) ) {
  370.            $thenode = getenv( 'REQUEST_URI' );
  371.         } else {
  372.            $thenode = $_SERVER[ "REQUEST_URI" ];
  373.         }
  374.         $v = $this->url_decoder( $thenode ); // first of two urldecodes
  375.         $v = preg_replace( "/$this->_whitelistpattern/i", "", $this->url_decoder( $v ) );
  376.  
  377.         # run through a specific set of tests
  378.        if ( ( false !== ( bool )preg_match( "/onmouse(?:down|over)/i", $v ) )
  379.             && ( 2 < ( int )preg_match_all( "/c(?:path|tthis|t\(this)|http:|(?:forgotte|admi)n|sqlpatch|,,|ftp:|(?:aler|promp)t/i", $v, $matches ) ) ) {
  380.             $injectattempt = true;
  381.         } elseif ( ( ( false !== strpos( $v, "ftp:" ) ) && ( substr_count( $v, "ftp" ) > 1 ) )
  382.             && ( 2 < ( int )preg_match_all( "/@|\/\/|:/i", $v, $matches ) ) ) {
  383.             $injectattempt = true;
  384.         } elseif ( ( false !== ( bool )preg_match( "/(?:showimg|cookie|cookies)=/i", $v ) ) && ( "POST" == $_SERVER[ "REQUEST_METHOD" ] ) ) {
  385.             $injectattempt = true;
  386.         } elseif ( ( ( substr_count( $v, "../" ) > 2 ) || ( substr_count( $v, "..//" ) > 2 ) )
  387.             && ( false !== ( bool )preg_match( "/$sqlfilematchlist/i", $v ) ) ) {
  388.             $injectattempt = true;
  389.         } elseif ( false !== ( bool )preg_match( "/php:\/\/filter|convert.base64-(?:encode|decode)|zlib.(?:inflate|deflate)/i", $v )
  390.                 || false !== ( bool )preg_match( "/data:\/\/filter|text\/plain|http:\/\/(?:127.0.0.1|localhost)/i", $v ) ) {
  391.             $injectattempt = true;
  392.         }
  393.         if ( false !== ( bool )$injectattempt ) {
  394.             $r = "osC_Sec detected an attempt to read or include unauthorized file content. ";
  395.             $this->banChecker( $r, true );
  396.             return;
  397.         }
  398.         foreach ( $reqvar_blacklist as $blacklisted ) {
  399.             $blacklisted = strtolower( $this->url_decoder( $blacklisted ) );
  400.             # somple check of the request_uri against the blacklist irregardless of request type
  401.            if ( ( false !== strpos( $thenode, $blacklisted ) ) ||
  402.                  ( false !== strpos( $this->url_decoder( urldecode( $thenode ) ), $this->url_decoder( $blacklisted ) ) ) ) {
  403.                 $r = "osC_Sec blacklist request_uri item is banned: " . htmlspecialchars( $blacklisted ) . ". ";
  404.                 $this->banChecker( $r, true );
  405.                 return;
  406.             }
  407.         }
  408.         # check each part of the query string against the list
  409.        if ( ( "POST" !== $_SERVER[ "REQUEST_METHOD" ] ) && ( is_array( $_GET ) ) && !empty( $_SERVER[ "QUERY_STRING" ] ) ) {
  410.             $gnodes = explode( "&", $_SERVER[ "QUERY_STRING" ] );
  411.             $i = 0;
  412.             while ( $i < count( $gnodes ) ) {
  413.                 if ( is_string( $gnodes[$i] ) ) {
  414.                     $tmp = explode( "=", $gnodes[$i] );
  415.                     if ( is_array( $tmp ) ) {
  416.                         $gvar = $tmp[count( $tmp ) - count( $tmp )];
  417.                         $gval = $tmp[count( $tmp ) - 1];
  418.                     }
  419.                     $gvar = strtolower( $gvar );
  420.                     $gfvar = preg_replace( "/$whitelistpattern/i", "", $this->url_decoder( $gvar ) );
  421.                     $gval64 = strtolower( base64_decode( $gval ) );
  422.                     $gval = strtolower( $gval );
  423.                     $gfval = preg_replace( "/$whitelistpattern/i", "", $this->url_decoder( $gval ) );
  424.  
  425.                     foreach ( $reqvar_blacklist as $blacklisted ) {
  426.                         $blacklisted = strtolower( $this->url_decoder( $blacklisted ) );
  427.                         if ( ( false !== strpos( $gvar, $blacklisted ) )
  428.                             || ( false !== strpos( $this->url_decoder( urldecode( $gvar ) ), $this->url_decoder( $blacklisted ) ) ) ) {
  429.                              $r = "getShield() listed query_string variable is banned: " . htmlspecialchars( $blacklisted ) . ". ";
  430.                              $this->banChecker( $r, true );
  431.                              return;
  432.                         }
  433.                         if ( ( false !== strpos( $gfvar, $blacklisted ) )
  434.                             || ( false !== strpos( $this->url_decoder( urldecode( $gfvar ) ), $this->url_decoder( $blacklisted ) ) ) ) {
  435.                              $r = "getShield() listed query_string filtered variable is banned: " . htmlspecialchars( $blacklisted ) . ". ";
  436.              
  437.                              $this->banChecker( $r, true );
  438.                              return;
  439.                         }
  440.                         if ( ( false !== strpos( $gval, $blacklisted ) ) ||
  441.                              ( false !== strpos( $this->url_decoder( urldecode( $gval ) ), $this->url_decoder( $blacklisted ) ) ) ) {
  442.                              $r = "osC_Sec blacklist query_string value is banned: " . htmlspecialchars( $blacklisted ) . ". ";
  443.                              $this->banChecker( $r, true );
  444.                              return;
  445.                         }
  446.                         if ( false !== strpos( $gval64, $blacklisted ) ) {
  447.                              $r = "osC_Sec base64 encoded blacklist query_string value is banned: " . htmlspecialchars( $blacklisted ) . ". ";
  448.                              $this->banChecker( $r, true );
  449.                              return;
  450.                         }
  451.                         if ( ( false !== strpos( $gfval, $blacklisted ) ) ||
  452.                              ( false !== strpos( $this->url_decoder( urldecode( $gfval ) ), $this->url_decoder( $blacklisted ) ) ) ) {
  453.                              $r = "osC_Sec blacklist query_string filtered value is banned: " . htmlspecialchars( $blacklisted ) . ". ";
  454.                              $this->banChecker( $r, true );
  455.                              return;
  456.                         }
  457.                     }
  458.                 }
  459.                 $i++;
  460.             }
  461.         }
  462.     }
  463.     /**
  464.      * cookieShield()
  465.      *
  466.      * @return
  467.      */
  468.     function cookieShield() {
  469.      
  470.         if ( ( false === $this->byPass() ) || ( false !== empty( $_COOKIE ) ) ) return;
  471.        
  472.         $_cookie_blacklist = "eval\(|base64_|fromCharCode|prompt\(|ZXZhbCg=|ZnJvbUNoYXJDb2Rl|U0VMRUNULyoqLw==|Ki9XSEVSRS8q";
  473.  
  474.         $injectattempt = false;
  475.         $cnodekeys = array_keys( $_COOKIE );
  476.         $cnodevals = array_values( $_COOKIE );
  477.         $v = implode( " ", $cnodevals );
  478.         $orig_v = $v;
  479.         $injectattempt = $this->injectionMatch( $v );
  480.         if ( isset( $injectattempt ) && ( false !== ( bool )$injectattempt ) ) {
  481.             $r = "osC_Sec detected malicious \$_Cookie content: [ " . stripslashes( $orig_v ) . " ].";
  482.             $this->banChecker( $r, true );
  483.             return;
  484.         }
  485.  
  486.         $i = 0;
  487.         while ( $i < count( $cnodekeys ) ) {
  488.             $cnodekey = strtolower( $cnodekeys[$i] );
  489.             $cnodeval = rawurldecode( strtolower( $cnodevals[$i] ) );
  490.             if ( ( is_string( $cnodekey ) ) ) {
  491.                if ( false !== ( bool )preg_match( "/$_cookie_blacklist/i", ( $cnodeval ) ) ) {
  492.                   $r = "osC_Sec detected a banned \$_Cookie string: " . $cnodekey . "=" . $cnodeval;
  493.                   $this->banChecker( $r, true );
  494.                   return;
  495.                }
  496.             }
  497.             $i++;
  498.         }
  499.     }
  500.     /**
  501.      * injectionMatch()
  502.      *
  503.      * @param mixed $string
  504.      * @return
  505.      */
  506.     function injectionMatch( $string ) {
  507.       $string = $this->url_decoder( $string );
  508.       $string = preg_replace( "/[^\w\s\p{L}\d\r?,(=@%:{}\/.-]/i", "", $this->url_decoder( $string ) ); // urldecode twice
  509.       $string = strtolower( $string );
  510.       $string = str_replace( "//", " ", $string );
  511.       $sqlmatchlist = "(?:abs|ascii|base64|bin|benchmark|cast|chr|char|charset|collation|concat|concat_ws|
  512.                        conv|convert|count|curdate|database|date|decode|diff|distinct|elt|encode|encrypt|
  513.                        extract|field|floor|format|hex|if|in|insert|instr|interval|lcase|left|
  514.                        length|load_file|locate|lock|log|lower|lpad|ltrim|max|md5|mid|mod|name|now|
  515.                        null|ord|password|position|quote|rand|repeat|replace|reverse|right|rlike|
  516.                        round|row_count|rpad|rtrim|_set|schema|sha1|sha2|sleep|soundex|space|strcmp|
  517.                        substr|substr_index|substring|sum|time|trim|truncate|ucase|unhex|upper|
  518.                        _user|user|values|varchar|version|while|xor)\(|\(0x|0x|@@|cast|integer";
  519.                         $sqlmatchlist = preg_replace( "/[\s]/i", "", $sqlmatchlist );
  520.      
  521.       $sqlupdatelist = "\bcolumn\b|\bdata\b|concat\(|\bemail\b|\blogin\b|\bname\b|\bpass\b|sha1|sha2|\btable\b|\bwhere\b|\buser\b|\bval\b|0x";
  522.      
  523.       if ( false !== ( bool )preg_match( "/\bdrop\b/i", $string )
  524.           && false !== ( bool )preg_match( "/\btable\b|\buser\b/i", $string )
  525.           && false !== ( bool )preg_match( "/--|\//i", $string ) ) {
  526.             return true;
  527.       } elseif ( ( false !== strpos( $string, "grant" ) )
  528.               && ( false !== strpos( $string, "all" ) )
  529.               && ( false !== strpos( $string, "privileges" ) ) ) {
  530.             return true;
  531.       } elseif ( false !== preg_match_all( "/\bload\b|\bdata\b|\binfile\b|\btable\b|\bterminated\b/i", $string, $matches ) > 3 ) {
  532.             return true;
  533.       } elseif ( ( ( false !== ( bool )preg_match( "/select|declare/i", $string ) )
  534.         && ( ( false !== ( bool )preg_match( "/\band\b/i", $string ) )
  535.         || ( false !== ( bool )preg_match( "/\bif\b/i", $string ) ) )
  536.         && ( false !== preg_match( "/$sqlmatchlist/", $string ) ) ) ) {
  537.             return true;
  538.       } elseif ( false !== preg_match_all( "/$sqlmatchlist/", $string, $matches ) > 1 ) {
  539.             return true;
  540.       } elseif ( false !== strpos( $string, "update" ) && false !== ( bool )preg_match( "/\bset\b/i", $string )
  541.             && ( false !== ( bool )preg_match( "/$sqlupdatelist/i", $string ) ) ) {
  542.             return true;
  543.       # tackle the noDB / js issue
  544.      } elseif ( ( substr_count( $string, "var" ) > 1 ) && ( false !== ( bool )preg_match( "/date\(|while\(|sleep\(/i", $string ) ) ) {
  545.             return true;
  546.       }
  547.       $string = preg_replace( "/$this->_whitelistpattern/i", "", $string );
  548.       $sqlmatchlist = "_and|ascii|b(?:enchmark|etween|in|itlength|ulk)|c(?:ast|har|ookie|ollate|oncat|urrent)|\bdate\b|dump|
  549.                       e(?:lt|xport)|false|\bfield\b|fetch|format|function|\bhaving\b|i(?:dentity|nforma|nstr)|\bif\b|\bin\b|
  550.                       l(?:case|eft|ength|ike|imit|oad|ocate|ower|pad|trim)|join|m(:?ake|atch|d5|id)|not_like|not_regexp|order|outfile|
  551.                       p(?:ass|ost|osition|riv)|\bquote\b|\br(?:egexp\b|ename\b|epeat\b|eplace\b|equest\b|everse\b|eturn\b|ight\b|like\b|pad\b|trim\b)|
  552.                       \bs(?:ql\b|hell\b|trcmp\b|ubstr\b)|\bt(?:able\b|rim\b|rue\b|runcate\b)|u(?:case|nhex|pdate|pper|ser)|
  553.                       values|varchar|\bwhen\b|where|with|0x|_(?:decrypt|encrypt|get|post|server|cookie|global|or|request|xor)|
  554.                       (?:column|db|load|not|octet|sql|table|xp)_";
  555.                       $sqlmatchlist = preg_replace( "/[\s]/i", "", $sqlmatchlist );
  556.       if ( false !== strpos( $string, "by" )
  557.           && ( false !== ( bool )preg_match( "/\border\b|\bgroup\b/i", $string ) )
  558.           && ( false !== ( bool )preg_match( "/\bcolumn\b|\bdesc\b|\berror\b|\bfrom\b|hav|\blimit\b|\boffset\b|\btable\b|\/|--/i", $string )
  559.           || ( false !== ( bool )preg_match( "/\b[0-9]\b/i", $string ) ) ) ) {
  560.             return true;
  561.       } elseif ( ( false !== ( bool )preg_match( "/\btable\b|\bcolumn\b/i", $string  ) ) && false !== strpos( $string, "exists" )
  562.           && ( false !== ( bool )preg_match( "/\bif\b|\berror\b|\buser\b|\bno\b/i", $string ) ) ) {
  563.             return true;
  564.       } elseif ( ( ( false !== strpos( $string, "waitfor" ) && false !== strpos( $string, "delay" ) && ( ( bool )preg_match( "/(:)/i", $string ) ) )
  565.           || false !== strpos( $string, "nowait" ) )
  566.           && ( false !== ( bool )preg_match( "/--|\/|\blimit\b|\bshutdown\b|\bupdate\b|\bdesc\b/i", $string ) ) ) {
  567.             return true;
  568.       } elseif ( false !== ( bool )preg_match( "/\binto\b/i", $string )
  569.           && ( false !== ( bool )preg_match( "/\boutfile\b/i", $string ) ) ) {
  570.             return true;
  571.       } elseif ( false !== ( bool )preg_match( "/\bdrop\b/i", $string )
  572.           && ( false !== ( bool )preg_match( "/\buser\b/i", $string ) ) ) {
  573.             return true;
  574.       } elseif ( ( ( false !== strpos( $string, "create" ) && false !== ( bool )preg_match( "/\btable\b|\buser\b|\bselect\b/i", $string ) )
  575.           || ( false !== strpos( $string, "delete" ) && false !== strpos( $string, "from" ) )
  576.           || ( false !== strpos( $string, "insert" ) && ( false !== ( bool )preg_match( "/\bexec\b|\binto\b|from/i", $string ) ) )
  577.           || ( false !== strpos( $string, "select" ) && ( false !== ( bool )preg_match( "/\bby\b|\bcase\b|from|\bif\b|\binto\b|\bord\b|union/i", $string ) ) ) )
  578.           && ( ( false !== ( bool )preg_match( "/$sqlmatchlist/i", $string ) ) || ( 2 < substr_count( $string, "," ) ) ) ) {
  579.             return true;
  580.       } elseif ( false !== strpos( $string, "null" ) ) {
  581.             $nstring = preg_replace( "/[^a-z]/i", "", $this->url_decoder( $string ) );
  582.             if ( false !== ( bool )preg_match( "/(null){2,}/i", $nstring ) ) {
  583.                 return true;
  584.             } else return false;
  585.       } else return false;
  586.     return false;
  587.     }
  588.     function notemptisarr( $var ) {
  589.        return ( bool )( !empty( $var ) && is_array( $var ) );
  590.     }
  591.     /**
  592.      * htaccessbanip()
  593.      *
  594.      * @param mixed $banip
  595.      * @return
  596.      */
  597.     function htaccessbanip( $banip ) {
  598.         if ( false === $this->byPass() ) return;
  599.         if ( !isset( $this->_htaccessfile ) ) return $this->senda403Header();
  600.         $limitend = "# End of $this->_httphost Osc_Sec Ban\n";
  601.         $newline = "deny from $banip\n";
  602.         if ( file_exists( $this->_htaccessfile ) ) {
  603.             $mybans = file( $this->_htaccessfile );
  604.             $lastline = "";
  605.             if ( in_array( $newline, $mybans ) ) exit();
  606.             if ( in_array( $limitend, $mybans ) ) {
  607.                 $i = count( $mybans ) - 1;
  608.                 while ( $mybans[$i] != $limitend ) {
  609.                     $lastline = array_pop( $mybans ) . $lastline;
  610.                     $i--;
  611.                 }
  612.                 $lastline = array_pop( $mybans ) . $lastline;
  613.                 $lastline = array_pop( $mybans ) . $lastline;
  614.                 array_push( $mybans, $newline, $lastline );
  615.             } else {
  616.                 array_push( $mybans, "\n\n# $this->_httphost Osc_Sec Ban\n", "order allow,deny\n", $newline,
  617.                     "allow from all\n", $limitend );
  618.             }
  619.         } else {
  620.             $mybans = array( "# $this->_httphost Osc_Sec Ban\n", "order allow,deny\n", $newline, "allow from all\n", $limitend );
  621.         }
  622.         if ( ini_get( 'allow_url_fopen' ) == 1 ) @ini_set( 'allow_url_fopen', '0' );
  623.         if ( ini_get( 'allow_url_include' ) == 1 ) @ini_set( 'allow_url_include', '0' );
  624.         $myfile = fopen( $this->_htaccessfile, "w" );
  625.         fwrite( $myfile, implode( $mybans, "" ) );
  626.         fclose( $myfile );
  627.     }
  628.     /**
  629.      * ipTrapped()
  630.      *
  631.      * @return
  632.      */
  633.     function ipTrapped() {
  634.         if ( false !== $this->_useIPTRAP ) {
  635.             # if IP is already in IP Trap list then redirect
  636.            $mybans = file( $this->_ipTrappedURL );
  637.             if ( false === $mybans ) return false;
  638.             $mybans = array_values( $mybans );
  639.             foreach ( $mybans as $i => $value ) {
  640.                 if ( strlen( $mybans[$i] > 0 ) ) {
  641.                     # find IP address in IP Trap ban list
  642.                    if ( false !== strpos( $mybans[$i], $this->getRealIP() ) ) {
  643.                         $this->_emailenabled = 0;
  644.                         return true;
  645.                     }
  646.                 }
  647.             }
  648.         }
  649.         return false;
  650.     }
  651.    
  652.     function setIPTrapBlocked( $ipTrapBlocked ) {
  653.       if ( false !== ( bool )$this->fINT( $this->_useIPTRAP ) ) {
  654.          if ( false !== $this->fURL( $ipTrapBlocked )
  655.              && false !== strpos( $ipTrapBlocked, "blocked.php" ) ) {
  656.              $this->_ipTrapBlocked = $ipTrapBlocked;
  657.          } else {
  658.              $this->_ipTrapBlocked = false;
  659.          }
  660.       }
  661.     }
  662.     /**
  663.      * my_array_filter_fn()
  664.      *
  665.      * @param mixed $val
  666.      * @return
  667.      */
  668.     function my_array_filter_fn( $val ) {
  669.         $val = trim( $val );
  670.         $allowed_vals = array( "0" );
  671.         return in_array( $val, $allowed_vals, true ) ? true : ( $val ? true : false );
  672.     }
  673.     /**
  674.      * ipTrapban()
  675.      *
  676.      * @param mixed $banip
  677.      * @return
  678.      */
  679.     function ipTrapban( $banip ) {
  680.         if ( false === $this->byPass() ) return;
  681.         $bannedAlready = false;
  682.         $limitend = "\n";
  683.         $newline = "$banip";
  684.         if ( file_exists( $this->_ipTrappedURL ) ) {
  685.             $mybans = file( $this->_ipTrappedURL );
  686.             $lastline = "";
  687.             $mybans = array_filter( $mybans, array( "osC_Sec", "my_array_filter_fn" ) );
  688.             $mybans = array_values( $mybans );
  689.             $endIPTrapIP = "999.999.999.999";
  690.             foreach ( $mybans as $i => $value ) {
  691.                 if ( strlen( $mybans[$i] > 0 ) ) {
  692.                     if ( false !== strpos( $mybans[$i], $newline ) ) $bannedAlready = true;
  693.                 }
  694.             }
  695.             foreach ( $mybans as $i => $value ) {
  696.                 if ( false !== strpos( $mybans[$i], " " ) ) $mybans[$i] = preg_replace( "/[\s\r\n]/i", "", $mybans[$i] );
  697.                 if ( ( false === ( bool )preg_match( "`[\r\n]`", $mybans[$i] ) ) ) $mybans[$i] = $mybans[$i] . "\n";
  698.             }
  699.             if ( false !== ( bool )$bannedAlready ) {
  700.                 if ( ini_get( 'allow_url_fopen' ) == 1 ) @ini_set( 'allow_url_fopen', '0' );
  701.                 if ( ini_get( 'allow_url_include' ) == 1 ) @ini_set( 'allow_url_include', '0' );
  702.                 $myfile = fopen( $this->_ipTrappedURL, "w" );
  703.                 fwrite( $myfile, implode( $mybans, "" ) );
  704.                 fclose( $myfile );
  705.             }
  706.             if ( false === ( bool )$bannedAlready ) {
  707.                 if ( ( false !== strpos( $mybans[$i], $endIPTrapIP ) ) ) unset( $mybans[$i] );
  708.                 if ( in_array( $limitend, $mybans ) ) {
  709.                     $i = count( $mybans ) - 1;
  710.                     while ( $mybans[$i] != $limitend ) {
  711.                         $lastline = array_pop( $mybans ) . $lastline;
  712.                         $i--;
  713.                     }
  714.                     array_push( $mybans, $newline, $endIPTrapIP );
  715.                 } else {
  716.                     array_push( $mybans, "\n", $newline, $endIPTrapIP );
  717.                 }
  718.             } else {
  719.                 if ( false === ( bool )$bannedAlready ) {
  720.                     $mybans = array( "\n", $newline, $endIPTrapIP );
  721.                 }
  722.             }
  723.             if ( false === ( bool )$bannedAlready ) {
  724.                 $mybans = array_filter( $mybans, array( "osC_Sec", "my_array_filter_fn" ) );
  725.                 $mybans = array_values( $mybans );
  726.                 $i = 0;
  727.                 foreach ( $mybans as $i => $value ) {
  728.                     if ( false !== strpos( $mybans[$i], " " ) ) $mybans[$i] = str_replace( " ", "", $mybans[$i] );
  729.                     if ( ( false === ( bool )preg_match( "`[\r\n]`", $mybans[$i] ) ) ) $mybans[$i] = $mybans[$i] . "\n";
  730.                 }
  731.                 if ( ini_get( 'allow_url_fopen' ) == 1 ) @ini_set( 'allow_url_fopen', '0' );
  732.                 if ( ini_get( 'allow_url_include' ) == 1 ) @ini_set( 'allow_url_include', '0' );
  733.                 $myfile = fopen( $this->_ipTrappedURL, "w" );
  734.                 fwrite( $myfile, implode( $mybans, "" ) );
  735.                 fclose( $myfile );
  736.             }
  737.         }
  738.     }
  739.     /**
  740.      * hCoreFileChk()
  741.      *
  742.      * @param mixed $filename
  743.      * @return
  744.      */
  745.     function hCoreFileChk( $filename ) {
  746.         if ( is_writable( $filename ) ) {
  747.             return true;
  748.         }
  749.         return false;
  750.     }
  751.     /**
  752.      * checkfilename()
  753.      *
  754.      * @param mixed $fname
  755.      * @return
  756.      */
  757.     function checkfilename( $fname ) {
  758.       # check for login spoofing ( filename.php/login.php )
  759.        if ( ( !empty( $fname ) )
  760.             && ( substr_count( $fname, ".php" ) == 1 )
  761.             && ( ".php" == substr( $fname, -4 ) ) ) {
  762.             if ( ( ( strlen( $fname ) ) - ( strpos( $fname, "." ) ) ) <> 4 ) {
  763.                 return false;
  764.             } elseif ( ( false !== is_readable( $fname ) )
  765.                       || ( false !== strpos( $_SERVER[ "SCRIPT_NAME" ], "ext/modules/" ) ) ) return true;
  766.         } else return false;
  767.         return false;
  768.     }
  769.     /**
  770.      * phpSelfFix()
  771.      *
  772.      * @return
  773.      */
  774.     function phpSelfFix() {
  775.         global $PHP_SELF;
  776.         if ( false !== ( bool )ini_get( "register_globals" ) || ( !isset( $HTTP_SERVER_VARS ) ) ) $HTTP_SERVER_VARS = $_SERVER;
  777.         $filename = NULL;
  778.         # this is the RC3 standard code
  779.        $filename = ( ( ( strlen( ini_get( "cgi.fix_pathinfo" ) ) > 0 )
  780.                      && ( ( bool )ini_get( "cgi.fix_pathinfo" ) == false ) )
  781.                      || !isset( $HTTP_SERVER_VARS[ "SCRIPT_NAME" ] ) ) ?
  782.                      basename( $HTTP_SERVER_VARS[ "PHP_SELF" ] ) :
  783.                      basename( $HTTP_SERVER_VARS[ "SCRIPT_NAME" ] );
  784.                     if ( false === $this->checkfilename( $filename ) ) {
  785.                         $filename = NULL;
  786.                     } else return $filename;
  787.  
  788.         # if RC3 fails then try a version of FWR Media's $PHP_SELF code.
  789.        if ( empty( $filename ) && ( false !== strpos( $_SERVER[ "SCRIPT_NAME" ], ".php" ) ) ) {
  790.             preg_match( "@[a-z0-9_]+\.php@i", $_SERVER[ "SCRIPT_NAME" ], $matches );
  791.             if ( is_array( $matches ) && ( array_key_exists( 0, $matches ) )
  792.                 && ( substr( $matches[0], -4, 4 ) == ".php" )
  793.                 && ( is_readable( $matches[0] )
  794.                 || ( false !== strpos( $_SERVER[ "SCRIPT_NAME" ], "ext/modules/" ) ) ) ) {
  795.                 $filename = $matches[0];
  796.             }
  797.             if ( false === $this->checkfilename( $filename ) ) {
  798.                 $filename = NULL;
  799.             } else return $filename;
  800.         }
  801.  
  802.         # if that fails then try osC_Sec $PHP_SELF code
  803.        if ( empty( $filename ) && isset( $_SERVER[ "SCRIPT_FILENAME" ] ) && ( "" !== $_SERVER[ "SCRIPT_FILENAME" ] ) ) {
  804.             $tmp = explode( "/", $_SERVER[ "SCRIPT_FILENAME" ] );
  805.             if ( is_array( $tmp ) ) {
  806.                 $filename = $tmp[count( $tmp ) - 1];
  807.             }
  808.             if ( false !== $this->checkfilename( $filename ) ) {
  809.                 return $filename;
  810.             }
  811.         } elseif ( ( $_SERVER[ "PHP_SELF" ] == "/" ) || ( $_SERVER[ "SCRIPT_NAME" ] == "/" ) ) {
  812.          return "index.php";
  813.         } else die(); // prevent the page from executing
  814.     }
  815.     /**
  816.      * array_flatten()
  817.      *
  818.      * @param mixed $array
  819.      * @param bool $preserve_keys
  820.      * @return
  821.      */
  822.     function array_flatten( $array, $preserve_keys = false ) {
  823.       if ( !$preserve_keys ) {
  824.           $array = array_values( $array );
  825.       }
  826.       $flattened_array = array();
  827.       foreach ( $array as $k => $v ) {
  828.           if ( is_array( $v ) ) {
  829.               $flattened_array = array_merge( $flattened_array, $this->array_flatten( $v, $preserve_keys ) );
  830.           } elseif ( $preserve_keys ) {
  831.               $flattened_array[ $k ] = $v;
  832.           } else {
  833.               $flattened_array[] = $v;
  834.           }
  835.       }
  836.       return $flattened_array;
  837.     }
  838.  
  839.     /**
  840.      * byPass()
  841.      *
  842.      * @return
  843.      */
  844.     function byPass() {
  845.         $_PHP_SELF = $this->phpSelfFix();
  846.        
  847.         $filename_bypass = array();
  848.         $dir_bypass = array();
  849.         $exfrmBanlist = array();
  850.  
  851.         # list of files to bypass. I have added a few for consideration. Try to keep this list short
  852.        $filename_bypass = array( "sitemonitor", "protx_process.php", "dps_pxpay_result_handler.php",
  853.                                   "ipn.php", "express_payflow.php", "quickpay.php" );
  854.        
  855.         # bypass all files in a directory. Use this sparingly
  856.        $dir_bypass = array( "/ext/modules/payment" );
  857.  
  858.         # list of IP exceptions. Add bypass ips and uncomment for use
  859.        # $exfrmBanlist = array( '', '', '' );
  860.        
  861.         $realip = $this->getRealIP();
  862.         if ( false === empty( $exfrmBanlist ) ) {
  863.           foreach ( $exfrmBanlist as $exCeptions ) {
  864.               if ( false !== ( strlen( $realip ) == strlen( $exCeptions ) )
  865.                   && ( false !== strpos( $realip, $exCeptions ) ) ) {
  866.                   return false;
  867.               }
  868.           }
  869.         }
  870.         if ( false === empty( $filename_bypass ) ) {
  871.           foreach ( $filename_bypass as $filename ) {
  872.               if ( false !== strpos( $_PHP_SELF, $filename ) ) {
  873.                   return false;
  874.               }
  875.           }
  876.         }
  877.         if ( false === empty( $dir_bypass ) ) {
  878.           foreach ( $dir_bypass as $dirname ) {
  879.               if ( false !== strpos( $_SERVER[ "SCRIPT_NAME" ], $dirname ) ) {
  880.                   return false;
  881.               }
  882.           }
  883.         }
  884.         return true;
  885.     }
  886.     /**
  887.      * checkReqType()
  888.      *
  889.      * @return
  890.      */
  891.     function checkReqType() {
  892.         if ( false === $this->byPass() || ( false === $this->_nonGETPOSTReqs ) ) return;
  893.         $reqType = $_SERVER[ "REQUEST_METHOD" ];
  894.         $req_whitelist = array( "GET", "OPTIONS", "HEAD", "POST" );
  895.         # first check for numbers in REQUEST_METHOD
  896.        if ( false !== ( bool )preg_match( "/[0-9]+/", $reqType ) ) {
  897.             $r = " Request method [ " . $_SERVER[ "REQUEST_METHOD" ] .
  898.                 " ] should not contain numbers. ";
  899.             $this->banChecker( $r, true );
  900.         }
  901.         # then make sure its all UPPERCASE (for servers that do not filter the case of the request method)
  902.        if ( false === ctype_upper( $reqType ) ) {
  903.             $r = " Request method [ " . $_SERVER[ "REQUEST_METHOD" ] .
  904.                 " ] should be in all uppercase letters. ";
  905.             $this->banChecker( $r, true );
  906.             # lastly check against the whitelist
  907.        } elseif ( false === in_array( $reqType, $req_whitelist ) ) {
  908.             $r = " Request method [ " . $_SERVER[ "REQUEST_METHOD" ] .
  909.                 " ] is neither GET, OPTIONS, HEAD or POST. ";
  910.             $this->banChecker( $r, true );
  911.         }
  912.     }
  913.     /**
  914.      * chkSetup()
  915.      *
  916.      * @return
  917.      */
  918.     function chkSetup() {
  919.         # Make sure $banipaddress and $useIPTRAP are not both activated at the same time
  920.        if ( ( $this->_banipaddress ) && ( $this->_useIPTRAP ) ) die( "<p align=center><font face=verdana size=1>" .
  921.                 "<strong>WARNING</strong>: Choose either \$banipaddress or \$useIPTRAP, not both thanks.</font></p>" );
  922.         # if using IPTrap, Make sure $ipTrapBlocked is set
  923.        if ( ( $this->_useIPTRAP ) && ( false === $this->_ipTrapBlocked ) ) die( "<p align=center><font face=verdana size=1>" .
  924.                 "<strong>WARNING</strong>: Check the \$ipTrapBlocked url to the IP Trap blocked.php file in the osc.php file for errors.<br />".
  925.                 "\$ipTrapBlocked cannot be left empty if IP Trap is enabled. If not empty then check that the URL is correct." );
  926.     }
  927.     /**
  928.      * getDir()
  929.      *
  930.      * @return
  931.      */
  932.     function getDir() {
  933.         if ( ( defined( "DIR_FS_CATALOG" ) ) && ( "/" !== substr( DIR_FS_CATALOG, -1 ) ) ) {
  934.             return DIR_FS_CATALOG . "/";
  935.         } elseif ( defined( "DIR_FS_CATALOG" ) ) {
  936.             return DIR_FS_CATALOG;
  937.         } elseif ( !defined( "DIR_FS_CATALOG" ) ) {
  938.             $rootDir = $_SERVER[ "SCRIPT_NAME" ];
  939.             if ( false !== strpos( $rootDir, "/" ) ) {
  940.                 if ( $rootDir[0] == "/" ) {
  941.                     $rootDir = substr( $rootDir, 1 );
  942.                     $pos = strpos( strtolower( $rootDir ), strtolower( "/" ) );
  943.                     $pos += strlen( "." ) - 1;
  944.                     $rootDir = substr( $rootDir, 0, $pos );
  945.                     if ( "/" !== substr( $rootDir, -1 ) ) $rootDir = "/" . $rootDir . "/";
  946.                 }
  947.             }
  948.             $dirFS = $_SERVER[ "DOCUMENT_ROOT" ] . $rootDir;
  949.             while ( ( false !== strpos( $dirFS, "//" ) ) ) {
  950.                 $dirFS = str_replace( "//", "/", $dirFS );
  951.             }
  952.            return $dirFS;
  953.         }
  954.     }
  955.     /**
  956.      * check_ip()
  957.      *
  958.      * @param mixed $ip
  959.      * @return
  960.      */
  961.     function check_ip( $ip ) {
  962.       # simple ip format check
  963.      if ( function_exists( 'filter_var' )
  964.           && defined( 'FILTER_VALIDATE_IP' )
  965.           && defined( 'FILTER_FLAG_IPV4' )
  966.           && defined( 'FILTER_FLAG_IPV6' ) ) {
  967.           if ( filter_var( $ip, FILTER_VALIDATE_IP,
  968.                                 FILTER_FLAG_IPV4 ||
  969.                                 FILTER_FLAG_IPV6 ) === false ) {
  970.                                 return $this->senda403Header();
  971.           } else return true;
  972.       }
  973.       if ( preg_match( '/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/', $ip ) ) {
  974.         $parts = explode( '.', $ip );
  975.  
  976.         foreach ( $parts as $ip_parts ) {
  977.           if ( !is_numeric( $ip_parts ) || ( ( int )( $ip_parts ) > 255 ) || ( ( int )( $ip_parts ) < 0 ) ) {
  978.              return $this->senda403Header();
  979.           }
  980.         }
  981.         return true;
  982.       } else return false;
  983.     }
  984.    
  985.     /**
  986.      * getRealIP()
  987.      *
  988.      * @return
  989.      */
  990.     function getRealIP() {
  991.       global $_SERVER;
  992.       $ip_addresses = array();
  993.       if ( isset( $_SERVER ) ) {
  994.       // check for IPs passing through proxies
  995.       if ( !empty( $_SERVER[ 'HTTP_X_FORWARDED_FOR' ] ) ) {
  996.        // check if multiple ips exist in var
  997.         $iplist = explode( ',', $_SERVER[ 'HTTP_X_FORWARDED_FOR' ] );
  998.         foreach ( $iplist as $ip ) {
  999.          if ( $this->check_ip( $ip ) )
  1000.           $HTTP_X_FORWARDED_FOR = $ip;
  1001.         }
  1002.        }
  1003.       }
  1004.       if ( ( !empty( $_SERVER[ 'HTTP_CLIENT_IP' ] ) && false !== $this->check_ip( $_SERVER[ 'HTTP_CLIENT_IP' ] ) )
  1005.         || ( !empty( $HTTP_X_FORWARDED_FOR ) && false !== $this->check_ip( $HTTP_X_FORWARDED_FOR ) )
  1006.         || ( !empty( $_SERVER[ 'HTTP_X_FORWARDED' ] ) && false !== $this->check_ip( $_SERVER[ 'HTTP_X_FORWARDED' ] ) )
  1007.         || ( !empty( $_SERVER[ 'HTTP_PROXY_USER' ] ) && false !== $this->check_ip( $_SERVER[ 'HTTP_PROXY_USER' ] ) )
  1008.         || ( !empty( $_SERVER[ 'HTTP_X_CLUSTER_CLIENT_IP' ] ) && false !== $this->check_ip( $_SERVER[ 'HTTP_X_CLUSTER_CLIENT_IP' ] ) )
  1009.         || ( !empty( $_SERVER[ 'HTTP_FORWARDED' ] ) && false !== $this->check_ip( $_SERVER[ 'HTTP_FORWARDED' ] ) )
  1010.         || ( !empty( $_SERVER[ 'HTTP_CF_CONNECTING_IP' ] ) && false !== $this->check_ip( $_SERVER[ 'HTTP_CF_CONNECTING_IP' ] ) )
  1011.         || ( !empty( $_SERVER[ 'HTTP_FORWARDED_FOR' ] ) && false !== $this->check_ip( $_SERVER[ 'HTTP_FORWARDED_FOR' ] ) ) ) {
  1012.                # just disable the ban IP function so as not to
  1013.               # accidentally ban an upstream proxy server
  1014.               # however osC_Sec can still block any
  1015.               # malicious requests irregardless
  1016.               $this->_banipaddress = 0;
  1017.                $this->_useIPTRAP = 0;
  1018.       }
  1019.       return ( false !== $this->check_ip( $_SERVER[ "REMOTE_ADDR" ] ) ) ? $_SERVER[ "REMOTE_ADDR" ] : $this->senda403Header();
  1020.     }
  1021.     function fINT( $integ ) {
  1022.      # check input is an integer and no lower than 0 in value
  1023.      if ( function_exists( 'filter_var' ) && defined( 'FILTER_SANITIZE_NUMBER_INT' ) ) {
  1024.              $integ_filtered = ( int )filter_var( $integ, FILTER_SANITIZE_NUMBER_INT );
  1025.              if ( isset( $integ )
  1026.                  && $integ_filtered
  1027.                  && is_int( $integ_filtered )
  1028.                  && 0 <= $integ_filtered ) {
  1029.                return $integ_filtered;
  1030.              } else return 0;
  1031.       } elseif ( isset( $integ )
  1032.                  && 0 <= ( int )$integ ) {
  1033.                return ( int )$integ;
  1034.       } else return 0;
  1035.     }
  1036.     function fURL( $url ) {
  1037.      # check input is an integer and no lower than 0 in value
  1038.      if ( function_exists( 'filter_var' ) && defined( 'FILTER_SANITIZE_URL' ) ) {
  1039.              $url_filtered = filter_var( $url, FILTER_SANITIZE_URL );
  1040.       }
  1041.       if ( isset( $url_filtered ) ) {
  1042.         if ( preg_match( "#^http(s)?://[a-z0-9-_.]+\.[a-z]{2,4}#i", $url ) ) {
  1043.             return $url;
  1044.         } else return false;
  1045.       }
  1046.       return false;
  1047.     }
  1048.     /**
  1049.      * strCharsfrmStr()
  1050.      *
  1051.      * @param mixed $string
  1052.      * @param mixed $strip
  1053.      * @param mixed $replace
  1054.      * @return
  1055.      */
  1056.     function strCharsfrmStr( $string, $strip, $replace ) {
  1057.         $x = ( false !== strpos( $string, $strip ) ) ? true : false;
  1058.         while ( false !== $x ) {
  1059.             $string = str_replace( $strip, $replace, $string );
  1060.             $x = ( false !== strpos( $string, $strip ) ) ? true : false;
  1061.         }
  1062.         return $string;
  1063.     }
  1064.     /**
  1065.      * Bad Spider Block
  1066.      */
  1067.     function badArachnid() {
  1068.         if ( false === $this->byPass() ) return;
  1069.         if ( isset( $_SERVER[ "HTTP_USER_AGENT" ] ) ) {
  1070.           $badagentlist = array( "Baidu", "WebLeacher", "autoemailspider", "MSProxy", "Yeti", "Twiceler", "blackhat", "Mail.Ru", "fuck" );
  1071.           $lcUserAgent = strtolower( $_SERVER[ "HTTP_USER_AGENT" ] );
  1072.           foreach ( $badagentlist as $badagent ) {
  1073.               $badagent = strtolower( $badagent );
  1074.               if ( false !== strpos( $lcUserAgent, $badagent ) ) {
  1075.                   $header = array( "HTTP/1.1 404 Not Found", "HTTP/1.1 404 Not Found", "Content-Length: 0" );
  1076.                   foreach ( $header as $sent ) {
  1077.                       header( $sent );
  1078.                   }
  1079.                   die();
  1080.               }
  1081.           }
  1082.         }
  1083.     }
  1084.     function get_version() {
  1085.        if ( false !== file_exists( $this->getDir() . 'includes/version.php' )
  1086.           && false !== is_readable( $this->getDir() . 'includes/version.php' ) ) {
  1087.           return trim( implode( '', file( $this->getDir() . 'includes/version.php' ) ) );
  1088.        }
  1089.     return false;
  1090.     }
  1091.     function setOpenBaseDir() {
  1092.        if ( false !== $this->get_version()
  1093.           && $this->get_version() == "2.3.1" ) {
  1094.           if ( strlen( ini_get( 'open_basedir' ) == 0 ) ) {
  1095.               return @ini_set( 'open_basedir', $this->getDir() );
  1096.           }
  1097.        }
  1098.     }
  1099.    /**
  1100.     * x_powered_by()
  1101.     */
  1102.     function x_powered_by() {
  1103.        $errlevel = ini_get( 'error_reporting' );
  1104.        error_reporting( 0 );
  1105.        if ( false !== ( bool )ini_get( 'expose_php' ) ) {
  1106.           header( "X-Powered-By: osC_Sec" );
  1107.        }
  1108.        error_reporting( $errlevel );
  1109.     }
  1110.    /**
  1111.     * url_decoder()
  1112.     */
  1113.     function url_decoder( $var ) {
  1114.       return rawurldecode( urldecode( $var ) );
  1115.     }
  1116.   } // end of class
  1117.  
  1118.   /**
  1119.    * osCSec_selfchk()
  1120.    *
  1121.    * @return
  1122.    */
  1123.   function osCSec_selfchk() {
  1124.       $oscsecfilepath = str_replace( DIRECTORY_SEPARATOR, urldecode( "%2F" ), __file__ );
  1125.       $oscsecfilepath = explode( "/", $oscsecfilepath );
  1126.       if ( is_array( $oscsecfilepath ) ) {
  1127.           $fileself = $oscsecfilepath[count( $oscsecfilepath ) - 1];
  1128.           if ( $fileself[0] == "/" ) {
  1129.               return $fileself;
  1130.           } else {
  1131.               return "/" . $fileself;
  1132.           }
  1133.       }
  1134.   }
  1135.   /**
  1136.    * senda404Header()
  1137.    *
  1138.    * @return
  1139.    */
  1140.   function senda404Header() {
  1141.       $header = array( "HTTP/1.1 404 Not Found", "HTTP/1.1 404 Not Found", "Content-Length: 0" );
  1142.       foreach ( $header as $sent ) {
  1143.           header( $sent );
  1144.       }
  1145.       die();
  1146.   }
  1147.  
  1148.  /**
  1149.   * fix_server_vars()
  1150.   *
  1151.   * @return
  1152.   */
  1153.   function fix_server_vars() {
  1154.       $_request_uri = "";
  1155.       if ( empty( $_SERVER[ "REQUEST_URI" ] )
  1156.           || ( php_sapi_name() != "cgi-fcgi"
  1157.               && false !== ( bool )preg_match( "/^Microsoft-IIS\//", $_SERVER[ "SERVER_SOFTWARE" ] ) ) ) {
  1158.           if ( isset( $_SERVER[ "HTTP_X_ORIGINAL_URL" ] ) ) {
  1159.               $_request_uri = $_SERVER[ "HTTP_X_ORIGINAL_URL" ];
  1160.           } else
  1161.               if ( isset( $_SERVER[ "HTTP_X_REWRITE_URL" ] ) ) {
  1162.                   $_request_uri = $_SERVER[ "HTTP_X_REWRITE_URL" ];
  1163.               } else {
  1164.                   if ( !isset( $_SERVER[ "PATH_INFO" ] )
  1165.                       && isset( $_SERVER[ "ORIG_PATH_INFO" ] ) ) $_SERVER[ "PATH_INFO" ] = $_SERVER[ "ORIG_PATH_INFO" ];
  1166.                   if ( isset( $_SERVER[ "PATH_INFO" ] ) ) {
  1167.                       if ( $_SERVER[ "PATH_INFO" ] == $_SERVER[ "SCRIPT_NAME" ] ) {
  1168.                           $_request_uri = $_SERVER[ "PATH_INFO" ];
  1169.                       } else {
  1170.                           $_request_uri = $_SERVER[ "SCRIPT_NAME" ] . $_SERVER[ "PATH_INFO" ];
  1171.                       }
  1172.                   }
  1173.                   if ( !empty( $_SERVER[ "QUERY_STRING" ] ) ) {
  1174.                       $_request_uri .= "?" . $_SERVER[ "QUERY_STRING" ];
  1175.                   }
  1176.               }
  1177.       }
  1178.       if ( false !== getenv( 'REQUEST_URI' ) && strlen( getenv( 'REQUEST_URI' ) ) > 7 ) {
  1179.          $_request_uri = getenv( 'REQUEST_URI' );
  1180.       }
  1181.       $_SERVER[ "REQUEST_URI" ] = $_request_uri;
  1182.       # fix php.cgi in script_filename
  1183.      if ( isset( $_SERVER[ "SCRIPT_FILENAME" ] )
  1184.           && isset( $_SERVER[ "PATH_TRANSLATED" ] )
  1185.           && ( strpos( $_SERVER[ "SCRIPT_FILENAME" ], "php.cgi" ) == strlen( $_SERVER[ "SCRIPT_FILENAME" ] ) - 7 ) ) {
  1186.           $_SERVER[ "SCRIPT_FILENAME" ] = $_SERVER[ "PATH_TRANSLATED" ];
  1187.       }
  1188.   }
  1189. ?>