require 'support/shared_examples_for_issue_checks' RSpec.describe Pluginscan::FileIssuesScanner do ################## # MATCH EXAMPLES # ################## # Most of the following examples come from real pluginscan test runs and # should be considered regression specs: things which we shouldn't fail to match in future! describe "SUPERGLOBAL EXAMPLES" do it_behaves_like "matches a variable assigned to a superglobal", "$_GET" it_behaves_like "matches a variable assigned to a superglobal", "$_POST" it_behaves_like "matches a variable assigned to a superglobal", "$_SERVER" it_behaves_like "matches a variable assigned to a superglobal", "$_REQUEST" it_behaves_like "matches a variable assigned to a superglobal", "$_COOKIE" it_behaves_like "matches a variable assigned to a superglobal", "$_ENV" it_behaves_like "matches a variable assigned to a superglobal", "$_FILES" # Should be looked at: it_behaves_like "matches lines containing", "$_POST", %($contact_form->set_title( $_POST['wpcf7-title'] );) it_behaves_like "matches lines containing", "$_POST", %($locale = trim( $_POST['wpcf7-locale'] );) it_behaves_like "matches lines containing", "$_POST", %($properties['form'] = trim( $_POST['wpcf7-form'] );) it_behaves_like "matches lines containing", "$_POST", %($id = $_POST['post_ID'];) it_behaves_like "matches lines containing", "$_REQUEST", %(return $_REQUEST['action'];) it_behaves_like "matches lines containing", "$_POST", %($submitted = isset( $_POST[$tagname] ) ? $_POST[$tagname] : '';) it_behaves_like "matches lines containing", "$_POST", %($value = $_POST[$fe['name']];) it_behaves_like "matches lines containing", "$_REQUEST", %($replaced_login = str_replace('%user_login%', $_REQUEST['user_login'], $email);) it_behaves_like "matches lines containing", "$_REQUEST", %($replaced_all = str_replace('%pass1%', $_REQUEST['pass1'], $replaced_login);) it_behaves_like "matches lines containing", "$_SERVER", %($redirect_to = isset( $_SERVER['HTTP_REFERER'] ) ? $_SERVER['HTTP_REFERER'] : admin_url( 'edit-comments.php' );) it_behaves_like "matches lines containing", "$_SERVER", %(return isset( $_SERVER['HTTP_REFERER'] ) ? $_SERVER['HTTP_REFERER'] : null;) it_behaves_like "matches lines containing", "$_REQUEST", %($this->items = MLAMime::mla_query_view_items( $_REQUEST, ( ( $current_page - 1 ) * $per_page ), $per_page );) it_behaves_like "matches lines containing", "$_REQUEST", %q(echo ' - search results for "' . esc_html( stripslashes( trim( $_REQUEST['s'] ) ) ) . "\"\r\n";) it_behaves_like "matches lines containing", "$_GET", %($_GET['order'] = $_REQUEST['order'];) it_behaves_like "matches lines containing", "$_REQUEST", %($_GET['order'] = $_REQUEST['order'];), check_index: 0, match_index: 1 it_behaves_like "matches lines containing", "$_SERVER", %() it_behaves_like "matches lines containing", "$_POST", %() # Should be looked at - but look similar to safe infixes: it_behaves_like "matches lines containing", "$_POST", %('name' => $_POST['EventBriteTicketName'],) it_behaves_like "matches lines containing", "$_POST", %('cost' => $_POST['EventBriteEventCost'] * 100,) # Double check the infixes: there's a risk of false negatives due to double-counting infixes (e.g. == and ===): # NOT SEEN IN THE WILD: it_behaves_like "matches lines containing", "$_GET", %($x = $_GET['message'] <= 1; $y = $_GET['message'] ) it_behaves_like "matches lines containing", "$_GET", %($x = $_GET['message'] < 1; $y = $_GET['message'] ) it_behaves_like "matches lines containing", "$_GET", %($x = $_GET['message'] > 1; $y = $_GET['message'] ) it_behaves_like "matches lines containing", "$_GET", %($x = $_GET['message'] >= 1; $y = $_GET['message'] ) it_behaves_like "matches lines containing", "$_GET", %($x = $_GET['message'] === 1; $y = $_GET['message'] ) it_behaves_like "matches lines containing", "$_GET", %($x = $_GET['message'] !== 1; $y = $_GET['message'] ) it_behaves_like "matches lines containing", "$_GET", %($x = $_GET['message'] == 1; $y = $_GET['message'] ) it_behaves_like "matches lines containing", "$_GET", %($x = $_GET['message'] != 1; $y = $_GET['message'] ) # Matches because the value ends up in $danger, even though it's used in a check it_behaves_like "matches lines containing", "$_POST", %(if( ($danger = $_POST['post_type']) == 'page') \{) # Requires looking at surrounding lines: it_behaves_like "matches lines containing", "$_POST", %{$_POST['wpcf7-mail-2-additional-headers'] );} # IGNORE: ######### # Ignored because value is checked but not used: it_behaves_like "ignores lines containing", "$_POST", %(if ( isset( $_POST['wpcf7-title'] ) ) \{) it_behaves_like "ignores lines containing", "$_POST", %(if ( ! empty( $_POST['post_ID'] ) )) it_behaves_like "ignores lines containing", "$_POST", %($id = empty( $_POST['post_ID'] )) it_behaves_like "ignores lines containing", "$_POST", %($mail['use_html'] = ! empty( $_POST['wpcf7-mail-use-html'] );) it_behaves_like "ignores lines containing", "$_REQUEST", %(if ( 'created' == $_REQUEST['message'] )) it_behaves_like "ignores lines containing", "$_SERVER", %(if ( 'POST' == $_SERVER['REQUEST_METHOD'] ) \{) it_behaves_like "ignores lines containing", "$_POST", %('message' => ( -1 == $_POST['post_ID'] ) ? 'created' : 'saved',) it_behaves_like "ignores lines containing", "$_SERVER", %(return $_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest';) it_behaves_like "ignores lines containing", "$_GET", %(if ( ! ( isset( $_GET['recheckqueue'] ) || ( isset( $_REQUEST['action'] ) && 'akismet_recheck_queue' == $_REQUEST['action'] ) ) )) it_behaves_like "ignores lines containing", "$_REQUEST", %(if ( isset( $_REQUEST[ $value['value'] ] ) )) it_behaves_like "ignores lines containing", "$_SERVER", %(&& strpos( $_SERVER['REQUEST_URI'], 'wp-admin/update.php' ) !== false) it_behaves_like "ignores lines containing", "$_GET", %(if ($_GET['s'])\{) it_behaves_like "ignores lines containing", "$_POST", %(if ( is_email( $_POST['id_emailaddress'] ) ) \{) it_behaves_like "ignores lines containing", "$_GET", %(if ( intval($_GET['message']) == 1 )\{) it_behaves_like "ignores lines containing", "$_POST", %(if ( !wp_verify_nonce( $_POST['_wpnonce'], self::NONCE ) )) it_behaves_like "ignores lines containing", "$_POST", %($comment = get_comment( intval( $_POST['id'] ), ARRAY_A );) it_behaves_like "ignores lines containing", "$_REQUEST", %(if (wp_verify_nonce($_REQUEST['nonce'], $this->hook . '_ajax-nonce')) \{) it_behaves_like "ignores lines containing", "$_REQUEST", %(return wp_verify_nonce($_REQUEST['nonce'], $this->plugin_slug . '_foolic-ajax-nonce');) it_behaves_like "ignores lines containing", "$_POST", %(if ( ! wp_verify_nonce( $_POST['wp_nonce'], 'BWPS_admin_save' ) || ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ) || ( $_POST['post_type'] == 'page' && ! current_user_can( 'edit_page', $id ) ) || ( $_POST['post_type'] == 'post' && ! current_user_can( 'edit_post', $id ) ) ) \{) it_behaves_like "ignores lines containing", "$_POST", %(: absint( $_POST['post_ID'] );) it_behaves_like "ignores lines containing", "$_REQUEST", %(? absint( $_REQUEST['post'] )) it_behaves_like "ignores lines containing", "$_REQUEST", %(unset( $_REQUEST['heading_suffix'] );) it_behaves_like "ignores lines containing", "$_GET", %(switch ( $_GET['page'] ) ) it_behaves_like "ignores lines containing", "$_GET", %{$x = $_GET[eval($danger)] == 1 } # however: it_behaves_like "matches lines containing", "eval", %($x = $_GET[eval($danger)] == 1 ), check_index: 1, match_index: 0 # Ignored because some infixes make superglobals safe: it_behaves_like "ignores lines containing", "$_GET", %($x = $_GET['message'] <= 1 ) it_behaves_like "ignores lines containing", "$_GET", %($x = $_GET['message'] < 1 ) it_behaves_like "ignores lines containing", "$_GET", %($x = $_GET['message'] > 1 ) it_behaves_like "ignores lines containing", "$_GET", %($x = $_GET['message'] >= 1 ) it_behaves_like "ignores lines containing", "$_GET", %($x = $_GET['message'] === 1 ) it_behaves_like "ignores lines containing", "$_GET", %($x = $_GET['message'] !== 1 ) it_behaves_like "ignores lines containing", "$_GET", %($x = $_GET['message'] == 1 ) it_behaves_like "ignores lines containing", "$_GET", %($x = $_GET['message'] != 1 ) it_behaves_like "ignores lines containing", "$_GET", %($x = $_GET['message']<=1 ) it_behaves_like "ignores lines containing", "$_GET", %($x = $_GET['message']<1 ) it_behaves_like "ignores lines containing", "$_GET", %($x = $_GET['message']>1 ) it_behaves_like "ignores lines containing", "$_GET", %($x = $_GET['message']>=1 ) it_behaves_like "ignores lines containing", "$_GET", %($x = $_GET['message']===1 ) it_behaves_like "ignores lines containing", "$_GET", %($x = $_GET['message']!==1 ) it_behaves_like "ignores lines containing", "$_GET", %($x = $_GET['message']==1 ) it_behaves_like "ignores lines containing", "$_GET", %($x = $_GET['message']!=1 ) # Ignored because two values are checked but neither is used: it_behaves_like "ignores lines containing", "$_POST", %(if ( !empty( $_POST['id'] ) && !empty( $_POST['url'] ) && check_admin_referer( 'comment_author_url_nonce' ) ) \{) it_behaves_like "ignores lines containing", "$_REQUEST", %(if ( ! ( isset( $_GET['recheckqueue'] ) || ( isset( $_REQUEST['action'] ) && 'akismet_recheck_queue' == $_REQUEST['action'] ) ) )), check_index: 0, match_index: 1 it_behaves_like "ignores lines containing", "$_POST", %(if ( isset( $_POST['action'] ) && $_POST['action'] == 'enter-key' ) \{) it_behaves_like "ignores lines containing", "$_GET", %(if ( isset( $_GET['page'] ) && 'akismet-stats-display' == $_GET['page'] ) \{) it_behaves_like "ignores lines containing", "$_GET", %(elseif ( isset( $_GET['view'] ) && $_GET['view'] == 'stats' )) it_behaves_like "ignores lines containing", "$_POST", %(( isset( $_POST['comment_status'] ) && in_array( $_POST['comment_status'], array( 'spam', 'unspam' ) ) )) it_behaves_like "ignores lines containing", "$_REQUEST", %(if ( isset( $_REQUEST['action'] ) && -1 != $_REQUEST['action'] )) it_behaves_like "ignores lines containing", "$_REQUEST", %(if ( isset( $_REQUEST['m'] ) && ( '0' != $_REQUEST['m'] ) )) # Ignored because multiple values are checked but none are used: it_behaves_like "ignores lines containing", "$_POST", %(if ( isset( $_POST['action'] ) && ( $_POST['action'] == 'query-attachments' ) && isset( $_POST['query']['s'] ) && is_array( $_POST['query']['s'] ) )\{) # Ignored because in a comment: it_behaves_like "ignores lines containing", "$_REQUEST", %(// ignore anything else in $_REQUEST) it_behaves_like "ignores lines containing", "$_POST", %(// Check group $_POST data) it_behaves_like "ignores lines containing", "$_REQUEST", %(* Initializes some properties from $_REQUEST variables, then) it_behaves_like "ignores lines containing", "$_REQUEST", %(* @param array query parameters from web page, usually found in $_REQUEST) # SHOULD BE ignored because value is checked but not used: it_behaves_like "matches lines containing", "$_GET", %(if ( isset( $_GET['token'] ) && preg_match('/^(\d+)-[0-9a-f]{20}$/', $_GET['token'] ) )) # SHOULD BE ignored because multiple values are checked but none are used it_behaves_like "matches lines containing", "$_REQUEST", %(if ( ! ( isset( $_REQUEST['cmb_ajax_nonce'], $_REQUEST['oembed_url'] ) && wp_verify_nonce( $_REQUEST['cmb_ajax_nonce'], 'ajax_nonce' ) ) ) ) # (should be ignored because in a comment. Actually ignored because in an empty) it_behaves_like "ignores lines containing", "$_REQUEST", %{\} // (!empty($_REQUEST['mla_admin_action'])} # SHOULD BE ignored because value is escaped?: it_behaves_like "matches lines containing", "$_REQUEST", %() it_behaves_like "matches lines containing", "$_REQUEST", %{. '', esc_html( $_REQUEST['s'] ) );} # SHOULD BE ignored because value is sanitized? (Probably not?): it_behaves_like "matches lines containing", "$_REQUEST", %($oembed_string = sanitize_text_field( $_REQUEST['oembed_url'] );) end describe "DATABASE ACCESS EXAMPLES" do it_behaves_like "ignores lines containing", "$wpdb", %(global $wpdb;) it_behaves_like "ignores lines containing", "$wpdb", %($q = "SELECT post_id FROM $wpdb->postmeta WHERE meta_key = '_old_cf7_unit_id'") it_behaves_like "matches lines containing", "$wpdb", %($db = new db_subscribe($wpdb);) it_behaves_like "matches lines containing", "$wpdb", %(strangefunc($wpdb);) it_behaves_like "matches lines containing", "$wpdb", %($foo = $wpdb;) it_behaves_like "matches lines containing", "$wpdb", %(. $wpdb->prepare( " AND meta_value = %d", $old_id );) it_behaves_like "matches lines containing", "$wpdb", %(if ( $new_id = $wpdb->get_var( $q ) )) it_behaves_like "matches lines containing", "$wpdb", %($table_name = $wpdb->prefix . "contact_form_7";) it_behaves_like "matches lines containing", "$wpdb", %($wpdb->query( "DROP TABLE IF EXISTS $table_name" );) it_behaves_like "matches lines containing", "$wpdb", %($key = $wpdb->get_var($wpdb->prepare("SELECT activation_key FROM {$wpdb->signups} WHERE user_login = %s AND user_email = %s", $new_user_login, $_REQUEST['email']));), check_index: 1 end describe "MYSQL EXAMPLES" do # Let's find some real ones!!! # Not seen in the wild: it_behaves_like "matches lines containing", "mysql_foo", %(mysql_foo($evil);) it_behaves_like "matches lines containing", "mysqli_foo", %(mysqli_foo($evil);) end describe "PHP CODE GENERATION FUNCTION EXAMPLES" do it_behaves_like "matches lines containing", "create_function", %q{$pee = preg_replace_callback( '/<(script|style|textarea).*?<\/\\1>/s', create_function( '$matches', 'return str_replace("\n", "", $matches[0]);' ), $pee );} it_behaves_like "matches lines containing", "create_function", %{$function = @create_function('', 'return ' . $value . ';' );} end describe "USER-CONTROLLABLE FUNCTION CALL EXAMPLES" do it_behaves_like "matches lines containing", "call_user_func", %(return $m[1] . call_user_func( $func, $scanned_tag ) . $m[6];) it_behaves_like "matches lines containing", "call_user_func", %(return is_array( $value ) ? array_map( 'sanitize_text_field', $value ) : call_user_func( 'sanitize_text_field', $value );) end describe "VARIABLE EVALUATION EXAMPLES" do # Not seen in the wild: it_behaves_like "matches lines containing", "parse_str", %(parse_str($_GET['meow']); eval($x);), check_index: 2 it_behaves_like "matches lines containing", "extract", %(extract($var_array, EXTR_PREFIX_SAME, "wddx");) end describe "SYSTEM CALLS:" do # Not actually system commands (??) but potentially dodgy inclusions in SQL? it_behaves_like "matches lines containing", "`post_content`", %(WHERE {$exclude_revisions}(CONVERT(`post_content` USING utf8 ) LIKE %s)", "%{$like}%") it_behaves_like "matches lines containing", "`post_content`", %(CONVERT(`post_content` USING utf8 )) # Ignored because in a comment it_behaves_like "ignores lines containing", "`$saved`", %(// Add to `$saved` array) it_behaves_like "ignores lines containing", "`if`", %(// TODO: should this `if` be in the constructor instead?) end describe "FILE OPERATIONS EXAMPLES" do it_behaves_like "matches lines containing", "unlink", %(@unlink( $dir );) it_behaves_like "matches lines containing", "unlink", %(@unlink( $dir . $file );) it_behaves_like "matches lines containing", "chmod", %(@chmod( $new_file, 0400 );) it_behaves_like "matches lines containing", "chmod", %(elseif ( ! is_writable( MLA_BACKUP_DIR ) && ! @chmod( MLA_BACKUP_DIR , '0777') ) \{) it_behaves_like "matches lines containing", "move_uploaded_file", %(if ( false === @move_uploaded_file( $file['tmp_name'], $new_file ) ) \{) it_behaves_like "matches lines containing", "file_put_contents", %(@file_put_contents( $htaccess_upload, $htaccess_content, LOCK_EX );) it_behaves_like "matches lines containing", "file_put_contents", %(if ( @file_put_contents( $htaccess_upload, $file_rules ) === false )\{) it_behaves_like "matches lines containing", "file_get_contents", %($settings = @file_get_contents( $filename, false );) it_behaves_like "matches lines containing", "file_get_contents", %($object_content = file_get_contents( $file_name, true, NULL, $file_offset, $chunksize );) it_behaves_like "matches lines containing", "rename", %(@rename( $current_datastore_path, $new_datastore_path );) it_behaves_like "matches lines containing", "glob", %($files_found = glob( $directory_pattern );) it_behaves_like "matches lines containing", "unlink", %($removed = @unlink( $filepath );) it_behaves_like "matches lines containing", "file", %(return @file( $filepath, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES );) it_behaves_like "matches lines containing", "fread", %($chunk = fread( $file, $seek );) it_behaves_like "matches lines containing", "fwrite", %(if(false === @fwrite($file_pointer, $settings)) \{) # Note the use of %q here to get around the \n and \\ escaping: it_behaves_like "matches lines containing", "fwrite", %q{fwrite( $handle, 'Order deny,allow' . "\n" );} it_behaves_like "matches lines containing", "fwrite", %q{fwrite( $handle, '' . "\n" );} it_behaves_like "matches lines containing", "fwrite", 'fwrite( $handle, "Deny from all\n" );' it_behaves_like "matches lines containing", "fread", 'if ( fread( $file, 1 ) != "\n" ) { $lines -= 1; }' # IGNORE: ######### # ignored because not actually calling one of the dangerous functions it_behaves_like "ignores lines containing", "copy", %(public function copy() \{) # SHOULD BE ignored because not actually calling one of the dangerous functions it_behaves_like "matches lines containing", "copy", %($new_contact_form = $contact_form->copy();) it_behaves_like "matches lines containing", "file", %($page_content['message'] = "ERROR: reading the settings file ( {$filename} ){$php_errormsg}";) end describe "OBFUSCATION EXAMPLES" do it_behaves_like "matches lines containing", "base64_decode", %($data = base64_decode( $HTTP_RAW_POST_DATA );) end describe "NETWORK FUNCTION EXAMPLES" do it_behaves_like "matches lines containing", "wp_remote_get", %($response = wp_remote_get( $url, $req_args );) it_behaves_like "matches lines containing", "wp_remote_post", %($response = wp_remote_post( $url, $req_args );) it_behaves_like "matches lines containing", "wp_remote_head", %($resp = wp_remote_head( $possible_repository );) end describe "UNSAFE FUNCTION EXAMPLES" do it_behaves_like "matches lines containing", "wp_unslash", %($new_value[] = $pipes->do_pipe( wp_unslash( $v ) );) it_behaves_like "matches lines containing", "wp_unslash", %($value = $pipes->do_pipe( wp_unslash( $value ) );) it_behaves_like "matches lines containing", "wp_unslash", %{$free_text_atts['value'] = wp_unslash(} it_behaves_like "matches lines containing", "wp_unslash", %($answer = wp_unslash( $answer );) it_behaves_like "matches lines containing", "wp_unslash", %($replaced = wp_unslash( trim( $replaced ) );) it_behaves_like "matches lines containing", "htmlspecialchars", %($text = htmlspecialchars( $text );) it_behaves_like "matches lines containing", "wp_unslash", %($new_user_login = apply_filters('pre_user_login', sanitize_user(wp_unslash($_REQUEST['user_login']), true));), check_index: 1 it_behaves_like "matches lines containing", "wp_unslash", %(return isset( $_POST[$name] ) ? wp_unslash( $_POST[$name] ) : $default;), check_index: 1 it_behaves_like "matches lines containing", "wp_unslash", %q{? trim( wp_unslash( strtr( (string) $_POST[$name], "\n", " " ) ) )}, check_index: 1 end describe "PHP OBJECT INJECTION EXAMPLES" do # Let's find some end describe "REDUNDANT FUNCTION EXAMPLES" do # Should be looked at? it_behaves_like "matches lines containing", "mail", %($mail = mail($_REQUEST['email'], 'Login details', $replaced_all, $headers);), check_index: 1 # Ignored because they're defining mail functions - not using a built-in function(?): it_behaves_like "ignores lines containing", "mail", %(private function mail() \{) it_behaves_like "ignores lines containing", "mail", %(public static function mail() \{) # SHOULD BE ignored because they're not actually calling top-level mail functions (?): it_behaves_like "matches lines containing", "mail", %{'use' => __( 'Use mail (2)', 'contact-form-7' ) ) );} it_behaves_like "matches lines containing", "mail", %($template = self::mail();) it_behaves_like "matches lines containing", "mail", %(\} elseif ( $this->mail() )) end describe "BATSHIT WIERD EXAMPLES" do it_behaves_like "matches lines containing", "ini_set", %(ini_set( 'display_errors', 'on' );) end describe "ACCIDENTS EXAMPLES" do it_behaves_like "matches lines containing", "security", %(// Add some security, no direct load !) it_behaves_like "matches lines containing", "todo", %(// @todo more hardening?) it_behaves_like "matches lines containing", "hardening", %(// @todo more hardening?), check_index: 0, match_index: 1 it_behaves_like "matches lines containing", "TODO", %(__( 'Start', JM_TC_TEXTDOMAIN ) => '8l4k3zrD4Z0', /*TODO : redo tutorial (shorter)*/) # Don't actually represent anything bad, but probably no way we can automatically ignore? it_behaves_like "matches lines containing", "broken", %(return esc_attr( substr( $the_excerpt, 0, 200 ) ); // to prevent meta from being broken by e.g "") it_behaves_like "matches lines containing", "broken", %($weight = '' . __( 'Image is heavier than 1MB ! Card will be broken !', JM_TC_TEXTDOMAIN ) . '';) end describe "CONTENT SECURITY EXAMPLES", "Inline JavaScript" do # Mostly seen in the wild (but not in WP plugin code): it_behaves_like "matches lines containing", ") it_behaves_like "matches lines containing", "var _gaq = _gaq || [];) it_behaves_like "matches lines containing", ") # It's only inline javascript which matters: loading in from other sources is fine it_behaves_like "ignores lines containing", ") it_behaves_like "ignores lines containing", ") it_behaves_like "ignores lines containing", ") # Pathalogical examples: it_behaves_like "matches lines containing", "alert('evil');) it_behaves_like "ignores lines containing", ") it_behaves_like "ignores lines containing", ") it_behaves_like "matches lines containing", ") end describe "CONTENT SECURITY EXAMPLES", "Inline CSS" do # Mostly seen in the wild (but not in WP plugin code): it_behaves_like "matches lines containing", ") it_behaves_like "matches lines containing", "body \{) it_behaves_like "matches lines containing", ") it_behaves_like "matches lines containing", "#wpadminbar { display:none; }) it_behaves_like "matches lines containing", ") it_behaves_like "matches lines containing", ") it_behaves_like "matches lines containing", ") end describe "CONTENT SECURITY EXAMPLES", "HTML event attributes" do # Not seen in the wild: it_behaves_like "matches lines containing", "onclick", %(
Click me!
) it_behaves_like "matches lines containing", "onblur", %() end describe "DIRECT LOAD EXAMPLES" do # Not seen in the wild: it_behaves_like "matches lines containing", "wp-load.php", %(require(dirname(__FILE__) . '/wp-load.php');) end describe "UNRELIABLE IP EXAMPLES" do it_behaves_like "matches lines containing", "HTTP_X_FORWARDED_FOR", %(if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) { $ip = $_SERVER['HTTP_X_FORWARDED_FOR']; }), check_index: 1 it_behaves_like "matches lines containing", "HTTP_CLIENT_IP", %(if (isset($_SERVER['HTTP_CLIENT_IP'])) { $ip = $_SERVER['HTTP_CLIENT_IP']; }), check_index: 1 end describe "VERSION NUMBER EXAMPLES" do it_behaves_like "matches lines containing", "phpversion", %($pluginInfo['php_version'] = phpversion();) it_behaves_like "matches lines containing", "get_bloginfo('version", %($version = get_bloginfo('version');) it_behaves_like "matches lines containing", "get_bloginfo( 'version", %($version = get_bloginfo( 'version' );) it_behaves_like "matches lines containing", "bloginfo(\"version", %(