\"/:|?.# * - if we find a possible extension followed by the end of the string or * a #, that's our extension * - if we find a possible extension followed by a ?, that's our extension * - UNLESS it's exe, dll or cgi, in which case we ignore it and continue * searching for another possible extension * - if we find a possible extension followed by a dot or another illegal * character, we ignore it and continue searching * * @param string $url URL * @return mixed Detected extension (string), or false if none found */ public static function findIE6Extension( $url ) { $pos = 0; $hashPos = strpos( $url, '#' ); if ( $hashPos !== false ) { $urlLength = $hashPos; } else { $urlLength = strlen( $url ); } $remainingLength = $urlLength; while ( $remainingLength > 0 ) { // Skip ahead to the next dot $pos += strcspn( $url, '.', $pos, $remainingLength ); if ( $pos >= $urlLength ) { // End of string, we're done return false; } // We found a dot. Skip past it $pos++; $remainingLength = $urlLength - $pos; // Check for illegal characters in our prospective extension, // or for another dot $nextPos = $pos + strcspn( $url, "<>\\\"/:|?*.", $pos, $remainingLength ); if ( $nextPos >= $urlLength ) { // No illegal character or next dot // We have our extension return substr( $url, $pos, $urlLength - $pos ); } if ( $url[$nextPos] === '?' ) { // We've found a legal extension followed by a question mark // If the extension is NOT exe, dll or cgi, return it $extension = substr( $url, $pos, $nextPos - $pos ); if ( strcasecmp( $extension, 'exe' ) && strcasecmp( $extension, 'dll' ) && strcasecmp( $extension, 'cgi' ) ) { return $extension; } // Else continue looking } // We found an illegal character or another dot // Skip to that character and continue the loop $pos = $nextPos; $remainingLength = $urlLength - $pos; } return false; } /** * When passed the value of $_SERVER['SERVER_SOFTWARE'], this function * returns true if that server is known to have a REQUEST_URI variable * with %2E not decoded to ".". On such a server, it is possible to detect * whether the script filename has been obscured. * * The function returns false if the server is not known to have this * behavior. Microsoft IIS in particular is known to decode escaped script * filenames. * * SERVER_SOFTWARE typically contains either a plain string such as "Zeus", * or a specification in the style of a User-Agent header, such as * "Apache/1.3.34 (Unix) mod_ssl/2.8.25 OpenSSL/0.9.8a PHP/4.4.2" * * @param $serverSoftware * @return bool * */ public static function haveUndecodedRequestUri( $serverSoftware ) { static $whitelist = array( 'Apache', 'Zeus', 'LiteSpeed' ); if ( preg_match( '/^(.*?)($|\/| )/', $serverSoftware, $m ) ) { return in_array( $m[1], $whitelist ); } else { return false; } } }