Plugin Directory

Changeset 475315


Ignore:
Timestamp:
12/14/2011 11:35:05 AM (13 years ago)
Author:
blogrescue
Message:

Plugged security vulnerabilities, changed Snapshot Everything to Snapshot Everything New, Changed items now display new file details also.

Location:
wordpress-sentinel/trunk
Files:
2 added
2 edited

Legend:

Unmodified
Added
Removed
  • wordpress-sentinel/trunk/readme.txt

    r474975 r475315  
    55Requires at least: 3.0
    66Tested up to: 3.3
    7 Stable tag: 1.0.0
     7Stable tag: 1.0.1
    88
    9 This plugin acts as a sentinel that watches over your core Wordpress programs, as well as installed themes and plugins.  It periodically checks things and lets you know when anything changes.
     9This plugin acts as a sentinel that watches over your core Wordpress programs (plus installed themes and plugins) and tells you when changes happen.
    1010
    1111== Description ==
     
    19191. Install the plugin
    20202. Select the plugin option under the Settings menu
    21 3. Press the Snapshot Everything button
     213. Press the <strong>Snapshot Everything New</strong> button
    2222
    2323This causes the plugin to scan the Wordpress install and track details on all files used by Wordpress, as well as for all installed plugins and themes.
    2424
    25 It is also possible to disable watching specific files.  This is done in the detail view by clicking on the Eye Icon next to the filename.  A crossed out Eye Icon will appear and the status will change to "Not Watched".  To enable watching on that file, just click on the crossed out Eye Icon.
     25It is also possible to disable watching specific files.  This is done in the detail view by clicking on the Eye Icon next to the filename.  A crossed out Eye Icon will appear and the status will change to <strong>Not Watched</strong>.  To enable watching on that file, just click on the crossed out Eye Icon.
    2626
    2727== Frequently Asked Questions ==
     
    3333If you are hacked, there are four questions that you have to address:
    3434
    35 How did they get in?
    36 What did they change?
    37 How do I undo the damage that was done?
    38 How do I prevent them from getting in again?
     351. How did they get in?
     362. What did they change?
     373. How do I undo the damage that was done?
     384. How do I prevent them from getting in again?
     39
    3940The purpose of this plugin is to alert you when you have been hacked and to address questions 2 & 3. Wordpress Sentinel acts as a watchdog that knows how your install is supposed to look and then alert you when something gets changed.
    4041
     
    4344First, install the plugin and go to the Wordpress Sentinel option under Settings. It should list content under Wordpress, Themes and Plugins.
    4445
    45 Second, click the "Snapshot Everything" button, and every file in your Wordpress install, as well as installed Themes and Plugins will be catalogued.
     46Second, click the <strong>Snapshot Everything New</strong> button, and every file in your Wordpress install, as well as installed Themes and Plugins will be catalogued.
    4647
    47 Periodically, the plugin will check a portion of the items for which snapshots have been taken. If any changes are detected, an administrative message will be displayed in Wordpress Admin. If this happens, go back to the Wordpress Sentinel option under Settings. The offending item will be marked as "Changed" in Red. If you click details, you can see what files have been changed and you can determine if this was a valid change or an intrusion and take the appropriate action.
     48Periodically, the plugin will check a portion of the items for which snapshots have been taken. If any changes are detected, an administrative message will be displayed in Wordpress Admin. If this happens, go back to the Wordpress Sentinel option under Settings. The offending item will be marked as <strong>Changed</strong>. If you click details, you can see what files have been changed and you can determine if this was a valid change or an intrusion and take the appropriate action.
    4849
    4950= What if I'm the one making changes? =
    5051
    51 Obviously, the plugin isn't watching what you are doing, so if you make changes to a Theme or install a new Plugin, or even Upgrade Wordpress to a newer version, it is going to notice that something changed and let you know. When this happens (and it will happen), just go to the Wordpress Sentinel option, find the item that you changed or added, and Refresh the Snapshot. (The "Snapshot Everything" button should never be used except when the plugin is first installed.)
     52Obviously, the plugin cannot differentiate between a good change and a bad change, so if you make changes to a Theme or install a new Plugin, or even Upgrade Wordpress to a newer version, it is simply going to notice the change and let you know. When this happens (and it will happen), just go to the Wordpress Sentinel option, find the item that you changed or added, and Refresh the Snapshot. (The <strong>Snapshot Everything New</strong> button is a handy way to create initial snapshots after installing new themes and plugins.  It does not touch items which have previously been catalogued.)
    5253
    5354= It is complaining because my sitemap updated - How do I fix this? =
     
    5657
    57581. Go to the Wordpress Sentinel interface
    58 2. Under Wordpress Root, click the Detail link
    59 3. Find sitemap.xml in the list and click on the Eye Icon to the left of the filename
    60 4. Find sitemap.xml.gz (if it exists) in the list and click on the Eye Icon to the left of the filename
    61 5. Click the Back link to get back to the Sentinel main screen
    62 6. Under Wordpress Root, click the Perform Check link
     592. Under Wordpress Root, click the <strong>Detail</strong> link
     603. Find <em>sitemap.xml</em> in the list and click on the Eye Icon to the left of the filename
     614. Find <em>sitemap.xml.gz</em> (if it exists) in the list and click on the Eye Icon to the left of the filename
     625. Click the <strong>Back</strong> link to get back to the Sentinel main screen
     636. Under Wordpress Root, click the <strong>Perform Check</strong> link
    6364
    6465The same process can be used to disable watching any specific file.
     
    7576
    7677That is really beyond the scope of this plugin. The best course of action is to keep Wordpress as well as all plugins and themes up to date. If you know the time the hack occurred (and this plugin helps you determine that) then it is also a good idea to have an Analyst look through your server logs and try to isolate the entry point.
     78
     79== Screenshots ==
     80
     811. Wordpress Sentinel Administration Screen - shows all Top Level items (Wordpress Core, Themes, Plugins) and status for each.
     822. Item detail screen (In this screenshot: Wordpress Root)
     83
     84== Changelog ==
     85
     86= 1.0.1 =
     87* Fixed Security vulnerabilities, thanks to Julio from <a href='boiteaweb.fr'>boiteaweb.fr</a>.
     88* Changed "Snapshot Everything" button to "Snapshot Everything New" to prevent untentional overwriting of existing snapshot data.
     89* Changed Detail so it also shows current file information (size and date) in red below the snapshot values.
     90
     91= 1.0.0 =
     92* Initial Plugin Release
     93
     94== Upgrade Notice ==
     95
     96= 1.0.1 =
     97This new release plugs several potential security holes.  Please Upgrade Immediately.
  • wordpress-sentinel/trunk/wordpress_sentinel.php

    r474998 r475315  
    66Plugin Name: Wordpress Sentinel
    77Plugin URI: http://blogrescue.com/2011/12/new-plugin-wp-sentinel/
    8 Description: This plugin acts as a sentinel that watches your Wordpress install and notifies you when it is updated.
    9 Version: 1.0.0
     8Description: Watches over your install and alerts you when changes are made. <a href="options-general.php?page=wordpress_sentinel">Administration Panel</a> | <a href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=GFVCGSUFKX2CU">Donate</a>
     9Version: 1.0.1
    1010Author: Blogrescue.com
    1111Author URI: http://blogrescue.com
     
    105105    print '<h2>Wordpress Sentinel</h2>';
    106106    print "<div style='text-align:center;'>";
    107     print "<a href='".$this->url('snapshot', array('section'=>'all'))."' class='button'>".
    108       "Snapshot Everything</a>";
     107   
     108    $snapshot_url = $this->url('snapshot', array('section'=>'all'));
     109    $snapshot_link = ( function_exists('wp_nonce_url') ) ? wp_nonce_url($snapshot_url, 'sentinel-snapshot-all') : $snapshot_url;
     110    print "<a href='$snapshot_link' class='button'>".
     111      "Snapshot Everything New</a>";
     112     
    109113    print "&nbsp;&nbsp;&nbsp;&nbsp;";
    110     print "<a href='".$this->url('check', array('section'=>'all'))."' class='button'>Check Everything</a>";
     114   
     115    $check_url = $this->url('check', array('section'=>'all'));
     116    $check_link = ( function_exists('wp_nonce_url') ) ? wp_nonce_url($check_url, 'sentinel-check-all') : $check_url;
     117    print "<a href='$check_link' class='button'>Check Everything</a>";
     118   
    111119    print "&nbsp;&nbsp;&nbsp;&nbsp;";
    112120    print "<a href='".$this->url('help')."' class='button'>How Does This Work?</a>";
     
    114122
    115123    $admin_home = true;
    116     $action = $this->value($this->args, 'action');
    117     $section_id = $this->value($this->args, 'section');
     124    $action = $this->arg('action');
     125    $section_id = $this->arg('section', '0');
     126    $section_id_intval = intval($section_id);
    118127
    119128    if($action == 'snapshot') {
    120       if($section_id == 'all')
    121         $this->build_all_snapshots();
    122       else
    123         $this->build_snapshot($section_id);
     129      if($section_id == 'all') {
     130        check_admin_referer('sentinel-snapshot-all');
     131        $this->build_all_new_snapshots();
     132      } else {
     133        check_admin_referer('sentinel-snapshot-'.$section_id_intval);
     134        $this->build_snapshot($section_id_intval);
     135      }
     136     
    124137    } else if($action == 'details' && $section_id > 0) {
    125       $admin_home = $this->view_details($section_id);
     138      check_admin_referer('sentinel-details-'.$section_id_intval);
     139      $admin_home = $this->view_details($section_id_intval);
     140     
    126141    } else if($action == 'check') {
    127       if($section_id == 'all')
     142      if($section_id == 'all') {
     143        check_admin_referer('sentinel-check-all');
    128144        $this->check_all_sections();
    129       else
    130         $this->check_section($section_id);
     145      } else {
     146        check_admin_referer('sentinel-check-'.$section_id_intval);
     147        $this->check_section($section_id_intval);
     148      }
     149     
    131150    } else if($action == 'help') {
    132151      $this->show_help();
     
    167186
    168187  function display_section_name($section) {
     188    $details_url = $this->url('details', array('section'=>$section->id));
     189    $details_link = ( function_exists('wp_nonce_url') ) ? wp_nonce_url($details_url, 'sentinel-details-'.$section->id) : $details_url;
     190   
     191    $snapshot_url = $this->url('snapshot', array('section'=>$section->id));
     192    $snapshot_link = ( function_exists('wp_nonce_url') ) ? wp_nonce_url($snapshot_url, 'sentinel-snapshot-'.$section->id) : $snapshot_url;
     193   
     194    $check_url = $this->url('check', array('section'=>$section->id));
     195    $check_link = ( function_exists('wp_nonce_url') ) ? wp_nonce_url($check_url, 'sentinel-check-'.$section->id) : $check_url;
     196 
    169197    $output = "<strong>".$section->name."</strong><br />( ";
    170198    if($section->state != WPS_STATE_NEW)
    171       $output .= "<a href='".$this->url('details', array('section'=>$section->id))."'>Details</a> | ";
     199      $output .= "<a href='$details_link'>Details</a> | ";
    172200    $snap = ($section->state == WPS_STATE_NEW ? "Create Snapshot" : "Refresh Snapshot");
    173     $output .= "<a href='".$this->url('snapshot', array('section'=>$section->id))."'>$snap</a> | ";
    174     $output .= "<a href='".$this->url('check', array('section'=>$section->id))."'>Perform Check</a>";
     201    $output .= "<a href='$snapshot_link'>$snap</a> | ";
     202    $output .= "<a href='$check_link'>Perform Check</a>";
    175203    $output .= " )";
    176204
     
    189217  <h3>How do I use it?</h3>
    190218  <p>First, install the plugin and go to the Wordpress Sentinel option under Settings.  It should list content under Wordpress, Themes and Plugins.</p>
    191   <p>Second, click the "Snapshot Everything" button, and every file in your Wordpress install, as well as installed Themes and Plugins will be catalogued.</p>
    192   <p>Periodically, the plugin will check a portion of the items for which snapshots have been taken.  If any changes are detected, an administrative message will be displayed in Wordpress Admin.  If this happens, go back to the Wordpress Sentinel option under Settings.  The offending item will be marked as "Changed" in Red.  If you click details, you can see what files have been changed and you can determine if this was a valid change or an intrusion and take the appropriate action.</p>
     219  <p>Second, click the <strong>Snapshot Everything New</strong> button, and every file in your Wordpress install, as well as installed Themes and Plugins will be catalogued.</p>
     220  <p>Periodically, the plugin will check a portion of the items for which snapshots have been taken. If any changes are detected, an administrative message will be displayed in Wordpress Admin. If this happens, go back to the Wordpress Sentinel option under Settings. The offending item will be marked as <span style='font-weight:bold;color:red;'>Changed</span>. If you click details, you can see what files have been changed and you can determine if this was a valid change or an intrusion and take the appropriate action..</p>
    193221  <h3>What if I'm the one making changes?</h3>
    194   <p>Obviously, the plugin isn't watching what you are doing, so if you make changes to a Theme or install a new Plugin, or even Upgrade Wordpress to a newer version, it is going to notice that something changed and let you know.  When this happens (and it will happen), just go to the Wordpress Sentinel option, find the item that you changed or added, and Refresh the Snapshot. (The "Snapshot Everything" button should never be used except when the plugin is first installed.)</p>
     222  <p>Obviously, the plugin cannot differentiate between a good change and a bad change, so if you make changes to a Theme or install a new Plugin, or even Upgrade Wordpress to a newer version, it is simply going to notice the change and let you know. When this happens (and it will happen), just go to the Wordpress Sentinel option, find the item that you changed or added, and Refresh the Snapshot. (The <strong>Snapshot Everything New</strong> button is a handy way to create initial snapshots after installing new themes and plugins.  It does not touch items which have previously been catalogued.)</p>
     223  <h3>It is complaining because my sitemap updated - How do I fix this?</h3>
     224  To stop watching your sitemap files, do the following:
     225  <ol>
     226  <li>Go to the Wordpress Sentinel interface</li>
     227  <li>Under <em>Wordpress Root</em>, click the <strong>Detail</strong> link</li>
     228  <li>Find <em>sitemap.xml</em> in the list and click on the Eye Icon to the left of the filename</li>
     229  <li>Find <em>sitemap.xml.gz</em> (if it exists) in the list and click on the Eye Icon to the left of the filename</li>
     230  <li>Click the <strong>Back</strong> link to get back to the Sentinel main screen</li>
     231  <li>Under Wordpress Root, click the <strong>Perform Check</strong> link</li>
     232  </ol>
     233  The same process can be used to disable watching any specific file.
    195234  <h3>What do I do if I really have been hacked?</h3>
    196235  <p>The first thing to do is to look at the Wordpress Sentinel page and figure out what items have been changed.  Take a screenshot and then look at the details of those items to see what files have been affected.  If Wordpress is changed, you need to replace every file that is changed, although usually removing the existing install and replacing it with a clean install is the best course.</p>
     
    198237  <p>If a theme has been corrupted, then things may get complicated.  If it is a stock theme that can be removed and reinstalled, then do that.  If it is a custom theme, then every modified file needs to be carefully examined and cleaned up.  You may need someone with advanced skills in site development to help separate the template content from the injected code.</p>
    199238  <h3>How do I stop the hacker from getting back in?</h3>
    200   <p>That is really beyond the scope of this plugin.  The best course of action is to keep Wordpress as well as all plugins and themes up to date.  If you know the time the hack occurred (and this plugin helps you determine that) then it is also a good idea to have an Analyst look through your server logs and try to isolate the entry point.</p>
     239  <p>That is really beyond the scope of this plugin.  The best course of action is to keep Wordpress as well as all plugins and themes up to date.  If you know the time the hack occurred (and this plugin can help you determine that) then it is also a good idea to have an Analyst look through your server logs and try to isolate the entry point.</p>
    201240  <br /><br />
    202241  Hope this plugin helps, and if you do need advanced help recovering from a hack or any other Wordpress assistance, feel free to contact me at <strong>[email protected]</strong>.
     
    235274  function view_details($section_id) {
    236275    global $wpdb;
    237     $sql = "SELECT * FROM ".$wpdb->prefix."wordpresssentinel_section WHERE section_id = $section_id";
    238     $section_row = $wpdb->get_row($wpdb->prepare($sql, $this->type, $this->name, $this->location));
     276    $sql = "SELECT * FROM ".$wpdb->prefix."wordpresssentinel_section WHERE section_id = %d";
     277    $section_row = $wpdb->get_row($wpdb->prepare($sql, (int)$section_id));   
    239278   
    240279    if($section_row == null) {
     
    244283    }
    245284
    246     if(isset($this->args['watch'])) $this->set_file_watch_status($this->args['watch'], 1);
    247     if(isset($this->args['nowatch'])) $this->set_file_watch_status($this->args['nowatch'], 0);
     285    if(isset($this->args['watch'])) {
     286      $this->set_file_watch_status($this->arg('watch'), 1);
     287    }
     288    if(isset($this->args['nowatch'])) {
     289      $this->set_file_watch_status($this->arg('nowatch'), 0);
     290    }
    248291   
    249292    print "<a href='".$this->url()."'>&laquo; Back</a>";
     
    260303      $icon = $section_file->watch ? "watch.png" : "nowatch.png";
    261304      $action = $section_file->watch ? "nowatch" : "watch";
    262       $watch = "<a href='".$this->url('details',array('section'=>$section_id,$action=>$section_file->file_id))."'>".
    263         "<img src='".plugins_url("images/$icon" , __FILE__ )."' width='16'></a>";
     305      $link = $this->url('details',array('section'=>$section_id,$action=>$section_file->file_id));
     306      $action_link = ( function_exists('wp_nonce_url') ) ? wp_nonce_url($link, 'sentinel-details-'.intval($section_id)) : $link;
     307     
     308      $alt_size = '';
     309      $alt_date = '';
     310      $alt_state = '';
     311      if($section_file->status == WPS_STATE_CHANGED) {
     312        $alt_size = "<br /><span style='color:red;'>".$section_file->changed_size."</span>";
     313        $alt_date = "<br /><span style='color:red;'>".$section_file->changed_date."</span>";
     314        $alt_state = "<br /><span style='color:red;'>&laquo; To</span>";
     315      }
     316
     317      $watch = "<a href='$action_link'><img src='".plugins_url("images/$icon" , __FILE__ )."' width='16'></a>";
    264318      print "<tr>";
    265319      print "<td>$watch&nbsp;&nbsp;".$section_file->location."</td>";
    266       print "<td>".$section_file->size."</td>";
    267       print "<td>".$section_file->update_date."</td>";
    268       print "<td>".$this->states[$section_file->status]."</td>";
     320      print "<td>".$section_file->size.$alt_size."</td>";
     321      print "<td>".$section_file->update_date.$alt_date."</td>";
     322      print "<td>".$this->states[$section_file->status].$alt_state."</td>";
    269323      print "</tr>";
    270324    }
     
    277331    global $wpdb;
    278332    $wpdb->update($wpdb->prefix.'wordpresssentinel_file',
    279       array('watch'=>$watch_status), array('file_id'=>$file_id));
    280   }
    281 
    282   function build_all_snapshots() {
     333      array('watch'=>$watch_status), array('file_id'=>intval($file_id)));
     334  }
     335
     336  function build_all_new_snapshots() {
     337    $update_list = array();
    283338    $all_sections = array_merge($this->base, $this->themes, $this->plugins);
     339   
    284340    foreach($all_sections as $section) {
    285       $this->build_snapshot($section->id, false);
    286     }
    287     print "<div id='message' class='updated' style='margin-top:8px;'><p>Snapshots Updated for <strong>Everything</p></strong></div>";
     341      if($section->state == WPS_STATE_NEW) {
     342        $this->build_snapshot($section->id, false);
     343        $update_list[] = $section->name;
     344      }
     345    }
     346    print "<div id='message' class='updated' style='margin-top:8px;'><p>Snapshots Updated for: <strong>".
     347      (count($update_list) ? join(", ", $update_list) : "No New Items Found") ."</p></strong></div>";
    288348  }
    289349 
    290350  function build_snapshot($section_id, $display_message = true) {
    291351    global $wpdb;
    292     $sql = "SELECT * FROM ".$wpdb->prefix."wordpresssentinel_section WHERE section_id = $section_id";
    293     $section_row = $wpdb->get_row($wpdb->prepare($sql, $this->type, $this->name, $this->location));
     352    $sql = "SELECT * FROM ".$wpdb->prefix."wordpresssentinel_section WHERE section_id = %d";
     353    $section_row = $wpdb->get_row($wpdb->prepare($sql, (int)$section_id));   
    294354   
    295355    if($section_row == null) {
     
    362422  function check_section($section_id, $display_message = true) {
    363423    global $wpdb;
    364     $sql = "SELECT * FROM ".$wpdb->prefix."wordpresssentinel_section WHERE section_id = $section_id";
    365     $section_row = $wpdb->get_row($wpdb->prepare($sql, $this->type, $this->name, $this->location));
     424    $sql = "SELECT * FROM ".$wpdb->prefix."wordpresssentinel_section WHERE section_id = %d";
     425    $section_row = $wpdb->get_row($wpdb->prepare($sql, (int)$section_id));   
    366426   
    367427    if($section_row == null) {
     
    493553   
    494554      foreach($url_args as $key=>$val) {
    495         if(!in_array($key, $skip)) $url_result .= "&$key=$val";
     555        if(!in_array($key, $skip)) $url_result .= "&".esc_html($key)."=".esc_html($val);
    496556      }
    497557    }
    498558     
    499559    return $url_result;
     560  }
     561 
     562  function arg($key, $default='') {
     563    $value = esc_html($this->value($this->args, $key, $default));
     564    return ($value);
    500565  }
    501566
     
    505570
    506571  function parse_uri() {
    507     $this->uri = preg_replace('/\?.*$/', '', $_SERVER['REQUEST_URI']);
     572    $this->uri = preg_replace('/\?.*$/', '', esc_html($_SERVER['REQUEST_URI']));
    508573    parse_str($_SERVER['QUERY_STRING'], $this->args);
    509574  }
Note: See TracChangeset for help on using the changeset viewer.