Sucuri Security – Auditing, Malware Scanner and Security Hardening - Version 1.6.6

Version Description

  • Internal code cleanup and re-organization.
  • More white lists for the integrity checks.
  • Additional settings to customize some of the warnings.
Download this release

Release Info

Developer dd@sucuri.net
Plugin Icon 128x128 Sucuri Security – Auditing, Malware Scanner and Security Hardening
Version 1.6.6
Comparing to
See all releases

Code changes from version 1.6.5 to 1.6.6

inc/css/index.html ADDED
@@ -0,0 +1 @@
1
+ <!-- Avoid the directory listing. -->
inc/css/index.php DELETED
@@ -1,15 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * Avoid directory listing.
5
- *
6
- * @package Sucuri Plugin - SiteCheck Malware Scanner
7
- * @author Yorman Arias <yorman.arias@sucuri.net>
8
- * @author Daniel Cid <dcid@sucuri.net>
9
- * @copyright Since 2010-2014 Sucuri Inc.
10
- * @license Released under the GPL - see LICENSE file for details.
11
- * @link https://wordpress.sucuri.net/
12
- * @since File available since Release 0.1
13
- */
14
-
15
- if( !defined('SUCURISCAN') ){ exit(0); }
inc/css/sucuriscan-default-css.css CHANGED
@@ -16,7 +16,13 @@
16
.sucuriscan-pull-right{float:right}
17
.sucuriscan-list li{list-style:disc;margin:0 0 5px 15px}
18
.sucuriscan-gradient, .sucuriscan-modal-header, .sucuriscan-maincontent .sucuriscan-table tr > th{background:#f1f1f1;background-image:-webkit-gradient(linear,left bottom,left top,from(#ececec),to(#f9f9f9));background-image:-webkit-linear-gradient(bottom,#ececec,#f9f9f9);background-image:-moz-linear-gradient(bottom,#ececec,#f9f9f9);background-image:-o-linear-gradient(bottom,#ececec,#f9f9f9);background-image:linear-gradient(to top,#ececec,#f9f9f9)}
19
- /* WordPress Extra Buttons */
20
.wp-core-ui .button-danger.button-danger{background:#cc2e2e;border-color:#a20000;box-shadow:inset 0 1px 0 rgba(230, 120, 120, 0.6)}
21
.wp-core-ui .button-danger.focus, .wp-core-ui .button-danger.hover, .wp-core-ui .button-danger:focus, .wp-core-ui .button-danger:hover{background:#be1e1e}
22
.wp-core-ui .button-danger.focus, .wp-core-ui .button-danger:focus{border-color:#500e0e}
@@ -97,9 +103,10 @@
97
/* WordPress Alerts */
98
div.sucuriscan-alert{position:relative;margin:0 0 20px 0}
99
div.sucuriscan-alert > a.close{position:absolute;top:10px;right:10px;font-size:18px;font-weight:bold;text-decoration:none}
100
- .sucuriscan-inline-alert, .sucuriscan-inline-alert-updated, .sucuriscan-inline-alert-error{background:#fff;box-shadow:0 1px 1px 0 rgba(0,0,0,.1);padding:0;border-left:4px solid #ddd}
101
- .sucuriscan-inline-alert > p, .sucuriscan-inline-alert-updated > p, .sucuriscan-inline-alert-error > p{margin:0;padding:8px 12px;border:1px solid #ddd;border-left:0}
102
.sucuriscan-inline-alert-updated{border-left-color:#7ad03a}
103
.sucuriscan-inline-alert-error{border-left-color:#dd3d36}
104
/* Tabulation Panels */
105
.sucuriscan-tabs{}
@@ -124,6 +131,8 @@ div.sucuriscan-alert > a.close{position:absolute;top:10px;right:10px;font-size:1
124
.sucuriscan-loading .title{font-size:26px;margin-bottom:10px}
125
.sucuriscan-loading .description{font-size:18px}
126
.sucuriscan-sitelogo{width:190px;height:100px;background:url('http://sitecheck.sucuri.net/images/sucuri-sprite.png') no-repeat;margin:0 auto}
127
/* Scanner Results */
128
.sucuriscan-maincontent .sucuriscan-border{border:0;border-left:4px solid #ddd}
129
.sucuriscan-maincontent .sucuriscan-border > h3, .sucuriscan-maincontent .sucuriscan-border > .inside{border-top:1px solid #e5e5e5;border-right:1px solid #e5e5e5}
@@ -212,7 +221,7 @@ div.sucuriscan-alert > a.close{position:absolute;top:10px;right:10px;font-size:1
212
.sucuriscan-maincontent .sucuriscan-settings form{display:inline-block}
213
.sucuriscan-maincontent .sucuriscan-settings select, .sucuriscan-maincontent .sucuriscan-settings .input-text{min-width:220px}
214
.sucuriscan-maincontent .sucuriscan-settings-notifications{margin-top:0}
215
- .sucuriscan-wpconfig-textarea{width:600px;height:525px;background:#f5f5f5;font-size:12px;line-height:1.4em;resize:none;margin:15px 0 0 0;padding:10px}
216
/* Responsive Styles */
217
@media (max-width: 620px) {
218
.sucuriscan-tabs > ul li, .sucuriscan-tabs > ul li > a{display:block}
16
.sucuriscan-pull-right{float:right}
17
.sucuriscan-list li{list-style:disc;margin:0 0 5px 15px}
18
.sucuriscan-gradient, .sucuriscan-modal-header, .sucuriscan-maincontent .sucuriscan-table tr > th{background:#f1f1f1;background-image:-webkit-gradient(linear,left bottom,left top,from(#ececec),to(#f9f9f9));background-image:-webkit-linear-gradient(bottom,#ececec,#f9f9f9);background-image:-moz-linear-gradient(bottom,#ececec,#f9f9f9);background-image:-o-linear-gradient(bottom,#ececec,#f9f9f9);background-image:linear-gradient(to top,#ececec,#f9f9f9)}
19
+ /* WordPress Extra Buttons (success) */
20
+ .wp-core-ui .button-success.button-success{background:#74cc2e;border-color:#2da200;box-shadow:inset 0 1px 0 rgba(155, 230, 120, 0.6)}
21
+ .wp-core-ui .button-success.focus, .wp-core-ui .button-success.hover, .wp-core-ui .button-success:focus, .wp-core-ui .button-success:hover{background:#4bbe1e}
22
+ .wp-core-ui .button-success.focus, .wp-core-ui .button-success:focus{border-color:#23500e}
23
+ .wp-core-ui .button-success.active, .wp-core-ui .button-success.active:focus, .wp-core-ui .button-success.active:hover, .wp-core-ui .button-success:active{background:#47a61b;border-color:#358400}
24
+ .wp-core-ui .button-success-disabled, .wp-core-ui .button-success.disabled, .wp-core-ui .button-success:disabled, .wp-core-ui .button-success[disabled]{color:#b2e794 !important;background:#74ba29 !important;border-color:#3f7f1b !important}
25
+ /* WordPress Extra Buttons (danger) */
26
.wp-core-ui .button-danger.button-danger{background:#cc2e2e;border-color:#a20000;box-shadow:inset 0 1px 0 rgba(230, 120, 120, 0.6)}
27
.wp-core-ui .button-danger.focus, .wp-core-ui .button-danger.hover, .wp-core-ui .button-danger:focus, .wp-core-ui .button-danger:hover{background:#be1e1e}
28
.wp-core-ui .button-danger.focus, .wp-core-ui .button-danger:focus{border-color:#500e0e}
103
/* WordPress Alerts */
104
div.sucuriscan-alert{position:relative;margin:0 0 20px 0}
105
div.sucuriscan-alert > a.close{position:absolute;top:10px;right:10px;font-size:18px;font-weight:bold;text-decoration:none}
106
+ .sucuriscan-inline-alert, .sucuriscan-inline-alert-updated, .sucuriscan-inline-alert-error, .sucuriscan-inline-alert-warning{background:#fff;box-shadow:0 1px 1px 0 rgba(0,0,0,.1);padding:0;border-left:4px solid #ddd}
107
+ .sucuriscan-inline-alert > p, .sucuriscan-inline-alert-updated > p, .sucuriscan-inline-alert-error > p, .sucuriscan-inline-alert-warning > p{margin:0;padding:8px 12px;border:1px solid #ddd;border-left:0}
108
.sucuriscan-inline-alert-updated{border-left-color:#7ad03a}
109
+ .sucuriscan-inline-alert-warning{border-left-color:#ffba00}
110
.sucuriscan-inline-alert-error{border-left-color:#dd3d36}
111
/* Tabulation Panels */
112
.sucuriscan-tabs{}
131
.sucuriscan-loading .title{font-size:26px;margin-bottom:10px}
132
.sucuriscan-loading .description{font-size:18px}
133
.sucuriscan-sitelogo{width:190px;height:100px;background:url('http://sitecheck.sucuri.net/images/sucuri-sprite.png') no-repeat;margin:0 auto}
134
+ .sucuriscan-sitecheck-form{margin:20px 0 0 0}
135
+ .sucuriscan-sitecheck-form .button.button-hero{padding:0 46px}
136
/* Scanner Results */
137
.sucuriscan-maincontent .sucuriscan-border{border:0;border-left:4px solid #ddd}
138
.sucuriscan-maincontent .sucuriscan-border > h3, .sucuriscan-maincontent .sucuriscan-border > .inside{border-top:1px solid #e5e5e5;border-right:1px solid #e5e5e5}
221
.sucuriscan-maincontent .sucuriscan-settings form{display:inline-block}
222
.sucuriscan-maincontent .sucuriscan-settings select, .sucuriscan-maincontent .sucuriscan-settings .input-text{min-width:220px}
223
.sucuriscan-maincontent .sucuriscan-settings-notifications{margin-top:0}
224
+ .sucuriscan-maincontent .sucuriscan-wpcron-list{margin-top:0}
225
/* Responsive Styles */
226
@media (max-width: 620px) {
227
.sucuriscan-tabs > ul li, .sucuriscan-tabs > ul li > a{display:block}
inc/images/index.html ADDED
@@ -0,0 +1 @@
1
+ <!-- Avoid the directory listing. -->
inc/images/index.php DELETED
@@ -1,15 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * Avoid directory listing.
5
- *
6
- * @package Sucuri Plugin - SiteCheck Malware Scanner
7
- * @author Yorman Arias <yorman.arias@sucuri.net>
8
- * @author Daniel Cid <dcid@sucuri.net>
9
- * @copyright Since 2010-2014 Sucuri Inc.
10
- * @license Released under the GPL - see LICENSE file for details.
11
- * @link https://wordpress.sucuri.net/
12
- * @since File available since Release 0.1
13
- */
14
-
15
- if( !defined('SUCURISCAN') ){ exit(0); }
inc/index.html ADDED
@@ -0,0 +1 @@
1
+ <!-- Avoid the directory listing. -->
inc/index.php DELETED
@@ -1,15 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * Avoid directory listing.
5
- *
6
- * @package Sucuri Plugin - SiteCheck Malware Scanner
7
- * @author Yorman Arias <yorman.arias@sucuri.net>
8
- * @author Daniel Cid <dcid@sucuri.net>
9
- * @copyright Since 2010-2014 Sucuri Inc.
10
- * @license Released under the GPL - see LICENSE file for details.
11
- * @link https://wordpress.sucuri.net/
12
- * @since File available since Release 0.1
13
- */
14
-
15
- if( !defined('SUCURISCAN') ){ exit(0); }
inc/js/index.html ADDED
@@ -0,0 +1 @@
1
+ <!-- Avoid the directory listing. -->
inc/js/index.php DELETED
@@ -1,15 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * Avoid directory listing.
5
- *
6
- * @package Sucuri Plugin - SiteCheck Malware Scanner
7
- * @author Yorman Arias <yorman.arias@sucuri.net>
8
- * @author Daniel Cid <dcid@sucuri.net>
9
- * @copyright Since 2010-2014 Sucuri Inc.
10
- * @license Released under the GPL - see LICENSE file for details.
11
- * @link https://wordpress.sucuri.net/
12
- * @since File available since Release 0.1
13
- */
14
-
15
- if( !defined('SUCURISCAN') ){ exit(0); }
inc/tpl/index.html ADDED
@@ -0,0 +1 @@
1
+ <!-- Avoid the directory listing. -->
inc/tpl/index.php DELETED
@@ -1,15 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * Avoid directory listing.
5
- *
6
- * @package Sucuri Plugin - SiteCheck Malware Scanner
7
- * @author Yorman Arias <yorman.arias@sucuri.net>
8
- * @author Daniel Cid <dcid@sucuri.net>
9
- * @copyright Since 2010-2014 Sucuri Inc.
10
- * @license Released under the GPL - see LICENSE file for details.
11
- * @link https://wordpress.sucuri.net/
12
- * @since File available since Release 0.1
13
- */
14
-
15
- if( !defined('SUCURISCAN') ){ exit(0); }
inc/tpl/infosys-cronjobs.html.tpl CHANGED
@@ -1,19 +1,67 @@
1
2
- <table class="wp-list-table widefat sucuriscan-wpcron-list">
3
- <thead>
4
- <tr>
5
- <th colspan="4">WordPress Cronjobs (%%SUCURI.Cronjobs.Total%% tasks)</th>
6
- </tr>
7
- <tr>
8
- <th>Task</th>
9
- <th>Schedule</th>
10
- <th>Next due (GMT/UTC)</th>
11
- <th>WordPress Hook</th>
12
- <!-- <th>Hook arguments</th> -->
13
- </tr>
14
- </thead>
15
-
16
- <tbody>
17
- %%SUCURI.Cronjobs.List%%
18
- </tbody>
19
- </table>
1
2
+ <div id="poststuff">
3
+ <div class="postbox sucuriscan-border sucuriscan-table-description sucuriscan-%%SUCURI.IgnoreRules.TableVisibility%%">
4
+ <h3>Scheduled Tasks (%%SUCURI.Cronjobs.Total%% tasks)</h3>
5
+
6
+ <div class="inside">
7
+ <p>
8
+ <strong>Scheduled Tasks</strong> are rules registered in your database by a
9
+ plugin, theme, or the base system itself; they are used to automatically execute
10
+ actions defined in the code every certain amount of time. A good use of these
11
+ rules is to generate backup files of your site, execute a security scanner, or
12
+ remove unused elements like drafts.
13
+ </p>
14
+
15
+ <div class="sucuriscan-inline-alert-warning">
16
+ <p>
17
+ Note that there are some scheduled tasks <em>(registered by the base
18
+ system)</em> that can not be removed permanently using this tool, tasks such as
19
+ the <strong>addon update</strong> and <strong>version checker</strong> are
20
+ required by the site to work correctly.
21
+ </p>
22
+ </div>
23
+ </div>
24
+ </div>
25
+ </div>
26
+
27
+ <form action="%%SUCURI.URL.Infosys%%#wordpress-cronjobs" method="post">
28
+ <input type="hidden" name="sucuriscan_page_nonce" value="%%SUCURI.PageNonce%%" />
29
+
30
+ <table class="wp-list-table widefat sucuriscan-table sucuriscan-wpcron-list">
31
+ <thead>
32
+ <tr>
33
+ <th class="manage-column column-cb check-column">
34
+ <label class="screen-reader-text" for="cb-select-all-1">Select All</label>
35
+ <input id="cb-select-all-1" type="checkbox">
36
+ </th>
37
+ <th>Task</th>
38
+ <th>Schedule</th>
39
+ <th>Next due</th>
40
+ <th>Arguments</th>
41
+ </tr>
42
+ </thead>
43
+
44
+ <tbody>
45
+ %%SUCURI.Cronjobs.List%%
46
+ </tbody>
47
+
48
+ <tfoot>
49
+ <tr>
50
+ <td colspan="5">
51
+ <label>
52
+ <select name="sucuriscan_cronjob_action">
53
+ <option value="">Choose action</option>
54
+ <option value="runnow">Execute now</option>
55
+ <option value="hourly">Re-schedule to hourly</option>
56
+ <option value="twicedaily">Re-schedule to twicedaily</option>
57
+ <option value="daily">Re-schedule to daily</option>
58
+ <option value="remove">Remove</option>
59
+ </select>
60
+ </label>
61
+ <button type="submit" class="button button-primary">Send action</button>
62
+ </td>
63
+ </tr>
64
+ </tfoot>
65
+ </table>
66
+
67
+ </form>
inc/tpl/infosys-cronjobs.snippet.tpl CHANGED
@@ -1,8 +1,10 @@
1
2
<tr class="%%SUCURI.Cronjob.CssClass%%">
3
- <td>%%SUCURI.Cronjob.Task%%</td>
4
- <td>%%SUCURI.Cronjob.Schedule%%</td>
5
- <td>%%SUCURI.Cronjob.Nexttime%%</td>
6
<td><span class="sucuriscan-monospace">%%SUCURI.Cronjob.Hook%%</span></td>
7
- <!-- <td>%%SUCURI.Cronjob.Arguments%%</td> -->
8
</tr>
1
2
<tr class="%%SUCURI.Cronjob.CssClass%%">
3
+ <td class="check-column">
4
+ <input type="checkbox" name="sucuriscan_cronjobs[]" value="%%SUCURI.Cronjob.Hook%%" />
5
+ </td>
6
<td><span class="sucuriscan-monospace">%%SUCURI.Cronjob.Hook%%</span></td>
7
+ <td>%%SUCURI.Cronjob.Schedule%%</td>
8
+ <td>%%SUCURI.Cronjob.NextTime%%</td>
9
+ <td>%%SUCURI.Cronjob.Arguments%%</td>
10
</tr>
inc/tpl/infosys-htaccess.html.tpl CHANGED
@@ -1,14 +1,15 @@
1
2
<div id="poststuff" class="sucuriscan-infosys-htaccess">
3
<div class="postbox">
4
- <h3>HTAccess Integrity</h3>
5
6
<div class="inside">
7
<p>
8
- The <code>.htaccess</code> is a distributed configuration file, and is how Apache handles
9
- configuration changes on a per-directory basis. WordPress uses this file to manipulate how
10
- Apache serves files from its root directory, and subdirectories thereof. Most notably, WP
11
- modifies this file to be able to handle pretty permalinks.
12
</p>
13
14
<div class="sucuriscan-inline-alert-%%SUCURI.HTAccess.MessageType%% sucuriscan-%%SUCURI.HTAccess.MessageVisible%%">
1
2
<div id="poststuff" class="sucuriscan-infosys-htaccess">
3
<div class="postbox">
4
+ <h3>Access File Integrity</h3>
5
6
<div class="inside">
7
<p>
8
+ The <code>.htaccess</code> is a distributed configuration file, and is how the
9
+ Apache web server handles configuration changes on a per-directory basis.
10
+ WordPress uses this file to manipulate how Apache serves files from its root
11
+ directory and subdirectories thereof; most notably, it modifies this file to be
12
+ able to handle pretty permalinks.
13
</p>
14
15
<div class="sucuriscan-inline-alert-%%SUCURI.HTAccess.MessageType%% sucuriscan-%%SUCURI.HTAccess.MessageVisible%%">
inc/tpl/infosys-serverinfo.html.tpl CHANGED
@@ -1,69 +1,6 @@
1
2
<table class="wp-list-table widefat sucuriscan-server-info">
3
<tbody>
4
- <tr class="alternate">
5
- <td>Sucuri Plugin version</td>
6
- <td><span class="sucuriscan-monospace">%%SUCURI.PluginVersion%%</span></td>
7
- </tr>
8
- <tr>
9
- <td>Sucuri Plugin MD5Sum (sucuri.php)</td>
10
- <td><span class="sucuriscan-monospace">%%SUCURI.PluginMD5%%</span></td>
11
- </tr>
12
- <tr class="alternate">
13
- <td>Sucuri Plugin Last-time scan</td>
14
- <td><span class="sucuriscan-monospace">%%SUCURI.PluginRuntimeDatetime%%</span></td>
15
- </tr>
16
- <tr>
17
- <td>Operating System</td>
18
- <td><span class="sucuriscan-monospace">%%SUCURI.OperatingSystem%%</span></td>
19
- </tr>
20
- <tr class="alternate">
21
- <td>Server</td>
22
- <td><span class="sucuriscan-monospace">%%SUCURI.Server%%</span></td>
23
- </tr>
24
- <tr>
25
- <td>Memory usage</td>
26
- <td><span class="sucuriscan-monospace">%%SUCURI.MemoryUsage%%</span></td>
27
- </tr>
28
- <tr class="alternate">
29
- <td>MYSQL Version</td>
30
- <td><span class="sucuriscan-monospace">%%SUCURI.MySQLVersion%%</span></td>
31
- </tr>
32
- <tr>
33
- <td>SQL Mode</td>
34
- <td><span class="sucuriscan-monospace">%%SUCURI.SQLMode%%</span></td>
35
- </tr>
36
- <tr class="alternate">
37
- <td>PHP Version</td>
38
- <td><span class="sucuriscan-monospace">%%SUCURI.PHPVersion%%</span></td>
39
- </tr>
40
- <tr>
41
- <td>PHP Safe Mode</td>
42
- <td><span class="sucuriscan-monospace">%%SUCURI.SafeMode%%</span></td>
43
- </tr>
44
- <tr class="alternate">
45
- <td>PHP Allow URL fopen</td>
46
- <td><span class="sucuriscan-monospace">%%SUCURI.AllowUrlFopen%%</span></td>
47
- </tr>
48
- <tr>
49
- <td>PHP Memory Limit</td>
50
- <td><span class="sucuriscan-monospace">%%SUCURI.MemoryLimit%%</span></td>
51
- </tr>
52
- <tr class="alternate">
53
- <td>PHP Max Upload Size</td>
54
- <td><span class="sucuriscan-monospace">%%SUCURI.UploadMaxFilesize%%</span></td>
55
- </tr>
56
- <tr>
57
- <td>PHP Max Post Size</td>
58
- <td><span class="sucuriscan-monospace">%%SUCURI.PostMaxSize%%</span></td>
59
- </tr>
60
- <tr class="alternate">
61
- <td>PHP Max Script Execute Time</td>
62
- <td><span class="sucuriscan-monospace">%%SUCURI.MaxExecutionTime%%</span></td>
63
- </tr>
64
- <tr>
65
- <td>PHP Max Input Time</td>
66
- <td><span class="sucuriscan-monospace">%%SUCURI.MaxInputTime%%</span></td>
67
- </tr>
68
</tbody>
69
</table>
1
2
<table class="wp-list-table widefat sucuriscan-server-info">
3
<tbody>
4
+ %%SUCURI.ServerInfo.Variables%%
5
</tbody>
6
</table>
inc/tpl/infosys-serverinfo.snippet.tpl ADDED
@@ -0,0 +1,5 @@
1
+
2
+ <tr class="%%SUCURI.ServerInfo.CssClass%%">
3
+ <td>%%SUCURI.ServerInfo.Title%%</td>
4
+ <td><span class="sucuriscan-monospace">%%SUCURI.ServerInfo.Value%%</span></td>
5
+ </tr>
inc/tpl/infosys-wpconfig.html.tpl CHANGED
@@ -1,14 +1,8 @@
1
2
- <table class="wp-list-table widefat sucuriscan-wpconfig-rules">
3
<thead>
4
- <th colspan="7" class="thead-with-button">
5
- <span>WP-Config Variables</span>
6
- <div class="thead-topright-action">
7
- <a href="%%SUCURI.WordpressConfig.ThickboxURL%%" title="WordPress Config Variables" class="button button-primary thickbox">View File</a>
8
- </div>
9
- </th>
10
<tr>
11
- <th>Variable Name</th>
12
<th>Value</th>
13
</tr>
14
</thead>
@@ -17,7 +11,3 @@
17
%%SUCURI.WordpressConfig.Rules%%
18
</tbody>
19
</table>
20
-
21
- <div id="sucuriscan-wpconfig-content" style="display:none">
22
- <textarea class="sucuriscan-full-textarea sucuriscan-wpconfig-textarea sucuriscan-monospace">%%SUCURI.WordpressConfig.Content%%</textarea>
23
- </div>
1
2
+ <table class="wp-list-table widefat sucuriscan-table sucuriscan-wpconfig-rules">
3
<thead>
4
<tr>
5
+ <th>Variable</th>
6
<th>Value</th>
7
</tr>
8
</thead>
11
%%SUCURI.WordpressConfig.Rules%%
12
</tbody>
13
</table>
inc/tpl/infosys-wpconfig.snippet.tpl CHANGED
@@ -1,4 +1,5 @@
1
<tr class="%%SUCURI.WordpressConfig.CssClass%%">
2
- <td class="sucuriscan-monospace"><strong>%%SUCURI.WordpressConfig.VariableName%%</strong></td>
3
- <td class="sucuriscan-monospace">%%SUCURI.WordpressConfig.VariableValue%%</td>
4
</tr>
1
+
2
<tr class="%%SUCURI.WordpressConfig.CssClass%%">
3
+ <td><span class="sucuriscan-monospace">%%SUCURI.WordpressConfig.VariableName%%</span></td>
4
+ <td><span class="%%SUCURI.WordpressConfig.VariableCssClass%%">%%SUCURI.WordpressConfig.VariableValue%%</span></td>
5
</tr>
inc/tpl/infosys.html.tpl CHANGED
@@ -5,13 +5,13 @@
5
<a href="#" data-tabname="server-info">Plugin &amp; Server Info</a>
6
</li>
7
<li>
8
- <a href="#" data-tabname="wordpress-cronjobs">WordPress Cronjobs</a>
9
</li>
10
<li>
11
- <a href="#" data-tabname="htaccess-integrity">HTAccess Integrity</a>
12
</li>
13
<li>
14
- <a href="#" data-tabname="wpconfig-vars">WP Config Variables</a>
15
</li>
16
</ul>
17
5
<a href="#" data-tabname="server-info">Plugin &amp; Server Info</a>
6
</li>
7
<li>
8
+ <a href="#" data-tabname="wordpress-cronjobs">Scheduled Tasks</a>
9
</li>
10
<li>
11
+ <a href="#" data-tabname="htaccess-integrity">Access File Integrity</a>
12
</li>
13
<li>
14
+ <a href="#" data-tabname="wpconfig-vars">Config. Variables</a>
15
</li>
16
</ul>
17
inc/tpl/malwarescan.html.tpl CHANGED
@@ -4,14 +4,11 @@
4
5
<p class="description">Visit our <a href="http://sucuri.net/signup?fromloader" target="_blank">coverage &amp; pricing</a> page for details on how sucuri can help you.</p>
6
7
- <p><img src="http://sitecheck.sucuri.net/images/loading.gif" alt="Loading..." /></p>
8
-
9
- <div class="sucuriscan-sitelogo">&nbsp;</div>
10
-
11
- <form method="post" name="sucuriscan_sitecheck_form">
12
<input type="hidden" name="sucuriscan_page_nonce" value="%%SUCURI.PageNonce%%" />
13
<input type="hidden" name="sucuriscan_malware_scan" value="1" />
14
</form>
15
16
- <script type="text/javascript">setTimeout(function(){ document.forms.sucuriscan_sitecheck_form.submit() }, 3000)</script>
17
</div>
4
5
<p class="description">Visit our <a href="http://sucuri.net/signup?fromloader" target="_blank">coverage &amp; pricing</a> page for details on how sucuri can help you.</p>
6
7
+ <form action="%%SUCURI.URL.Scanner%%" method="post" name="sucuriscan_sitecheck_form">
8
<input type="hidden" name="sucuriscan_page_nonce" value="%%SUCURI.PageNonce%%" />
9
<input type="hidden" name="sucuriscan_malware_scan" value="1" />
10
+ <button type="submit" class="button button-hero button-primary">Scan Website</button>
11
</form>
12
13
+ <div class="sucuriscan-sitelogo">&nbsp;</div>
14
</div>
inc/tpl/monitoring.html.tpl CHANGED
@@ -1,34 +1,34 @@
1
2
<div id="poststuff">
3
4
- <div class="postbox sucuriscan-monitoring-instructions sucuriscan-%%SUCURI.Monitoring.InstructionsVisibility%%">
5
- <h3>Instructions to enable CloudProxy WAF</h3>
6
7
<div class="inside">
8
<p>
9
- A powerful <b>WAF</b> <em>(Web Application Firewall)</em> and <b>Intrusion Prevention</b>
10
- system for any WordPress user. If you do not have an account, you can sign up for one here:
11
- <a href="http://cloudproxy.sucuri.net/" target="_blank">Sucuri CloudProxy</a>
12
</p>
13
14
- <ol>
15
- <li>
16
- Sign up for a Sucuri CloudProxy account here:
17
- <a href="https://login.sucuri.net/signup2/create?CloudProxy" target="_blank">Sign up</a>
18
- </li>
19
- <li>
20
- Change your DNS to point your site to one of our servers. This link explains
21
- <a href="https://dashboard.sucuri.net/cloudproxy/" target="_blank"> CloudProxy Dashboard</a>
22
- or use our documentation here <a href="http://kb.sucuri.net/cloudproxy" target="_blank">
23
- KB CloudProxy</a>.
24
- </li>
25
- <li>You are all set. There is nothing else to do.</li>
26
- </ol>
27
28
<p>
29
- Once enabled, our firewall will act as a shield, protecting your site from attacks
30
- and preventing malware infections and reinfections. It will block SQL injection attempts,
31
- brute force attacks, XSS, RFI, backdoors and many other threats against your site.
32
</p>
33
</div>
34
</div>
1
2
<div id="poststuff">
3
4
+ <div class="postbox sucuriscan-border sucuriscan-border-info sucuriscan-%%SUCURI.Monitoring.InstructionsVisibility%%">
5
+ <h3>Activation instructions</h3>
6
7
<div class="inside">
8
<p>
9
+ A powerful <b>WAF</b> <em>(Web Application Firewall)</em> and <b>Intrusion
10
+ Prevention</b> system for any WordPress user and many other platforms. This page
11
+ will help you to configure and monitor your site through <strong>Sucuri
12
+ CloudProxy</strong>. Once enabled, our firewall will act as a shield, protecting
13
+ your site from attacks and preventing malware infections and reinfections. It
14
+ will block SQL injection attempts, brute force attacks, XSS, RFI, backdoors and
15
+ many other threats against your site.
16
</p>
17
18
+ <p>
19
+ Add your <strong>API key</strong> in the form bellow, click in the
20
+ <em>activate</em> button and after that your site will start communicating with
21
+ the official CloudProxy API service. Your account settings, whitelisted IP
22
+ addresses, audit logs, and the cache status will be displayed when the API key
23
+ is validated.
24
+ </p>
25
26
<p>
27
+ <em>[1]</em> More information about <a href="http://cloudproxy.sucuri.net/" target="_blank">CloudProxy</a>.<br>
28
+ <em>[2]</em> Configuration instructions and videos in the official <a href="http://kb.sucuri.net/cloudproxy"
29
+ target="_blank">Knowledge Base</a> site.<br>
30
+ <em>[3]</em> <a href="https://login.sucuri.net/signup2/create?CloudProxy" target="_blank">Sign up</a> for a new
31
+ account and start protecting your site with CloudProxy.
32
</p>
33
</div>
34
</div>
inc/tpl/posthack-resetpassword.html.tpl CHANGED
@@ -7,12 +7,20 @@
7
<input type="hidden" name="sucuriscan_reset_password" value="1" />
8
9
<p>
10
- Use this tool to reset the current password for some specific users or for all
11
- of them. We will send an email to each of those users adivising the password change
12
- that includes the new password automatically generated by WordPress. After the
13
- password reset your current session will be closed and you'll need to login again.
14
</p>
15
16
<table class="wp-list-table widefat sucuriscan-table">
17
<thead>
18
<tr>
7
<input type="hidden" name="sucuriscan_reset_password" value="1" />
8
9
<p>
10
+ You can generate a new random password for the user accounts that you select
11
+ from the list. An email with the new password will be sent to the email address
12
+ of each chosen users.
13
</p>
14
15
+ <div class="sucuriscan-inline-alert-warning">
16
+ <p>
17
+ If you choose to change the password of your own user, then your current session
18
+ will expire inmediately. You will need to log into the admin panel with the new
19
+ password that will be sent to your email. If you are unsure of this, do not
20
+ select your account from the list.
21
+ </p>
22
+ </div>
23
+
24
<table class="wp-list-table widefat sucuriscan-table">
25
<thead>
26
<tr>
inc/tpl/posthack-updatesecretkeys.html.tpl CHANGED
@@ -1,17 +1,39 @@
1
2
- <div id="poststuff" class="sucuriscan-update-secret-keys">
3
<div class="postbox">
4
<div class="inside">
5
<form method="post">
6
<input type="hidden" name="sucuriscan_page_nonce" value="%%SUCURI.PageNonce%%" />
7
<input type="hidden" name="sucuriscan_update_wpconfig" value="1" />
8
9
- <p>
10
- Use this button to update the security keys stored in the <code>wp-config.php</code>
11
- file, we will use the official WordPress Secret-Key API Generator. After the
12
- update your current session will be closed and you'll need to login again.
13
- </p>
14
-
15
<p>
16
<label>
17
<input type="hidden" name="sucuriscan_process_form" value="0" />
@@ -20,7 +42,7 @@
20
</label>
21
</p>
22
23
- <input type="submit" value="Update WP-Config Keys" class="button button-primary" />
24
</form>
25
26
<div class="sucuriscan_wpconfig_keys_updated sucuriscan-%%SUCURI.WPConfigUpdate.Visibility%%">
1
2
+ <div id="poststuff" class="sucuriscan-update-security-keys">
3
<div class="postbox">
4
<div class="inside">
5
+ <p>
6
+ The secret or security keys are a list of constants added to your site to ensure
7
+ better encryption of information stored in the user's cookies. A secret key
8
+ makes your site harder to hack and access by adding random elements to the
9
+ password. You do not have to remember the keys, just write a random,
10
+ complicated, and long string in the <code>wp-config.php</code> file. You can
11
+ change these keys at any point in time to invalidate all existing cookies,
12
+ forcing all users to login again.
13
+ </p>
14
+
15
+ <div class="sucuriscan-inline-alert-warning">
16
+ <p>Your session will expire immediately after the security keys are changed.</p>
17
+ </div>
18
+
19
+ <table class="wp-list-table widefat sucuriscan-table sucuriscan-security-keys-table">
20
+ <thead>
21
+ <tr>
22
+ <th>Key</th>
23
+ <th>Value</th>
24
+ <th>Status</th>
25
+ </tr>
26
+ </thead>
27
+
28
+ <tbody>
29
+ %%SUCURI.SecurityKeys.List%%
30
+ </tbody>
31
+ </table>
32
+
33
<form method="post">
34
<input type="hidden" name="sucuriscan_page_nonce" value="%%SUCURI.PageNonce%%" />
35
<input type="hidden" name="sucuriscan_update_wpconfig" value="1" />
36
37
<p>
38
<label>
39
<input type="hidden" name="sucuriscan_process_form" value="0" />
42
</label>
43
</p>
44
45
+ <input type="submit" value="Generate New Security Keys" class="button button-primary" />
46
</form>
47
48
<div class="sucuriscan_wpconfig_keys_updated sucuriscan-%%SUCURI.WPConfigUpdate.Visibility%%">
inc/tpl/posthack-updatesecretkeys.snippet.tpl ADDED
@@ -0,0 +1,6 @@
1
+
2
+ <tr class="%%SUCURI.SecurityKey.CssClass%%">
3
+ <td><span class="sucuriscan-monospace">%%SUCURI.SecurityKey.KeyName%%</span></td>
4
+ <td><span class="sucuriscan-monospace">%%SUCURI.SecurityKey.KeyValue%%</span></td>
5
+ <td><span class="sucuriscan-label-%%SUCURI.SecurityKey.KeyStatusCssClass%%">%%SUCURI.SecurityKey.KeyStatusText%%</span></td>
6
+ </tr>
inc/tpl/posthack.html.tpl CHANGED
@@ -2,7 +2,7 @@
2
<div class="sucuriscan-tabs">
3
<ul>
4
<li>
5
- <a href="#" data-tabname="update-secret-keys">Update WordPress Keys</a>
6
</li>
7
<li>
8
<a href="#" data-tabname="reset-users-password">Reset User's Password</a>
@@ -13,7 +13,7 @@
13
</ul>
14
15
<div class="sucuriscan-tab-containers">
16
- <div id="sucuriscan-update-secret-keys">
17
%%SUCURI.UpdateSecretKeys%%
18
</div>
19
2
<div class="sucuriscan-tabs">
3
<ul>
4
<li>
5
+ <a href="#" data-tabname="update-security-keys">Security Keys</a>
6
</li>
7
<li>
8
<a href="#" data-tabname="reset-users-password">Reset User's Password</a>
13
</ul>
14
15
<div class="sucuriscan-tab-containers">
16
+ <div id="sucuriscan-update-security-keys">
17
%%SUCURI.UpdateSecretKeys%%
18
</div>
19
inc/tpl/settings-general.html.tpl CHANGED
@@ -6,7 +6,7 @@
6
<tr>
7
<th colspan="3" class="thead-with-button">
8
<span>Plugin Settings</span>
9
- <form method="post" class="thead-topright-action">
10
<input type="hidden" name="sucuriscan_page_nonce" value="%%SUCURI.PageNonce%%" />
11
<button type="submit" name="sucuriscan_reset_options" class="button-primary">Reset plugin options</button>
12
</form>
@@ -34,18 +34,18 @@
34
<span class="sucuriscan-monospace">%%SUCURI.APIKey%%</span>
35
</td>
36
<td class="td-with-button">
37
- <form method="post" class="sucuriscan-%%SUCURI.APIKey.RecoverVisibility%%">
38
<input type="hidden" name="sucuriscan_page_nonce" value="%%SUCURI.PageNonce%%" />
39
- <button type="submit" name="sucuriscan_recover_api_key" class="button-primary">Recover</button>
40
</form>
41
42
- <form method="post" class="sucuriscan-%%SUCURI.APIKey.ManualKeyFormVisibility%%">
43
<input type="hidden" name="sucuriscan_page_nonce" value="%%SUCURI.PageNonce%%" />
44
<input type="text" name="sucuriscan_manual_api_key" class="input-text" placeholder="API key sent to your email" />
45
<button type="submit" class="button-primary">Save</button>
46
</form>
47
48
- <form method="post" class="sucuriscan-%%SUCURI.APIKey.RemoveVisibility%%">
49
<input type="hidden" name="sucuriscan_page_nonce" value="%%SUCURI.PageNonce%%" />
50
<button type="submit" name="sucuriscan_remove_api_key" class="button-primary button-danger">Remove</button>
51
</form>
@@ -53,21 +53,10 @@
53
</tr>
54
55
<tr>
56
- <td>Last Scanning</td>
57
- <td><span class="sucuriscan-monospace">%%SUCURI.ScanningRuntimeHuman%%</span></td>
58
- <td class="td-with-button">
59
- <form action="%%SUCURI.URL.Home%%" method="post">
60
- <input type="hidden" name="sucuriscan_page_nonce" value="%%SUCURI.PageNonce%%" />
61
- <button type="submit" name="sucuriscan_force_scan" class="button-primary">Force Scan</button>
62
- </form>
63
- </td>
64
- </tr>
65
-
66
- <tr class="alternate">
67
<td>Notify events to</td>
68
<td><a href="mailto:%%SUCURI.NotifyTo%%">%%SUCURI.NotifyTo%%</a></td>
69
<td class="td-with-button">
70
- <form method="post">
71
<input type="hidden" name="sucuriscan_page_nonce" value="%%SUCURI.PageNonce%%" />
72
<input type="text" name="sucuriscan_notify_to" class="input-text" placeholder="Send notifications to..." />
73
<button type="submit" class="button-primary">Change</button>
@@ -75,11 +64,11 @@
75
</td>
76
</tr>
77
78
- <tr>
79
<td>Alerts per hour</td>
80
<td>%%SUCURI.EmailsPerHour%%</td>
81
<td class="td-with-button">
82
- <form method="post">
83
<input type="hidden" name="sucuriscan_page_nonce" value="%%SUCURI.PageNonce%%" />
84
<select name="sucuriscan_emails_per_hour">
85
%%SUCURI.EmailsPerHourOptions%%
@@ -89,11 +78,11 @@
89
</td>
90
</tr>
91
92
- <tr class="alternate">
93
<td>Consider brute-force after</td>
94
<td>%%SUCURI.MaximumFailedLogins%%</td>
95
<td class="td-with-button">
96
- <form method="post">
97
<input type="hidden" name="sucuriscan_page_nonce" value="%%SUCURI.PageNonce%%" />
98
<select name="sucuriscan_maximum_failed_logins">
99
%%SUCURI.MaximumFailedLoginsOptions%%
@@ -103,11 +92,11 @@
103
</td>
104
</tr>
105
106
- <tr>
107
<td>Verify SSL Cert</td>
108
<td>%%SUCURI.VerifySSLCert%%</td>
109
<td class="td-with-button">
110
- <form method="post">
111
<input type="hidden" name="sucuriscan_page_nonce" value="%%SUCURI.PageNonce%%" />
112
<select name="sucuriscan_verify_ssl_cert">
113
%%SUCURI.VerifySSLCertOptions%%
@@ -117,11 +106,58 @@
117
</td>
118
</tr>
119
120
<tr class="alternate">
121
<td>Scanning frequency</td>
122
- <td><span class="sucuriscan-monospace">%%SUCURI.ScanningFrequency%%</span></td>
123
<td class="td-with-button">
124
- <form method="post">
125
<input type="hidden" name="sucuriscan_page_nonce" value="%%SUCURI.PageNonce%%" />
126
<select name="sucuriscan_scan_frequency">
127
%%SUCURI.ScanningFrequencyOptions%%
@@ -131,11 +167,11 @@
131
</td>
132
</tr>
133
134
- <tr class="sucuriscan-%%SUCURI.ScanningInterfaceVisibility%%">
135
<td>Scanning interface</td>
136
- <td><span class="sucuriscan-monospace">%%SUCURI.ScanningInterface%%</span></td>
137
<td class="td-with-button">
138
- <form method="post">
139
<input type="hidden" name="sucuriscan_page_nonce" value="%%SUCURI.PageNonce%%" />
140
<select name="sucuriscan_scan_interface">
141
%%SUCURI.ScanningInterfaceOptions%%
6
<tr>
7
<th colspan="3" class="thead-with-button">
8
<span>Plugin Settings</span>
9
+ <form action="%%SUCURI.URL.Settings%%" method="post" class="thead-topright-action">
10
<input type="hidden" name="sucuriscan_page_nonce" value="%%SUCURI.PageNonce%%" />
11
<button type="submit" name="sucuriscan_reset_options" class="button-primary">Reset plugin options</button>
12
</form>
34
<span class="sucuriscan-monospace">%%SUCURI.APIKey%%</span>
35
</td>
36
<td class="td-with-button">
37
+ <form action="%%SUCURI.URL.Settings%%" method="post" class="sucuriscan-%%SUCURI.APIKey.RecoverVisibility%%">
38
<input type="hidden" name="sucuriscan_page_nonce" value="%%SUCURI.PageNonce%%" />
39
+ <button type="submit" name="sucuriscan_recover_key" class="button-primary">Recover</button>
40
</form>
41
42
+ <form action="%%SUCURI.URL.Settings%%" method="post" class="sucuriscan-%%SUCURI.APIKey.ManualKeyFormVisibility%%">
43
<input type="hidden" name="sucuriscan_page_nonce" value="%%SUCURI.PageNonce%%" />
44
<input type="text" name="sucuriscan_manual_api_key" class="input-text" placeholder="API key sent to your email" />
45
<button type="submit" class="button-primary">Save</button>
46
</form>
47
48
+ <form action="%%SUCURI.URL.Settings%%" method="post" class="sucuriscan-%%SUCURI.APIKey.RemoveVisibility%%">
49
<input type="hidden" name="sucuriscan_page_nonce" value="%%SUCURI.PageNonce%%" />
50
<button type="submit" name="sucuriscan_remove_api_key" class="button-primary button-danger">Remove</button>
51
</form>
53
</tr>
54
55
<tr>
56
<td>Notify events to</td>
57
<td><a href="mailto:%%SUCURI.NotifyTo%%">%%SUCURI.NotifyTo%%</a></td>
58
<td class="td-with-button">
59
+ <form action="%%SUCURI.URL.Settings%%" method="post">
60
<input type="hidden" name="sucuriscan_page_nonce" value="%%SUCURI.PageNonce%%" />
61
<input type="text" name="sucuriscan_notify_to" class="input-text" placeholder="Send notifications to..." />
62
<button type="submit" class="button-primary">Change</button>
64
</td>
65
</tr>
66
67
+ <tr class="alternate">
68
<td>Alerts per hour</td>
69
<td>%%SUCURI.EmailsPerHour%%</td>
70
<td class="td-with-button">
71
+ <form action="%%SUCURI.URL.Settings%%" method="post">
72
<input type="hidden" name="sucuriscan_page_nonce" value="%%SUCURI.PageNonce%%" />
73
<select name="sucuriscan_emails_per_hour">
74
%%SUCURI.EmailsPerHourOptions%%
78
</td>
79
</tr>
80
81
+ <tr>
82
<td>Consider brute-force after</td>
83
<td>%%SUCURI.MaximumFailedLogins%%</td>
84
<td class="td-with-button">
85
+ <form action="%%SUCURI.URL.Settings%%" method="post">
86
<input type="hidden" name="sucuriscan_page_nonce" value="%%SUCURI.PageNonce%%" />
87
<select name="sucuriscan_maximum_failed_logins">
88
%%SUCURI.MaximumFailedLoginsOptions%%
92
</td>
93
</tr>
94
95
+ <tr class="alternate">
96
<td>Verify SSL Cert</td>
97
<td>%%SUCURI.VerifySSLCert%%</td>
98
<td class="td-with-button">
99
+ <form action="%%SUCURI.URL.Settings%%" method="post">
100
<input type="hidden" name="sucuriscan_page_nonce" value="%%SUCURI.PageNonce%%" />
101
<select name="sucuriscan_verify_ssl_cert">
102
%%SUCURI.VerifySSLCertOptions%%
106
</td>
107
</tr>
108
109
+ <tr>
110
+ <td>Filesystem scanner</td>
111
+ <td>%%SUCURI.FsScannerStatus%%</td>
112
+ <td class="td-with-button">
113
+ <form action="%%SUCURI.URL.Settings%%" method="post">
114
+ <input type="hidden" name="sucuriscan_page_nonce" value="%%SUCURI.PageNonce%%" />
115
+ <input type="hidden" name="sucuriscan_fs_scanner" value="%%SUCURI.FsScannerSwitchValue%%" />
116
+ <button type="submit" class="button-primary %%SUCURI.FsScannerSwitchCssClass%%">%%SUCURI.FsScannerSwitchText%%</button>
117
+ </form>
118
+ </td>
119
+ </tr>
120
+
121
<tr class="alternate">
122
+ <td>Scan modified files</td>
123
+ <td>%%SUCURI.ScanModfilesStatus%%</td>
124
+ <td class="td-with-button">
125
+ <form action="%%SUCURI.URL.Settings%%" method="post">
126
+ <input type="hidden" name="sucuriscan_page_nonce" value="%%SUCURI.PageNonce%%" />
127
+ <input type="hidden" name="sucuriscan_scan_modfiles" value="%%SUCURI.ScanModfilesSwitchValue%%" />
128
+ <button type="submit" class="button-primary %%SUCURI.ScanModfilesSwitchCssClass%%">%%SUCURI.ScanModfilesSwitchText%%</button>
129
+ </form>
130
+ </td>
131
+ </tr>
132
+
133
+ <tr>
134
+ <td>Integrity checking</td>
135
+ <td>%%SUCURI.ScanChecksumsStatus%%</td>
136
+ <td class="td-with-button">
137
+ <form action="%%SUCURI.URL.Settings%%" method="post">
138
+ <input type="hidden" name="sucuriscan_page_nonce" value="%%SUCURI.PageNonce%%" />
139
+ <input type="hidden" name="sucuriscan_scan_checksums" value="%%SUCURI.ScanChecksumsSwitchValue%%" />
140
+ <button type="submit" class="button-primary %%SUCURI.ScanChecksumsSwitchCssClass%%">%%SUCURI.ScanChecksumsSwitchText%%</button>
141
+ </form>
142
+ </td>
143
+ </tr>
144
+
145
+ <tr class="alternate">
146
+ <td>Last Scanning</td>
147
+ <td><span class="sucuriscan-monospace">%%SUCURI.ScanningRuntimeHuman%%</span></td>
148
+ <td class="td-with-button">
149
+ <form action="%%SUCURI.URL.Home%%" method="post">
150
+ <input type="hidden" name="sucuriscan_page_nonce" value="%%SUCURI.PageNonce%%" />
151
+ <button type="submit" name="sucuriscan_force_scan" class="button-primary">Force Scan</button>
152
+ </form>
153
+ </td>
154
+ </tr>
155
+
156
+ <tr>
157
<td>Scanning frequency</td>
158
+ <td>%%SUCURI.ScanningFrequency%%</td>
159
<td class="td-with-button">
160
+ <form action="%%SUCURI.URL.Settings%%" method="post">
161
<input type="hidden" name="sucuriscan_page_nonce" value="%%SUCURI.PageNonce%%" />
162
<select name="sucuriscan_scan_frequency">
163
%%SUCURI.ScanningFrequencyOptions%%
167
</td>
168
</tr>
169
170
+ <tr class="alternate sucuriscan-%%SUCURI.ScanningInterfaceVisibility%%">
171
<td>Scanning interface</td>
172
+ <td>%%SUCURI.ScanningInterface%%</td>
173
<td class="td-with-button">
174
+ <form action="%%SUCURI.URL.Settings%%" method="post">
175
<input type="hidden" name="sucuriscan_page_nonce" value="%%SUCURI.PageNonce%%" />
176
<select name="sucuriscan_scan_interface">
177
%%SUCURI.ScanningInterfaceOptions%%
inc/tpl/{setup_notice.html.tpl → setup-notice.html.tpl} RENAMED
@@ -14,7 +14,7 @@
14
<div class="sucuriscan-pull-right sucuriscan-setup-form">
15
<form action="%%SUCURI.URL.Settings%%" method="post">
16
<input type="hidden" name="sucuriscan_page_nonce" value="%%SUCURI.PageNonce%%" />
17
- <button type="submit" name="sucuriscan_wordpress_apikey" class="button button-primary button-hero">
18
<span class="sucuriscan-button-title">Generate API key</span>
19
<span class="sucuriscan-button-subtitle">for <b>%%SUCURI.CleanDomain%%</b> / <b>%%SUCURI.AdminEmail%%</b></span>
20
</button>
14
<div class="sucuriscan-pull-right sucuriscan-setup-form">
15
<form action="%%SUCURI.URL.Settings%%" method="post">
16
<input type="hidden" name="sucuriscan_page_nonce" value="%%SUCURI.PageNonce%%" />
17
+ <button type="submit" name="sucuriscan_plugin_api_key" class="button button-primary button-hero">
18
<span class="sucuriscan-button-title">Generate API key</span>
19
<span class="sucuriscan-button-subtitle">for <b>%%SUCURI.CleanDomain%%</b> / <b>%%SUCURI.AdminEmail%%</b></span>
20
</button>
index.html ADDED
@@ -0,0 +1 @@
1
+ <!-- Avoid the directory listing. -->
index.php DELETED
@@ -1,15 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * Avoid directory listing.
5
- *
6
- * @package Sucuri Plugin - SiteCheck Malware Scanner
7
- * @author Yorman Arias <yorman.arias@sucuri.net>
8
- * @author Daniel Cid <dcid@sucuri.net>
9
- * @copyright Since 2010-2014 Sucuri Inc.
10
- * @license Released under the GPL - see LICENSE file for details.
11
- * @link https://wordpress.sucuri.net/
12
- * @since File available since Release 0.1
13
- */
14
-
15
- if( !defined('SUCURISCAN') ){ exit(0); }
readme.txt CHANGED
@@ -3,8 +3,8 @@ Contributors: dd@sucuri.net
3
Donate Link: http://sitecheck.sucuri.net
4
Tags: malware, security, firewall, scan, spam, virus, sucuri, protection
5
Requires at least:3.2
6
- Stable tag:1.6.5
7
- Tested up to: 3.9.1
8
9
The Sucuri Security - Auditing, SiteCheck Malware Scanner and Hardening is a security plugin enables you to scan your WordPress site using Sucuri SiteCheck for security and malware issues, and also verifies the security integrity of your core files right in your dashboard. It includes audit trails and post-hack security ions to help you reset passwords and secret keys in case it has been already hacked, or infected with malware.
10
@@ -66,6 +66,11 @@ the compromise on your site).
66
67
== Changelog ==
68
69
= 1.6.5 =
70
* Fixed integrity checking display.
71
3
Donate Link: http://sitecheck.sucuri.net
4
Tags: malware, security, firewall, scan, spam, virus, sucuri, protection
5
Requires at least:3.2
6
+ Stable tag:1.6.6
7
+ Tested up to: 3.9.2
8
9
The Sucuri Security - Auditing, SiteCheck Malware Scanner and Hardening is a security plugin enables you to scan your WordPress site using Sucuri SiteCheck for security and malware issues, and also verifies the security integrity of your core files right in your dashboard. It includes audit trails and post-hack security ions to help you reset passwords and secret keys in case it has been already hacked, or infected with malware.
10
66
67
== Changelog ==
68
69
+ = 1.6.6 =
70
+ * Internal code cleanup and re-organization.
71
+ * More white lists for the integrity checks.
72
+ * Additional settings to customize some of the warnings.
73
+
74
= 1.6.5 =
75
* Fixed integrity checking display.
76
sucuri.php CHANGED
@@ -4,7 +4,7 @@ Plugin Name: Sucuri Security - Auditing, Malware Scanner and Hardening
4
Plugin URI: http://wordpress.sucuri.net/
5
Description: The <a href="http://sucuri.net/" target="_blank">Sucuri Security</a> <em>(Auditing, Malware Scanner and Hardening)</em> plugin enables you to scan your WordPress site using <a href="http://sitecheck.sucuri.net/" target="_blank">Sucuri SiteCheck</a> right in your dashboard. SiteCheck will check for malware, spam, blacklisting and other security issues like .htaccess redirects, hidden eval code, etc. The best thing about it is it's completely free.
6
Author: Sucuri, INC
7
- Version: 1.6.5
8
Author URI: http://sucuri.net
9
*/
10
@@ -12,7 +12,7 @@ Author URI: http://sucuri.net
12
/**
13
* Main file to control the plugin.
14
*
15
- * @package Sucuri Plugin - SiteCheck Malware Scanner
16
* @author Yorman Arias <yorman.arias@sucuri.net>
17
* @author Daniel Cid <dcid@sucuri.net>
18
* @copyright Since 2010-2014 Sucuri Inc.
@@ -22,26 +22,51 @@ Author URI: http://sucuri.net
22
*/
23
24
25
- /* No direct access. */
26
- if(!function_exists('add_action'))
27
- {
28
- exit(0);
29
}
30
31
/**
32
- * Unique name of the plugin through out all the code.
33
*/
34
- define('SUCURISCAN','sucuriscan');
35
36
/**
37
- * Current version of the plugin's code.
38
*/
39
- define('SUCURISCAN_VERSION','1.6.5');
40
41
/**
42
- * The local URL where the plugin's files and assets are served.
43
*/
44
- define('SUCURI_URL', rtrim(plugin_dir_url( __FILE__ ),'/') );
45
46
/**
47
* The name of the Sucuri plugin main file.
@@ -63,6 +88,11 @@ define('SUCURISCAN_PLUGIN_PATH', WP_PLUGIN_DIR.'/'.SUCURISCAN_PLUGIN_FOLDER);
63
*/
64
define('SUCURISCAN_PLUGIN_FILEPATH', SUCURISCAN_PLUGIN_PATH.'/'.SUCURISCAN_PLUGIN_FILE);
65
66
/**
67
* Checksum of this file to check the integrity of the plugin.
68
*/
@@ -113,6 +143,184 @@ define('SUCURISCAN_SITECHECK_LIFETIME', 1200);
113
*/
114
define('SUCURISCAN_GET_PLUGINS_LIFETIME', 1800);
115
116
/**
117
* Miscellaneous library.
118
*
@@ -128,6 +336,43 @@ class SucuriScan {
128
public function __construct(){
129
}
130
131
/**
132
* Generates a lowercase random string with an specific length.
133
*
@@ -176,165 +421,489 @@ class SucuriScan {
176
}
177
178
/**
179
- * Check the nonce comming from any of the settings pages.
180
*
181
- * @return boolean TRUE if the nonce is valid, FALSE otherwise.
182
*/
183
- public static function sucuriscan_check_options_wpnonce(){
184
- // Create the option_page value if permalink submission.
185
if(
186
- !isset($_POST['option_page'])
187
- && isset($_POST['permalink_structure'])
188
){
189
- $_POST['option_page'] = 'permalink';
190
}
191
192
- // Check if the option_page has an allowed value.
193
- if( isset($_POST['option_page']) ){
194
- $nonce='_wpnonce';
195
- $action = '';
196
197
- switch( $_POST['option_page'] ){
198
- case 'general': /* no_break */
199
- case 'writing': /* no_break */
200
- case 'reading': /* no_break */
201
- case 'discussion': /* no_break */
202
- case 'media': /* no_break */
203
- case 'options': /* no_break */
204
- $action = $_POST['option_page'] . '-options';
205
- break;
206
- case 'permalink':
207
- $action = 'update-permalink';
208
- break;
209
}
210
211
- // Check the nonce validity.
212
- if(
213
- !empty($action)
214
- && isset($_REQUEST[$nonce])
215
- && wp_verify_nonce($_REQUEST[$nonce], $action)
216
- ){
217
- return TRUE;
218
}
219
}
220
221
return FALSE;
222
}
223
224
- }
225
226
- /**
227
- * Class to process files and folders.
228
- *
229
- * Here are implemented the functions needed to open, scan, read, create files
230
- * and folders using the built-in PHP class SplFileInfo. The SplFileInfo class
231
- * offers a high-level object oriented interface to information for an individual
232
- * file.
233
- */
234
- class SucuriScanFileInfo extends SucuriScan {
235
236
/**
237
- * Whether the list of files that can be ignored from the filesystem scan will
238
- * be used to return the directory tree, this should be disabled when scanning a
239
- * directory without the need to filter the items in the list.
240
*
241
- * @var boolean
242
*/
243
- public $ignore_files = TRUE;
244
245
/**
246
- * Whether the list of folders that can be ignored from the filesystem scan will
247
- * be used to return the directory tree, this should be disabled when scanning a
248
- * path without the need to filter the items in the list.
249
*
250
- * @var boolean
251
*/
252
- public $ignore_directories = TRUE;
253
254
/**
255
- * Whether the filesystem scanner should run recursively or not.
256
*
257
- * @var boolean
258
*/
259
- public $run_recursively = TRUE;
260
261
/**
262
- * Class constructor.
263
*/
264
- public function __construct(){
265
}
266
267
/**
268
- * Retrieve a long text string with signatures of all the files contained
269
- * in the main and subdirectories of the folder specified, also the filesize
270
- * and md5sum of that file. Some folders and files will be ignored depending
271
- * on some rules defined by the developer.
272
*
273
- * @param string $directory Parent directory where the filesystem scan will start.
274
- * @param string $scan_with Set the tool used to scan the filesystem, SplFileInfo by default.
275
- * @param boolean $as_array Whether the result of the operation will be returned as an array or string.
276
- * @return array List of files in the main and subdirectories of the folder specified.
277
*/
278
- public function get_directory_tree_md5( $directory='', $scan_with='spl', $as_array=FALSE ){
279
- $project_signatures = '';
280
- $abs_path = rtrim( ABSPATH, '/' );
281
- $files = $this->get_directory_tree($directory, $scan_with);
282
- sort($files);
283
-
284
- if( $as_array ){
285
- $project_signatures = array();
286
}
287
288
- foreach( $files as $filepath){
289
- $file_checksum = @md5_file($filepath);
290
- $filesize = @filesize($filepath);
291
292
- if( $as_array ){
293
- $basename = str_replace( $abs_path . '/', '', $filepath );
294
- $project_signatures[$basename] = array(
295
- 'filepath' => $filepath,
296
- 'checksum' => $file_checksum,
297
- 'filesize' => $filesize,
298
- 'filetime' => filectime($filepath),
299
- );
300
- } else {
301
- $filepath = str_replace( $abs_path, $abs_path . '/', $filepath );
302
- $project_signatures .= sprintf(
303
- "%s%s%s%s\n",
304
- $file_checksum,
305
- $filesize,
306
- chr(32),
307
- $filepath
308
- );
309
- }
310
- }
311
312
- return $project_signatures;
313
}
314
315
/**
316
- * Retrieve a list with all the files contained in the main and subdirectories
317
- * of the folder specified. Some folders and files will be ignored depending
318
- * on some rules defined by the developer.
319
*
320
- * @param string $directory Parent directory where the filesystem scan will start.
321
- * @param string $scan_with Set the tool used to scan the filesystem, SplFileInfo by default.
322
- * @return array List of files in the main and subdirectories of the folder specified.
323
*/
324
- public function get_directory_tree($directory='', $scan_with='spl'){
325
- if( file_exists($directory) && is_dir($directory) ){
326
- $tree = array();
327
328
- switch( $scan_with ){
329
- case 'spl':
330
- if( $this->is_spl_available() ){
331
- $tree = $this->get_directory_tree_with_spl($directory);
332
- } else {
333
- $tree = $this->get_directory_tree($directory, 'opendir');
334
- }
335
- break;
336
337
- case 'glob':
338
$tree = $this->get_directory_tree_with_glob($directory);
339
break;
340
@@ -613,339 +1182,99 @@ class SucuriScanFileInfo extends SucuriScan {
613
return $all_removed;
614
}
615
616
}
617
618
/**
619
- * Class responsible for the processing of all the tasks associated to the database.
620
*
621
- * Here are implemented the functions needed to rename tables, generate random names,
622
- * change the Wordpress table prefix and modify the name of all the options linked to
623
- * the previous database prefix.
624
*/
625
- class SucuriScanDatabase extends SucuriScan {
626
627
/**
628
- * List all database tables in a clean array of strings.
629
*
630
- * @return array Array of strings.
631
*/
632
- public function get_dbtables(){
633
- global $wpdb;
634
-
635
- $table_names = array();
636
- $tables = $wpdb->get_results('SHOW TABLES', ARRAY_N);
637
-
638
- foreach($tables as $table){
639
- $table_names[] = $table[0];
640
- }
641
642
- return $table_names;
643
- }
644
645
/**
646
- * Set a new database table prefix to improve the security.
647
*
648
- * @return void
649
*/
650
- public function new_table_prefix(){
651
- $new_table_prefix = $this->random_char( rand(4,7) ).'_';
652
- $this->set_table_prefix($new_table_prefix);
653
- }
654
655
/**
656
- * Reset the database table prefix with the default value 'wp_'.
657
*
658
* @return void
659
*/
660
- public function reset_table_prefix(){
661
- $this->set_table_prefix('wp_');
662
}
663
664
/**
665
- * Set a new table prefix and changes table names, options, configuration files, etc.
666
*
667
- * @param string $new_table_prefix The new table prefix.
668
- * @return void
669
*/
670
- private function set_table_prefix( $new_table_prefix='wp_' ){
671
- $resp_parts = array();
672
-
673
- // Set the new table prefix in the configuration file.
674
- $resp_parts[] = $this->new_table_prefix_wpconfig($new_table_prefix);
675
-
676
- // Update options table with the new table prefix.
677
- $resp_parts[] = $this->new_table_prefix_optionstable($new_table_prefix);
678
-
679
- // Update usermeta table with the new table prefix.
680
- $resp_parts[] = $this->new_table_prefix_usermetatable($new_table_prefix);
681
-
682
- // Rename table names with the new table prefix.
683
- $resp_parts[] = $this->new_table_prefix_tablerename($new_table_prefix);
684
685
- foreach( $resp_parts as $response ){
686
- if( $response['process'] !== TRUE ){
687
- sucuriscan_error( $response['message'] );
688
- }
689
- }
690
}
691
692
/**
693
- * Using the new database table prefix, it modifies the main configuration file with that new value.
694
*
695
- * @param string $new_table_prefix
696
- * @return array An array with two default indexes containing the result of the operation and a message.
697
- */
698
- private function new_table_prefix_wpconfig( $new_table_prefix='' ){
699
- global $wpdb;
700
-
701
- $response = array( 'process'=>FALSE, 'message'=>'' );
702
- $wp_config_path = sucuriscan_get_wpconfig_path();
703
-
704
- if( file_exists($wp_config_path) ){
705
- @chmod($wp_config_path, 0777);
706
-
707
- if( is_writable($wp_config_path) ){
708
- $new_wpconfig = '';
709
- $wpconfig_lines = @file($wp_config_path);
710
-
711
- foreach( $wpconfig_lines as $line ){
712
- $line = str_replace("\n", '', $line);
713
-
714
- if( preg_match('/.*\$table_prefix([ ]+)?=.*/', $line, $match) ){
715
- $line = str_replace($wpdb->prefix, $new_table_prefix, $match[0]);
716
- }
717
-
718
- $new_wpconfig .= "{$line}\n";
719
- }
720
-
721
- $handle = fopen($wp_config_path, 'w');
722
- @fwrite($handle, $new_wpconfig);
723
- @fclose($handle);
724
- @chmod($wp_config_path, 0644);
725
-
726
- $response['process'] = TRUE;
727
- $response['message'] = 'Main configuration file modified.';
728
- } else {
729
- $response['message'] = 'Main configuration file is not writable, you will need to put the new
730
- table prefix <code>'.$new_table_prefix.'</code> manually in <code>wp-config.php</code>.';
731
- }
732
- } else {
733
- $response['message'] = 'Main configuration file was not located: <code>'.$wp_config_path.'</code>.';
734
- }
735
-
736
- return $response;
737
- }
738
-
739
- /**
740
- * Returns a list of all the tables in the selected database containing the same prefix.
741
- *
742
- * @param string $prefix A text string used to filter the tables with a specific prefix.
743
- * @return array A list of all the tables with the prefix specified.
744
- */
745
- public function get_prefixed_tables( $prefix='' ){
746
- global $wpdb;
747
-
748
- $tables = array();
749
- $prefix = empty($prefix) ? $wpdb->prefix : $prefix;
750
- $db_tables = $this->get_dbtables();
751
-
752
- foreach( $db_tables as $table_name ){
753
- if( preg_match("/^{$prefix}/", $table_name) ){
754
- $tables[] = $table_name;
755
- }
756
- }
757
-
758
- return $tables;
759
- }
760
-
761
- /**
762
- * Using the new database table prefix, it modifies the name of all tables with the new value.
763
- *
764
- * @param string $new_table_prefix
765
- * @return array An array with two default indexes containing the result of the operation and a message.
766
- */
767
- private function new_table_prefix_tablerename( $new_table_prefix='' ){
768
- global $wpdb;
769
-
770
- $response = array( 'process'=>FALSE, 'message'=>'' );
771
- $db_tables = $this->get_prefixed_tables();
772
-
773
- $renamed_count = 0;
774
- $total_tables = count($db_tables);
775
- $tables_not_renamed = array();
776
-
777
- foreach( $db_tables as $table_name ){
778
- $table_new_name = $new_table_prefix . str_replace($wpdb->prefix, '', $table_name);
779
- $sql = 'RENAME TABLE `%s` TO `%s`';
780
-
781
- /* Don't use WPDB->Prepare() */
782
- if( $wpdb->query(sprintf($sql, $table_name, $table_new_name))===FALSE ){
783
- $tables_not_renamed[] = $table_name;
784
- } else {
785
- $renamed_count += 1;
786
- }
787
- }
788
-
789
- $response['message'] = 'Database tables renamed: '.$renamed_count.' out of '.$total_tables;
790
-
791
- if( $renamed_count>0 && $renamed_count==$total_tables ){
792
- $response['process'] = TRUE;
793
- $error = $wpdb->set_prefix($new_table_prefix);
794
-
795
- if( is_wp_error($error) ){
796
- foreach( $error->errors as $error_index=>$error_data ){
797
- if( is_array($error_data) ){
798
- foreach( $error_data as $error_data_value ){
799
- $response['message'] .= chr(32) . $error_data_value . '.';
800
- }
801
- }
802
- }
803
- }
804
- } else {
805
- $response['message'] .= '<br>These tables were not renamed, you will need to do it manually:';
806
- $response['message'] .= chr(32) . implode( ',' . chr(32), $table_not_renamed );
807
- }
808
-
809
- return $response;
810
- }
811
-
812
- /**
813
- * Using the new database table prefix, it modifies the name of all options with the new value.
814
- *
815
- * @param string $new_table_prefix
816
- * @return array An array with two default indexes containing the result of the operation and a message.
817
- */
818
- private function new_table_prefix_optionstable( $new_table_prefix='' ){
819
- global $wpdb;
820
-
821
- $response = array( 'process'=>TRUE, 'message'=>'' );
822
- $results = $wpdb->get_results("SELECT option_id, option_name FROM {$wpdb->prefix}options WHERE option_name LIKE '{$wpdb->prefix}%'");
823
-
824
- foreach( $results as $row ){
825
- $row->new_option_name = $new_table_prefix.str_replace($wpdb->prefix, '', $row->option_name);
826
- $sql = "UPDATE {$wpdb->prefix}options SET option_name=%s WHERE option_id=%s LIMIT 1";
827
-
828
- if( $wpdb->query($wpdb->prepare($sql, $row->new_option_name, $row->option_id))===FALSE ){
829
- $response['process'] = FALSE;
830
- }
831
- }
832
-
833
- $response['message'] = $response['process']
834
- ? 'Database table options updated.'
835
- : 'Some entries in the database table <strong>Options</strong> were not updated';
836
-
837
- return $response;
838
- }
839
-
840
- /**
841
- * Using the new database table prefix, it modifies the name of all usermeta keys with the new value.
842
- *
843
- * @param string $new_table_prefix
844
- * @return array An array with two default indexes containing the result of the operation and a message.
845
- */
846
- private function new_table_prefix_usermetatable( $new_table_prefix='' ){
847
- global $wpdb;
848
-
849
- $response = array( 'process'=>TRUE, 'message'=>'' );
850
- $results = $wpdb->get_results("SELECT umeta_id, meta_key FROM {$wpdb->prefix}usermeta WHERE meta_key LIKE '{$wpdb->prefix}%'");
851
-
852
- foreach( $results as $row ){
853
- $row->new_meta_key = $new_table_prefix.str_replace($wpdb->prefix, '', $row->meta_key);
854
- $sql = "UPDATE {$wpdb->prefix}usermeta SET meta_key=%s WHERE umeta_id=%s LIMIT 1";
855
-
856
- if( $wpdb->query($wpdb->prepare($sql, $row->new_meta_key, $row->umeta_id))===FALSE ){
857
- $response['process'] = FALSE;
858
- }
859
- }
860
-
861
- $response['message'] = $response['process']
862
- ? 'Database table usermeta updated.'
863
- : 'Some entries in the database table <strong>UserMeta</strong> were not updated';
864
-
865
- return $response;
866
- }
867
-
868
- }
869
-
870
- /**
871
- * File-based cache library.
872
- *
873
- * WP_Object_Cache [1] is WordPress' class for caching data which may be
874
- * computationally expensive to regenerate, such as the result of complex
875
- * database queries. However the object cache is non-persistent. This means that
876
- * data stored in the cache resides in memory only and only for the duration of
877
- * the request. Cached data will not be stored persistently across page loads
878
- * unless of the installation of a 3party persistent caching plugin [2].
879
- *
880
- * [1] http://codex.wordpress.org/Class_Reference/WP_Object_Cache
881
- * [2] http://codex.wordpress.org/Class_Reference/WP_Object_Cache#Persistent_Caching
882
- */
883
- class SucuriScanCache extends SucuriScan {
884
-
885
- /**
886
- * The unique name (or identifier) of the file with the data.
887
- *
888
- * The file should be located in the same folder where the dynamic data
889
- * generated by the plugin is stored, and using the following format [1], it
890
- * most be a PHP file because it is expected to have an exit point in the first
891
- * line of the file causing it to stop the execution if a unauthorized user
892
- * tries to access it directly.
893
- *
894
- * [1] /public/data/sucuri-DATASTORE.php
895
- *
896
- * @var null|string
897
- */
898
- private $datastore = NULL;
899
-
900
- /**
901
- * The full path of the datastore file.
902
- *
903
- * @var string
904
- */
905
- private $datastore_path = '';
906
-
907
- /**
908
- * Whether the datastore file is usable or not.
909
- *
910
- * This variable will only be TRUE if the datastore file specified exists, is
911
- * writable and readable, in any other case it will always be FALSE.
912
- *
913
- * @var boolean
914
- */
915
- private $usable_datastore = FALSE;
916
-
917
- /**
918
- * Class constructor.
919
- *
920
- * @param string $datastore Unique name (or identifier) of the file with the data.
921
- * @return void
922
- */
923
- public function __construct( $datastore='' ){
924
- $this->datastore = $datastore;
925
- $this->datastore_path = $this->datastore_file_path();
926
- $this->usable_datastore = (bool) $this->datastore_path;
927
- }
928
-
929
- /**
930
- * Default attributes for every datastore file.
931
- *
932
- * @return string Default attributes for every datastore file.
933
- */
934
- private function datastore_default_info(){
935
- $attrs = array(
936
- 'datastore' => $this->datastore,
937
- 'created_on' => time(),
938
- 'updated_on' => time(),
939
- );
940
-
941
- return $attrs;
942
- }
943
-
944
- /**
945
- * Default content of every datastore file.
946
- *
947
- * @param array $finfo Rainbow table with the key names and decoded values.
948
- * @return string Default content of every datastore file.
949
*/
950
private function datastore_info( $finfo=array() ){
951
$attrs = $this->datastore_default_info();
@@ -1058,12 +1387,10 @@ class SucuriScanCache extends SucuriScan {
1058
);
1059
1060
if( $this->usable_datastore ){
1061
- $data_lines = @file($this->datastore_path);
1062
1063
if( !empty($data_lines) ){
1064
foreach( $data_lines as $line ){
1065
- $line = trim($line);
1066
-
1067
if( preg_match('/^\/\/ ([a-z_]+)=(.*);#x2F;', $line, $match) ){
1068
$data_object['info'][$match[1]] = $match[2];
1069
}
@@ -1073,7 +1400,7 @@ class SucuriScanCache extends SucuriScan {
1073
$this->valid_key_name($match[1])
1074
&& !array_key_exists($match[1], $data_object)
1075
){
1076
- $data_object['entries'][$match[1]] = json_decode( $match[2], $assoc );
1077
}
1078
}
1079
}
@@ -1248,3206 +1575,3379 @@ class SucuriScanCache extends SucuriScan {
1248
}
1249
1250
/**
1251
- * Check whether the current site is working as a multi-site instance.
1252
*
1253
- * @return boolean Either TRUE or FALSE in case WordPress is being used as a multi-site instance.
1254
- */
1255
- function sucuriscan_is_multisite(){
1256
- if( function_exists('is_multisite') && is_multisite() ){ return TRUE; }
1257
- return FALSE;
1258
- }
1259
-
1260
- /**
1261
- * Check whether the IP address specified is a valid IPv4 format.
1262
*
1263
- * @param string $remote_addr The host IP address.
1264
- * @return boolean TRUE if the address specified is a valid IPv4 format, FALSE otherwise.
1265
*/
1266
- function sucuriscan_is_valid_ipv4( $remote_addr='' ){
1267
- if( preg_match('/^([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})#x2F;', $remote_addr, $match) ){
1268
- for( $i=0; $i<4; $i++ ){
1269
- if( $match[$i] > 255 ){ return FALSE; }
1270
}
1271
1272
- return TRUE;
1273
}
1274
1275
- return FALSE;
1276
- }
1277
-
1278
- if( !function_exists('sucuriscan_init') ){
1279
/**
1280
- * Initialization code for the plugin.
1281
*
1282
- * The initial variables and information needed by the plugin during the
1283
- * execution of other functions will be generated. Things like the real IP
1284
- * address of the client when it has been forwarded or it's behind an external
1285
- * service like a Proxy.
1286
*
1287
- * @return void
1288
*/
1289
- function sucuriscan_init(){
1290
- if(
1291
- isset($_SERVER['HTTP_X_FORWARDED_FOR'])
1292
- && preg_match("/^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+#x2F;", $_SERVER['HTTP_X_FORWARDED_FOR'])
1293
- && sucuriscan_is_valid_ipv4($_SERVER['HTTP_X_FORWARDED_FOR'])
1294
- ){
1295
- $_SERVER['SUCURIREAL_REMOTE_ADDR'] = $_SERVER['REMOTE_ADDR'];
1296
- $_SERVER['REMOTE_ADDR'] = $_SERVER['HTTP_X_FORWARDED_FOR'];
1297
- }
1298
- }
1299
1300
- add_action('init', 'sucuriscan_init', 1);
1301
- }
1302
1303
- if( !function_exists('sucuriscan_create_uploaddir') ){
1304
/**
1305
- * Create a folder in the WordPress upload directory where the plugin will
1306
- * store all the temporal or dynamic information.
1307
*
1308
- * @return void
1309
*/
1310
- function sucuriscan_create_uploaddir(){
1311
- $plugin_upload_folder = sucuriscan_dir_filepath();
1312
1313
- if( !file_exists($plugin_upload_folder) ){
1314
- if( @mkdir($plugin_upload_folder) ){
1315
- // Create last-logins datastore file.
1316
- sucuriscan_lastlogins_datastore_exists();
1317
1318
- // Create a htaccess file to deny access from all.
1319
- @file_put_contents(
1320
- $plugin_upload_folder . '/.htaccess',
1321
- "Order Deny,Allow\nDeny from all",
1322
- LOCK_EX
1323
- );
1324
1325
- // Create an index.html to avoid directory listing.
1326
- @file_put_contents(
1327
- $plugin_upload_folder . '/index.html',
1328
- '<!-- Attemp to prevent the directory listing. -->',
1329
- LOCK_EX
1330
- );
1331
- } else {
1332
- sucuriscan_error(
1333
- 'Data folder does not exists and could not be created. You will need to
1334
- create this folder manually and give it write permissions:<br><br><code>'
1335
- . $plugin_upload_folder . '</code>'
1336
- );
1337
- }
1338
}
1339
- }
1340
1341
- add_action('admin_init', 'sucuriscan_create_uploaddir');
1342
- }
1343
1344
- if( !function_exists('sucuriscan_admin_script_style_registration') ){
1345
/**
1346
- * Define which javascript and css files will be loaded in the header of the page.
1347
- * @return void
1348
*/
1349
- function sucuriscan_admin_script_style_registration(){
1350
- $asset_version = '';
1351
-
1352
- if( strlen(SUCURISCAN_PLUGIN_CHECKSUM) >= 7 ){
1353
- $asset_version = substr(SUCURISCAN_PLUGIN_CHECKSUM, 0, 7);
1354
}
1355
1356
- wp_register_style( 'sucuriscan', SUCURI_URL . '/inc/css/sucuriscan-default-css.css', array(), $asset_version );
1357
- wp_register_script( 'sucuriscan', SUCURI_URL . '/inc/js/sucuriscan-scripts.js', array(), $asset_version );
1358
1359
- wp_enqueue_style( 'sucuriscan' );
1360
- wp_enqueue_script( 'sucuriscan' );
1361
}
1362
1363
- add_action( 'admin_enqueue_scripts', 'sucuriscan_admin_script_style_registration', 1 );
1364
- }
1365
-
1366
- /**
1367
- * Returns the system filepath to the relevant user uploads directory for this
1368
- * site. This is a multisite capable function.
1369
- *
1370
- * @param string $path The relative path that needs to be completed to get the absolute path.
1371
- * @return string The full filesystem path including the directory specified.
1372
- */
1373
- function sucuriscan_dir_filepath($path = ''){
1374
- return SucuriScan::datastore_folder_path($path);
1375
- }
1376
-
1377
- /**
1378
- * List an associative array with the sub-pages of this plugin.
1379
- *
1380
- * @param boolean $for_navbar Either TRUE or FALSE indicanting that the first page will be named Dashboard.
1381
- * @return array List of pages and sub-pages of this plugin.
1382
- */
1383
- function sucuriscan_pages( $for_navbar=FALSE ){
1384
- $pages = array(
1385
- 'sucuriscan' => 'Dashboard',
1386
- 'sucuriscan_scanner' => 'Malware Scan',
1387
- 'sucuriscan_monitoring' => 'Firewall (WAF)',
1388
- 'sucuriscan_hardening' => 'Hardening',
1389
- 'sucuriscan_posthack' => 'Post-Hack',
1390
- 'sucuriscan_lastlogins' => 'Last Logins',
1391
- 'sucuriscan_settings' => 'Settings',
1392
- 'sucuriscan_infosys' => 'Site Info',
1393
- );
1394
-
1395
- return $pages;
1396
- }
1397
1398
- /**
1399
- * Generate the menu and submenus for the plugin in the admin interface.
1400
- *
1401
- * @return void
1402
- */
1403
- function sucuriscan_menu(){
1404
- // Add main menu link.
1405
- add_menu_page(
1406
- 'Sucuri Security',
1407
- 'Sucuri Security',
1408
- 'manage_options',
1409
- 'sucuriscan',
1410
- 'sucuriscan_page',
1411
- SUCURI_URL . '/inc/images/menu-icon.png'
1412
- );
1413
1414
- $sub_pages = sucuriscan_pages();
1415
1416
- foreach( $sub_pages as $sub_page_func => $sub_page_title ){
1417
- $page_func = $sub_page_func . '_page';
1418
1419
- add_submenu_page(
1420
- 'sucuriscan',
1421
- $sub_page_title,
1422
- $sub_page_title,
1423
- 'manage_options',
1424
- $sub_page_func,
1425
- $page_func
1426
- );
1427
}
1428
- }
1429
1430
- if( !function_exists('sucuriscan_handle_old_plugin') ){
1431
/**
1432
- * Remove the old Sucuri plugins considering that with the new version (after
1433
- * 1.6.0) all the functionality of the others will be merged here, this will
1434
- * remove duplicated functionality, duplicated bugs and/or duplicated
1435
- * maintenance reports allowing us to focus in one unique project.
1436
*
1437
- * @return void
1438
*/
1439
- function sucuriscan_handle_old_plugin(){
1440
- $sucuri_fileinfo = new SucuriScanFileInfo();
1441
- $sucuri_fileinfo->ignore_files = FALSE;
1442
- $sucuri_fileinfo->ignore_directories = FALSE;
1443
-
1444
- $plugins = array(
1445
- 'sucuri-wp-plugin/sucuri.php',
1446
- 'sucuri-cloudproxy-waf/cloudproxy.php',
1447
);
1448
1449
- foreach( $plugins as $plugin ){
1450
- $plugin_directory = dirname( WP_PLUGIN_DIR . '/' . $plugin );
1451
-
1452
- if( file_exists($plugin_directory) ){
1453
- if( is_plugin_active($plugin) ){
1454
- deactivate_plugins($plugin);
1455
}
1456
1457
- $plugin_removed = $sucuri_fileinfo->remove_directory_tree($plugin_directory);
1458
}
1459
}
1460
}
1461
1462
- add_action('admin_init', 'sucuriscan_handle_old_plugin');
1463
- }
1464
1465
- /**
1466
- * Initialize the execute of the main plugin's functions.
1467
- *
1468
- * This will load the menu options in the WordPress administrator panel, and
1469
- * execute the bootstrap function of the plugin.
1470
- */
1471
- add_action('admin_menu', 'sucuriscan_menu');
1472
- add_action('sucuriscan_scheduled_scan', 'sucuriscan_filesystem_scan');
1473
- remove_action('wp_head', 'wp_generator');
1474
1475
- /**
1476
- * Validate email address.
1477
- *
1478
- * This use the native PHP function filter_var which is available in PHP >=
1479
- * 5.2.0 if it is not found in the interpreter this function will sue regular
1480
- * expressions to check whether the email address passed is valid or not.
1481
- *
1482
- * @see http://www.php.net/manual/en/function.filter-var.php
1483
- *
1484
- * @param string $email The string that will be validated as an email address.
1485
- * @return boolean TRUE if the email address passed to the function is valid, FALSE if not.
1486
- */
1487
- function is_valid_email( $email='' ){
1488
- if( function_exists('filter_var') ){
1489
- return (bool) filter_var($email, FILTER_VALIDATE_EMAIL);
1490
- } else {
1491
- $pattern = '/^([a-z0-9\+_\-]+)(\.[a-z0-9\+_\-]+)*@([a-z0-9\-]+\.)+[a-z]{2,6}#x2F;ix';
1492
- return (bool) preg_match($pattern, $email);
1493
}
1494
- }
1495
1496
- /**
1497
- * Cut a long text to the length specified, and append suspensive points at the end.
1498
- *
1499
- * @param string $text String of characters that will be cut.
1500
- * @param integer $length Maximum length of the returned string, default is 10.
1501
- * @return string Short version of the text specified.
1502
- */
1503
- function sucuriscan_excerpt( $text='', $length=10 ){
1504
- $text_length = strlen($text);
1505
1506
- if( $text_length > $length ){
1507
- return substr( $text, 0, $length ) . '...';
1508
}
1509
1510
- return $text;
1511
- }
1512
1513
- /**
1514
- * Check whether the email notifications will be sent in HTML or Plain/Text.
1515
- *
1516
- * @return boolean Whether the emails will be in HTML or Plain/Text.
1517
- */
1518
- function sucuriscan_prettify_mails(){
1519
- return ( sucuriscan_get_option('sucuriscan_prettify_mails') === 'enabled' );
1520
- }
1521
1522
- /**
1523
- * Check whether the SSL certificates will be verified while executing a HTTP
1524
- * request or not. This is only for customization of the administrator, in fact
1525
- * not verifying the SSL certificates can lead to a "Man in the Middle" attack.
1526
- *
1527
- * @return boolean Whether the SSL certs will be verified while sending a request.
1528
- */
1529
- function sucuriscan_verify_ssl_cert(){
1530
- return ( sucuriscan_get_option('sucuriscan_verify_ssl_cert') === 'true' );
1531
- }
1532
1533
- /**
1534
- * Send a message to a specific email address.
1535
- *
1536
- * @param string $email The email address of the recipient that will receive the message.
1537
- * @param string $subject The reason of the message that will be sent.
1538
- * @param string $message Body of the message that will be sent.
1539
- * @param array $data_set Optional parameter to add more information to the notification.
1540
- * @return boolean Whether the email contents were sent successfully.
1541
- */
1542
- function sucuriscan_send_mail( $email='', $subject='', $message='', $data_set=array() ){
1543
- $headers = array();
1544
- $subject = ucwords(strtolower($subject));
1545
- $wp_domain = isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : get_option('siteurl');
1546
- $force = FALSE;
1547
- $debug = FALSE;
1548
-
1549
- // Check whether the mail will be printed in the site instead of sent.
1550
- if(
1551
- isset($data_set['Debug'])
1552
- && $data_set['Debug'] == TRUE
1553
- ){
1554
- $debug = TRUE;
1555
- unset($data_set['Debug']);
1556
- }
1557
1558
- // Check whether the mail will be even if the limit per hour was reached or not.
1559
- if(
1560
- isset($data_set['Force'])
1561
- && $data_set['Force'] == TRUE
1562
- ){
1563
- $force = TRUE;
1564
- unset($data_set['Force']);
1565
}
1566
1567
- // Check whether the email notifications will be sent in HTML or Plain/Text.
1568
- if( sucuriscan_prettify_mails() ){
1569
- $headers = array( 'Content-type: text/html' );
1570
- $data_set['PrettifyType'] = 'pretty';
1571
- }
1572
1573
- if( !sucuriscan_emails_per_hour_reached() || $force || $debug ){
1574
- $message = sucuriscan_prettify_mail($subject, $message, $data_set);
1575
1576
- if( $debug ){ die($message); }
1577
1578
- $email_sent = wp_mail(
1579
- $email,
1580
- "Sucuri WP Notification: {$wp_domain} - {$subject}",
1581
- $message,
1582
- $headers
1583
- );
1584
1585
- if( $email_sent ){
1586
- $emails_sent_num = (int) sucuriscan_get_option('sucuriscan_emails_sent');
1587
- update_option( 'sucuriscan_emails_sent', $emails_sent_num + 1 );
1588
- update_option( 'sucuriscan_last_email_at', time() );
1589
1590
- return TRUE;
1591
}
1592
- } else {
1593
- // sucuriscan_error( 'Cant send more emails for the next hour' );
1594
- }
1595
1596
- return FALSE;
1597
- }
1598
1599
- /**
1600
- * Check whether the maximum quantity of emails per hour was reached.
1601
- *
1602
- * @return boolean Whether the quota emails per hour was reached.
1603
- */
1604
- function sucuriscan_emails_per_hour_reached(){
1605
- $max_emails_per_hour = sucuriscan_get_option('sucuriscan_emails_per_hour');
1606
1607
- if( $max_emails_per_hour != 'unlimited' ){
1608
- // Check if we are still in that sixty minutes.
1609
- $current_time = time();
1610
- $last_email_at = sucuriscan_get_option('sucuriscan_last_email_at');
1611
- $diff_time = abs( $current_time - $last_email_at );
1612
1613
- if( $diff_time <= 3600 ){
1614
- // Check if the quantity of emails sent is bigger than the configured.
1615
- $emails_sent = (int) sucuriscan_get_option('sucuriscan_emails_sent');
1616
- $max_emails_per_hour = intval($max_emails_per_hour);
1617
1618
- if( $emails_sent >= $max_emails_per_hour ){
1619
- return TRUE;
1620
}
1621
- } else {
1622
- // Reset the counter of emails sent.
1623
- update_option( 'sucuriscan_emails_sent', 0 );
1624
}
1625
}
1626
1627
- return FALSE;
1628
- }
1629
1630
- /**
1631
- * Generate a HTML version of the message that will be sent through an email.
1632
- *
1633
- * @param string $subject The reason of the message that will be sent.
1634
- * @param string $message Body of the message that will be sent.
1635
- * @param array $data_set Optional parameter to add more information to the notification.
1636
- * @return string The message formatted in a HTML template.
1637
- */
1638
- function sucuriscan_prettify_mail( $subject='', $message='', $data_set=array() ){
1639
- $prettify_type = isset($data_set['PrettifyType']) ? $data_set['PrettifyType'] : 'simple';
1640
- $template_name = 'notification-' . $prettify_type;
1641
- $remote_addr = sucuriscan_get_remoteaddr();
1642
- $user = wp_get_current_user();
1643
- $display_name = '';
1644
1645
- if(
1646
- $user instanceof WP_User
1647
- && isset($user->user_login)
1648
- && !empty($user->user_login)
1649
- ){
1650
- $display_name = sprintf( 'User: %s (%s)', $user->display_name, $user->user_login );
1651
}
1652
1653
- $mail_variables = array(
1654
- 'TemplateTitle' => 'Sucuri WP Notification',
1655
- 'Subject' => $subject,
1656
- 'Website' => get_option('siteurl'),
1657
- 'RemoteAddress' => $remote_addr,
1658
- 'Message' => $message,
1659
- 'User' => $display_name,
1660
- 'Time' => current_time('mysql'),
1661
- );
1662
1663
- foreach($data_set as $var_key=>$var_value){
1664
- $mail_variables[$var_key] = $var_value;
1665
}
1666
1667
- return sucuriscan_get_section( $template_name, $mail_variables );
1668
- }
1669
1670
- /**
1671
- * Prints a HTML alert in the WordPress admin interface.
1672
- *
1673
- * @param string $type The type of alert, it can be either Updated or Error.
1674
- * @param string $message The message that will be printed in the alert.
1675
- * @return void
1676
- */
1677
- function sucuriscan_admin_notice($type='updated', $message=''){
1678
- $alert_id = rand(100, 999);
1679
- if( !empty($message) ): ?>
1680
- <div id="sucuriscan-alert-<?php echo $alert_id; ?>" class="<?php echo $type; ?> sucuriscan-alert sucuriscan-alert-<?php echo $type; ?>">
1681
- <a href="javascript:void(0)" class="close" onclick="sucuriscan_alert_close('<?php echo $alert_id; ?>')">&times;</a>
1682
- <p><?php _e($message); ?></p>
1683
- </div>
1684
- <?php endif;
1685
- }
1686
1687
- /**
1688
- * Prints a HTML alert of type ERROR in the WordPress admin interface.
1689
- *
1690
- * @param string $error_msg The message that will be printed in the alert.
1691
- * @return void
1692
- */
1693
- function sucuriscan_error( $error_msg='' ){
1694
- sucuriscan_admin_notice( 'error', '<b>Sucuri:</b> ' . $error_msg );
1695
- }
1696
1697
- /**
1698
- * Prints a HTML alert of type INFO in the WordPress admin interface.
1699
- *
1700
- * @param string $info_msg The message that will be printed in the alert.
1701
- * @return void
1702
- */
1703
- function sucuriscan_info( $info_msg='' ){
1704
- sucuriscan_admin_notice( 'updated', '<b>Sucuri:</b> ' . $info_msg );
1705
- }
1706
1707
- /**
1708
- * Verify the nonce of the previous page after a form submission. If the
1709
- * validation fails the execution of the script will be stopped and a dead page
1710
- * will be printed to the client using the official WordPress method.
1711
- *
1712
- * @return boolean Either TRUE or FALSE if the nonce is valid or not respectively.
1713
- */
1714
- function sucuriscan_check_page_nonce(){
1715
- if( !empty($_POST) ){
1716
- $nonce_name = 'sucuriscan_page_nonce';
1717
1718
- if( !isset($_POST[$nonce_name]) || !wp_verify_nonce($_POST[$nonce_name], $nonce_name) ){
1719
- wp_die(__('WordPress Nonce verification failed, try again going back and checking the form.') );
1720
1721
- return FALSE;
1722
}
1723
- }
1724
1725
- return TRUE;
1726
- }
1727
-
1728
- /**
1729
- * Replace all pseudo-variables from a string of characters.
1730
- *
1731
- * @param string $content The content of a template file which contains pseudo-variables.
1732
- * @param array $params List of pseudo-variables that will be replaced in the template.
1733
- * @return string The content of the template with the pseudo-variables replated.
1734
- */
1735
- function sucuriscan_replace_pseudovars( $content='', $params=array() ){
1736
- if( is_array($params) ){
1737
- foreach( $params as $tpl_key => $tpl_value ){
1738
- $tpl_key = '%%SUCURI.' . $tpl_key . '%%';
1739
- $content = str_replace( $tpl_key, $tpl_value, $content );
1740
}
1741
1742
- return $content;
1743
}
1744
1745
- return FALSE;
1746
}
1747
1748
/**
1749
- * Complement the list of pseudo-variables that will be used in the base
1750
- * template files, this will also generate the navigation bar and detect which
1751
- * items in it are selected by the current page.
1752
*
1753
- * @param array $params A hash containing the pseudo-variable name as the key and the value that will replace it.
1754
- * @return array A complementary list of pseudo-variables for the template files.
1755
*/
1756
- function sucuriscan_links_and_navbar( $params=array() ){
1757
- $params = is_array($params) ? $params : array();
1758
- $sub_pages = sucuriscan_pages(TRUE);
1759
1760
- $params['Navbar'] = '';
1761
- $params['CurrentPageFunc'] = isset($_GET['page']) ? $_GET['page'] : '';
1762
-
1763
- foreach( $sub_pages as $sub_page_func => $sub_page_title ){
1764
- $func_parts = explode( '_', $sub_page_func, 2 );
1765
1766
- if( isset($func_parts[1]) ){
1767
- $unique_name = $func_parts[1];
1768
- $pseudo_var = 'URL.' . ucwords($unique_name);
1769
- } else {
1770
- $unique_name = '';
1771
- $pseudo_var = 'URL.Home';
1772
}
1773
1774
- $params[$pseudo_var] = sucuriscan_get_url($unique_name);
1775
1776
- $navbar_item_css_class = 'nav-tab';
1777
1778
- if( $params['CurrentPageFunc'] == $sub_page_func ){
1779
- $navbar_item_css_class .= chr(32) . 'nav-tab-active';
1780
}
1781
1782
- $params['Navbar'] .= sprintf(
1783
- '<a class="%s" href="%s">%s</a>' . "\n",
1784
- $navbar_item_css_class,
1785
- $params[$pseudo_var],
1786
- $sub_page_title
1787
- );
1788
- }
1789
1790
- return $params;
1791
- }
1792
1793
- /**
1794
- * Generate a HTML code using a template and replacing all the pseudo-variables
1795
- * by the dynamic variables provided by the developer through one of the parameters
1796
- * of the function.
1797
- *
1798
- * @param string $template Filename of the template that will be used to generate the page.
1799
- * @param array $params A hash containing the pseudo-variable name as the key and the value that will replace it.
1800
- * @param boolean $type Either page, section or snippet indicating the type of template that will be retrieved.
1801
- * @return string The formatted HTML page after replace all the pseudo-variables.
1802
- */
1803
- function sucuriscan_get_template( $template='', $params=array(), $type='page' ){
1804
- switch( $type ){
1805
- case 'page': /* no_break */
1806
- case 'section':
1807
- $template_path_pattern = '%s/%s/inc/tpl/%s.html.tpl';
1808
- break;
1809
- case 'snippet':
1810
- $template_path_pattern = '%s/%s/inc/tpl/%s.snippet.tpl';
1811
- break;
1812
- }
1813
1814
- $template_content = '';
1815
- $template_path = sprintf( $template_path_pattern, WP_PLUGIN_DIR, SUCURISCAN_PLUGIN_FOLDER, $template );
1816
- $params = is_array($params) ? $params : array();
1817
1818
- if( file_exists($template_path) && is_readable($template_path) ){
1819
- $template_content = file_get_contents($template_path);
1820
1821
- $current_page = isset($_GET['page']) ? htmlentities($_GET['page']) : '';
1822
- $params['CurrentURL'] = sprintf( '%s/wp-admin/admin.php?page=%s', site_url(), $current_page );
1823
- $params['SucuriURL'] = SUCURI_URL;
1824
1825
- // Replace the global pseudo-variables in the section/snippets templates.
1826
- if(
1827