Version Description
- Fixed remote scanning that was not loading automatically on some installs.
Download this release
Release Info
Developer | dd@sucuri.net |
Plugin | Sucuri Security – Auditing, Malware Scanner and Security Hardening |
Version | 1.7.1 |
Comparing to | |
See all releases |
Code changes from version 1.7.0 to 1.7.1
- inc/css/sucuriscan-default-css.css +4 -3
- inc/tpl/posthack-resetpassword.html.tpl +1 -1
- inc/tpl/settings-general.html.tpl +0 -87
- inc/tpl/settings-ignorescanning.html.tpl +62 -0
- inc/tpl/settings-ignorescanning.snippet.tpl +9 -0
- inc/tpl/settings-scanner.html.tpl +128 -0
- inc/tpl/settings.html.tpl +16 -2
- readme.txt +82 -1
- sucuri.php +388 -101
inc/css/sucuriscan-default-css.css
CHANGED
@@ -103,11 +103,12 @@
|
|
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{}
|
113 |
.sucuriscan-tabs > ul{margin:0}
|
@@ -222,6 +223,7 @@ div.sucuriscan-alert > a.close{position:absolute;top:10px;right:10px;font-size:1
|
|
222 |
.sucuriscan-maincontent .sucuriscan-settings form{display:inline-block}
|
223 |
.sucuriscan-maincontent .sucuriscan-settings select, .sucuriscan-maincontent .sucuriscan-settings .input-text{width:220px}
|
224 |
.sucuriscan-maincontent .sucuriscan-settings-notifications{margin-top:0}
|
|
|
225 |
.sucuriscan-maincontent .sucuriscan-settings-heartbeat{}
|
226 |
.sucuriscan-maincontent .sucuriscan-wpcron-list{margin-top:0}
|
227 |
/* Responsive Styles */
|
@@ -247,7 +249,6 @@ div.sucuriscan-alert > a.close{position:absolute;top:10px;right:10px;font-size:1
|
|
247 |
.sucuriscan-maincontent #poststuff{min-width:initial;padding-top:0}
|
248 |
.sucuriscan-maincontent .widefat tbody th.check-column{padding:6px 0 3px 0}
|
249 |
.sucuriscan-maincontent .hardening-box .primary-secondary{margin:0 0 0 10px}
|
250 |
-
.sucuri-inline-error{font-weight:bold;color:red}
|
251 |
.sucuriscan-maincontent .alternate{background:#f5f5f5}
|
252 |
.sucuriscan-maincontent hr{border:none;border-top:1px solid #999}
|
253 |
.sucuriscan-maincontent table td > table{background:#fff}
|
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, .sucuriscan-inline-alert-info{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, .sucuriscan-inline-alert-info > 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 |
+
.sucuriscan-inline-alert-info{border-left-color:#2ea2cc}
|
112 |
/* Tabulation Panels */
|
113 |
.sucuriscan-tabs{}
|
114 |
.sucuriscan-tabs > ul{margin:0}
|
223 |
.sucuriscan-maincontent .sucuriscan-settings form{display:inline-block}
|
224 |
.sucuriscan-maincontent .sucuriscan-settings select, .sucuriscan-maincontent .sucuriscan-settings .input-text{width:220px}
|
225 |
.sucuriscan-maincontent .sucuriscan-settings-notifications{margin-top:0}
|
226 |
+
.sucuriscan-maincontent .sucuriscan-settings-ignorescanning{margin-top:0}
|
227 |
.sucuriscan-maincontent .sucuriscan-settings-heartbeat{}
|
228 |
.sucuriscan-maincontent .sucuriscan-wpcron-list{margin-top:0}
|
229 |
/* Responsive Styles */
|
249 |
.sucuriscan-maincontent #poststuff{min-width:initial;padding-top:0}
|
250 |
.sucuriscan-maincontent .widefat tbody th.check-column{padding:6px 0 3px 0}
|
251 |
.sucuriscan-maincontent .hardening-box .primary-secondary{margin:0 0 0 10px}
|
|
|
252 |
.sucuriscan-maincontent .alternate{background:#f5f5f5}
|
253 |
.sucuriscan-maincontent hr{border:none;border-top:1px solid #999}
|
254 |
.sucuriscan-maincontent table td > table{background:#fff}
|
inc/tpl/posthack-resetpassword.html.tpl
CHANGED
@@ -15,7 +15,7 @@
|
|
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
|
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>
|
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 immediately. 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>
|
inc/tpl/settings-general.html.tpl
CHANGED
@@ -127,92 +127,5 @@
|
|
127 |
</td>
|
128 |
</tr>
|
129 |
|
130 |
-
<tr class="alternate">
|
131 |
-
<td>Filesystem scanner</td>
|
132 |
-
<td>%%SUCURI.FsScannerStatus%%</td>
|
133 |
-
<td class="td-with-button">
|
134 |
-
<form action="%%SUCURI.URL.Settings%%" method="post">
|
135 |
-
<input type="hidden" name="sucuriscan_page_nonce" value="%%SUCURI.PageNonce%%" />
|
136 |
-
<input type="hidden" name="sucuriscan_fs_scanner" value="%%SUCURI.FsScannerSwitchValue%%" />
|
137 |
-
<button type="submit" class="button-primary %%SUCURI.FsScannerSwitchCssClass%%">%%SUCURI.FsScannerSwitchText%%</button>
|
138 |
-
</form>
|
139 |
-
</td>
|
140 |
-
</tr>
|
141 |
-
|
142 |
-
<tr>
|
143 |
-
<td>Scan modified files</td>
|
144 |
-
<td>%%SUCURI.ScanModfilesStatus%%</td>
|
145 |
-
<td class="td-with-button">
|
146 |
-
<form action="%%SUCURI.URL.Settings%%" method="post">
|
147 |
-
<input type="hidden" name="sucuriscan_page_nonce" value="%%SUCURI.PageNonce%%" />
|
148 |
-
<input type="hidden" name="sucuriscan_scan_modfiles" value="%%SUCURI.ScanModfilesSwitchValue%%" />
|
149 |
-
<button type="submit" class="button-primary %%SUCURI.ScanModfilesSwitchCssClass%%">%%SUCURI.ScanModfilesSwitchText%%</button>
|
150 |
-
</form>
|
151 |
-
</td>
|
152 |
-
</tr>
|
153 |
-
|
154 |
-
<tr class="alternate">
|
155 |
-
<td>Integrity checking</td>
|
156 |
-
<td>%%SUCURI.ScanChecksumsStatus%%</td>
|
157 |
-
<td class="td-with-button">
|
158 |
-
<form action="%%SUCURI.URL.Settings%%" method="post">
|
159 |
-
<input type="hidden" name="sucuriscan_page_nonce" value="%%SUCURI.PageNonce%%" />
|
160 |
-
<input type="hidden" name="sucuriscan_scan_checksums" value="%%SUCURI.ScanChecksumsSwitchValue%%" />
|
161 |
-
<button type="submit" class="button-primary %%SUCURI.ScanChecksumsSwitchCssClass%%">%%SUCURI.ScanChecksumsSwitchText%%</button>
|
162 |
-
</form>
|
163 |
-
</td>
|
164 |
-
</tr>
|
165 |
-
|
166 |
-
<tr>
|
167 |
-
<td>Scan error log files</td>
|
168 |
-
<td>%%SUCURI.ScanErrorlogsStatus%%</td>
|
169 |
-
<td class="td-with-button">
|
170 |
-
<form action="%%SUCURI.URL.Settings%%" method="post">
|
171 |
-
<input type="hidden" name="sucuriscan_page_nonce" value="%%SUCURI.PageNonce%%" />
|
172 |
-
<input type="hidden" name="sucuriscan_scan_errorlogs" value="%%SUCURI.ScanErrorlogsSwitchValue%%" />
|
173 |
-
<button type="submit" class="button-primary %%SUCURI.ScanErrorlogsSwitchCssClass%%">%%SUCURI.ScanErrorlogsSwitchText%%</button>
|
174 |
-
</form>
|
175 |
-
</td>
|
176 |
-
</tr>
|
177 |
-
|
178 |
-
<tr class="alternate">
|
179 |
-
<td>Last Scanning</td>
|
180 |
-
<td><span class="sucuriscan-monospace">%%SUCURI.ScanningRuntimeHuman%%</span></td>
|
181 |
-
<td class="td-with-button">
|
182 |
-
<form action="%%SUCURI.URL.Home%%" method="post">
|
183 |
-
<input type="hidden" name="sucuriscan_page_nonce" value="%%SUCURI.PageNonce%%" />
|
184 |
-
<button type="submit" name="sucuriscan_force_scan" class="button-primary">Force Scan</button>
|
185 |
-
</form>
|
186 |
-
</td>
|
187 |
-
</tr>
|
188 |
-
|
189 |
-
<tr>
|
190 |
-
<td>Scanning frequency</td>
|
191 |
-
<td>%%SUCURI.ScanningFrequency%%</td>
|
192 |
-
<td class="td-with-button">
|
193 |
-
<form action="%%SUCURI.URL.Settings%%" method="post">
|
194 |
-
<input type="hidden" name="sucuriscan_page_nonce" value="%%SUCURI.PageNonce%%" />
|
195 |
-
<select name="sucuriscan_scan_frequency">
|
196 |
-
%%SUCURI.ScanningFrequencyOptions%%
|
197 |
-
</select>
|
198 |
-
<button type="submit" class="button-primary">Change</button>
|
199 |
-
</form>
|
200 |
-
</td>
|
201 |
-
</tr>
|
202 |
-
|
203 |
-
<tr class="alternate sucuriscan-%%SUCURI.ScanningInterfaceVisibility%%">
|
204 |
-
<td>Scanning interface</td>
|
205 |
-
<td>%%SUCURI.ScanningInterface%%</td>
|
206 |
-
<td class="td-with-button">
|
207 |
-
<form action="%%SUCURI.URL.Settings%%" method="post">
|
208 |
-
<input type="hidden" name="sucuriscan_page_nonce" value="%%SUCURI.PageNonce%%" />
|
209 |
-
<select name="sucuriscan_scan_interface">
|
210 |
-
%%SUCURI.ScanningInterfaceOptions%%
|
211 |
-
</select>
|
212 |
-
<button type="submit" class="button-primary">Change</button>
|
213 |
-
</form>
|
214 |
-
</td>
|
215 |
-
</tr>
|
216 |
-
|
217 |
</tbody>
|
218 |
</table>
|
127 |
</td>
|
128 |
</tr>
|
129 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
130 |
</tbody>
|
131 |
</table>
|
inc/tpl/settings-ignorescanning.html.tpl
ADDED
@@ -0,0 +1,62 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
|
2 |
+
<div id="poststuff">
|
3 |
+
<div class="postbox sucuriscan-border sucuriscan-table-description">
|
4 |
+
<h3>Ignore Scanning</h3>
|
5 |
+
|
6 |
+
<div class="inside">
|
7 |
+
<p>
|
8 |
+
If your project has too many directories and/or files it may cause the file
|
9 |
+
system scanners to fail, you may want to increase the maximum execution time of
|
10 |
+
the PHP scripts and the memory limit to allow the functions executed during the
|
11 |
+
file system scans to finish successfully. If you do not want or do not have
|
12 |
+
sufficient privileges to increase these values then you may want to skip some
|
13 |
+
directories, this will force the plugin to ignore the files inside these
|
14 |
+
folders.
|
15 |
+
</p>
|
16 |
+
</div>
|
17 |
+
</div>
|
18 |
+
</div>
|
19 |
+
|
20 |
+
<form action="%%SUCURI.URL.Settings%%#settings-ignorescanning" method="post">
|
21 |
+
<input type="hidden" name="sucuriscan_page_nonce" value="%%SUCURI.PageNonce%%" />
|
22 |
+
|
23 |
+
<table class="wp-list-table widefat sucuriscan-table sucuriscan-settings-ignorescanning">
|
24 |
+
<thead>
|
25 |
+
<th class="manage-column column-cb check-column">
|
26 |
+
<label class="screen-reader-text" for="cb-select-all-1">Select All</label>
|
27 |
+
<input id="cb-select-all-1" type="checkbox">
|
28 |
+
</th>
|
29 |
+
<th class="manage-column" width="80">Ignored</th>
|
30 |
+
<th class="manage-column">Directory</th>
|
31 |
+
<th class="manage-column" width="180">Ignored At</th>
|
32 |
+
</thead>
|
33 |
+
|
34 |
+
<tbody>
|
35 |
+
%%SUCURI.IgnoreScanning.ResourceList%%
|
36 |
+
</tbody>
|
37 |
+
|
38 |
+
<tfoot>
|
39 |
+
<tr>
|
40 |
+
<td colspan="4">
|
41 |
+
<p>
|
42 |
+
Selecting one or more directories from the list will force the plugin to ignore
|
43 |
+
the monitoring of the sub-folders and files inside these directories during the
|
44 |
+
execution of any of the file system scanners. This will applies to all the
|
45 |
+
scanners <em>(general scanner, modified files, integrity checks, error
|
46 |
+
logs)</em>.
|
47 |
+
</p>
|
48 |
+
|
49 |
+
<label>
|
50 |
+
<select name="sucuriscan_ignorescanning_action">
|
51 |
+
<option value="">Choose action</option>
|
52 |
+
<option value="ignore">Ignore items</option>
|
53 |
+
<option value="unignore">Un-ignore items</option>
|
54 |
+
</select>
|
55 |
+
</label>
|
56 |
+
|
57 |
+
<button type="submit" class="button button-primary">Send action</button>
|
58 |
+
</td>
|
59 |
+
</tr>
|
60 |
+
</tfoot>
|
61 |
+
</table>
|
62 |
+
</form>
|
inc/tpl/settings-ignorescanning.snippet.tpl
ADDED
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
|
2 |
+
<tr class="%%SUCURI.IgnoreScanning.CssClass%%">
|
3 |
+
<td class="check-column">
|
4 |
+
<input type="checkbox" name="sucuriscan_ignorescanning_dirs[]" value="%%SUCURI.IgnoreScanning.DirectoryPath%%" />
|
5 |
+
</td>
|
6 |
+
<td><span class="sucuriscan-label-%%SUCURI.IgnoreScanning.IgnoredCssClass%%">%%SUCURI.IgnoreScanning.IgnoredAtText%%</span></td>
|
7 |
+
<td><span class="sucuriscan-monospace sucuriscan-wraptext">%%SUCURI.IgnoreScanning.DirectoryPath%%</span></td>
|
8 |
+
<td>%%SUCURI.IgnoreScanning.IgnoredAt%%</td>
|
9 |
+
</tr>
|
inc/tpl/settings-scanner.html.tpl
ADDED
@@ -0,0 +1,128 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
|
2 |
+
<div id="poststuff">
|
3 |
+
<div class="postbox sucuriscan-border sucuriscan-table-description">
|
4 |
+
<h3>Scanner Settings</h3>
|
5 |
+
|
6 |
+
<div class="inside">
|
7 |
+
<p>
|
8 |
+
There are multiple scanners implemented in the code of the plugin, all of them
|
9 |
+
are enabled by default and you can deactivate them separately without affect the
|
10 |
+
others. You may want to disable a scanner because your site has too many
|
11 |
+
directories and/or files to scan, or because the maximum quantity of memory
|
12 |
+
allowed for your project is not enough to execute one these functions. You can
|
13 |
+
enable and disable any of the scanners anything you want.
|
14 |
+
</p>
|
15 |
+
|
16 |
+
<div class="sucuriscan-inline-alert-info">
|
17 |
+
<p>
|
18 |
+
The <em>Scanning Interface</em> is the method that will be used internally to
|
19 |
+
retrieve the diretories and files inside the project when the file system
|
20 |
+
scanners are executed. In the best case <strong>SPL</strong> will be enough
|
21 |
+
<em>(and it is the default option)</em>, but with older versions of PHP you may
|
22 |
+
need to choose a different method like <strong>OpenDir</strong> or
|
23 |
+
<strong>Glob</strong> which provide the same results.
|
24 |
+
</p>
|
25 |
+
</div>
|
26 |
+
</div>
|
27 |
+
</div>
|
28 |
+
</div>
|
29 |
+
|
30 |
+
<table class="wp-list-table widefat sucuriscan-table sucuriscan-settings sucuriscan-settings-scanner">
|
31 |
+
<thead>
|
32 |
+
<tr>
|
33 |
+
<th>Option</th>
|
34 |
+
<th>Value</th>
|
35 |
+
<th> </th>
|
36 |
+
</tr>
|
37 |
+
</thead>
|
38 |
+
|
39 |
+
<tbody>
|
40 |
+
<tr class="alternate">
|
41 |
+
<td>Filesystem scanner</td>
|
42 |
+
<td>%%SUCURI.FsScannerStatus%%</td>
|
43 |
+
<td class="td-with-button">
|
44 |
+
<form action="%%SUCURI.URL.Settings%%#settings-scanner" method="post">
|
45 |
+
<input type="hidden" name="sucuriscan_page_nonce" value="%%SUCURI.PageNonce%%" />
|
46 |
+
<input type="hidden" name="sucuriscan_fs_scanner" value="%%SUCURI.FsScannerSwitchValue%%" />
|
47 |
+
<button type="submit" class="button-primary %%SUCURI.FsScannerSwitchCssClass%%">%%SUCURI.FsScannerSwitchText%%</button>
|
48 |
+
</form>
|
49 |
+
</td>
|
50 |
+
</tr>
|
51 |
+
|
52 |
+
<tr>
|
53 |
+
<td>Scan modified files</td>
|
54 |
+
<td>%%SUCURI.ScanModfilesStatus%%</td>
|
55 |
+
<td class="td-with-button">
|
56 |
+
<form action="%%SUCURI.URL.Settings%%#settings-scanner" method="post">
|
57 |
+
<input type="hidden" name="sucuriscan_page_nonce" value="%%SUCURI.PageNonce%%" />
|
58 |
+
<input type="hidden" name="sucuriscan_scan_modfiles" value="%%SUCURI.ScanModfilesSwitchValue%%" />
|
59 |
+
<button type="submit" class="button-primary %%SUCURI.ScanModfilesSwitchCssClass%%">%%SUCURI.ScanModfilesSwitchText%%</button>
|
60 |
+
</form>
|
61 |
+
</td>
|
62 |
+
</tr>
|
63 |
+
|
64 |
+
<tr class="alternate">
|
65 |
+
<td>Integrity checking</td>
|
66 |
+
<td>%%SUCURI.ScanChecksumsStatus%%</td>
|
67 |
+
<td class="td-with-button">
|
68 |
+
<form action="%%SUCURI.URL.Settings%%#settings-scanner" method="post">
|
69 |
+
<input type="hidden" name="sucuriscan_page_nonce" value="%%SUCURI.PageNonce%%" />
|
70 |
+
<input type="hidden" name="sucuriscan_scan_checksums" value="%%SUCURI.ScanChecksumsSwitchValue%%" />
|
71 |
+
<button type="submit" class="button-primary %%SUCURI.ScanChecksumsSwitchCssClass%%">%%SUCURI.ScanChecksumsSwitchText%%</button>
|
72 |
+
</form>
|
73 |
+
</td>
|
74 |
+
</tr>
|
75 |
+
|
76 |
+
<tr>
|
77 |
+
<td>Scan error log files</td>
|
78 |
+
<td>%%SUCURI.ScanErrorlogsStatus%%</td>
|
79 |
+
<td class="td-with-button">
|
80 |
+
<form action="%%SUCURI.URL.Settings%%#settings-scanner" method="post">
|
81 |
+
<input type="hidden" name="sucuriscan_page_nonce" value="%%SUCURI.PageNonce%%" />
|
82 |
+
<input type="hidden" name="sucuriscan_scan_errorlogs" value="%%SUCURI.ScanErrorlogsSwitchValue%%" />
|
83 |
+
<button type="submit" class="button-primary %%SUCURI.ScanErrorlogsSwitchCssClass%%">%%SUCURI.ScanErrorlogsSwitchText%%</button>
|
84 |
+
</form>
|
85 |
+
</td>
|
86 |
+
</tr>
|
87 |
+
|
88 |
+
<tr class="alternate">
|
89 |
+
<td>Last Scanning</td>
|
90 |
+
<td><span class="sucuriscan-monospace">%%SUCURI.ScanningRuntimeHuman%%</span></td>
|
91 |
+
<td class="td-with-button">
|
92 |
+
<form action="%%SUCURI.URL.Home%%" method="post">
|
93 |
+
<input type="hidden" name="sucuriscan_page_nonce" value="%%SUCURI.PageNonce%%" />
|
94 |
+
<button type="submit" name="sucuriscan_force_scan" class="button-primary">Force Scan</button>
|
95 |
+
</form>
|
96 |
+
</td>
|
97 |
+
</tr>
|
98 |
+
|
99 |
+
<tr>
|
100 |
+
<td>Scanning frequency</td>
|
101 |
+
<td>%%SUCURI.ScanningFrequency%%</td>
|
102 |
+
<td class="td-with-button">
|
103 |
+
<form action="%%SUCURI.URL.Settings%%#settings-scanner" method="post">
|
104 |
+
<input type="hidden" name="sucuriscan_page_nonce" value="%%SUCURI.PageNonce%%" />
|
105 |
+
<select name="sucuriscan_scan_frequency">
|
106 |
+
%%SUCURI.ScanningFrequencyOptions%%
|
107 |
+
</select>
|
108 |
+
<button type="submit" class="button-primary">Change</button>
|
109 |
+
</form>
|
110 |
+
</td>
|
111 |
+
</tr>
|
112 |
+
|
113 |
+
<tr class="alternate">
|
114 |
+
<td>Scanning interface</td>
|
115 |
+
<td>%%SUCURI.ScanningInterface%%</td>
|
116 |
+
<td class="td-with-button">
|
117 |
+
<form action="%%SUCURI.URL.Settings%%#settings-scanner" method="post">
|
118 |
+
<input type="hidden" name="sucuriscan_page_nonce" value="%%SUCURI.PageNonce%%" />
|
119 |
+
<select name="sucuriscan_scan_interface">
|
120 |
+
%%SUCURI.ScanningInterfaceOptions%%
|
121 |
+
</select>
|
122 |
+
<button type="submit" class="button-primary">Change</button>
|
123 |
+
</form>
|
124 |
+
</td>
|
125 |
+
</tr>
|
126 |
+
|
127 |
+
</tbody>
|
128 |
+
</table>
|
inc/tpl/settings.html.tpl
CHANGED
@@ -5,10 +5,16 @@
|
|
5 |
<a href="#" data-tabname="settings-general">General Settings</a>
|
6 |
</li>
|
7 |
<li>
|
8 |
-
<a href="#" data-tabname="settings-
|
9 |
</li>
|
10 |
<li>
|
11 |
-
<a href="#" data-tabname="settings-
|
|
|
|
|
|
|
|
|
|
|
|
|
12 |
</li>
|
13 |
<li>
|
14 |
<a href="#" data-tabname="settings-heartbeat">Heartbeat</a>
|
@@ -20,6 +26,14 @@
|
|
20 |
%%SUCURI.Settings.General%%
|
21 |
</div>
|
22 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
23 |
<div id="sucuriscan-settings-notifications">
|
24 |
%%SUCURI.Settings.Notifications%%
|
25 |
</div>
|
5 |
<a href="#" data-tabname="settings-general">General Settings</a>
|
6 |
</li>
|
7 |
<li>
|
8 |
+
<a href="#" data-tabname="settings-scanner">Scanner Settings</a>
|
9 |
</li>
|
10 |
<li>
|
11 |
+
<a href="#" data-tabname="settings-ignorescanning">Ignore Scanning</a>
|
12 |
+
</li>
|
13 |
+
<li>
|
14 |
+
<a href="#" data-tabname="settings-notifications">Alert Settings</a>
|
15 |
+
</li>
|
16 |
+
<li>
|
17 |
+
<a href="#" data-tabname="settings-ignorerules">Ignore Alerts</a>
|
18 |
</li>
|
19 |
<li>
|
20 |
<a href="#" data-tabname="settings-heartbeat">Heartbeat</a>
|
26 |
%%SUCURI.Settings.General%%
|
27 |
</div>
|
28 |
|
29 |
+
<div id="sucuriscan-settings-scanner">
|
30 |
+
%%SUCURI.Settings.Scanner%%
|
31 |
+
</div>
|
32 |
+
|
33 |
+
<div id="sucuriscan-settings-ignorescanning">
|
34 |
+
%%SUCURI.Settings.IgnoreScanning%%
|
35 |
+
</div>
|
36 |
+
|
37 |
<div id="sucuriscan-settings-notifications">
|
38 |
%%SUCURI.Settings.Notifications%%
|
39 |
</div>
|
readme.txt
CHANGED
@@ -3,7 +3,7 @@ Contributors: dd@sucuri.net
|
|
3 |
Donate Link: http://sitecheck.sucuri.net
|
4 |
Tags: malware, security, firewall, scan, spam, virus, sucuri, protection,WordPress Security, Login Security,Security Auditing,File Integrity,htaccess,phishing,backdoors,SQL Injection, RFI, LFI, XSS, CSRF,
|
5 |
Requires at least:3.2
|
6 |
-
Stable tag:1.7.
|
7 |
Tested up to: 4.0
|
8 |
|
9 |
The Sucuri WordPress Security plugin is the best security toolset for security integrity monitoring, activity monitoring and malware detection. It’s a complementary toolset to your existing security posture.
|
@@ -220,9 +220,90 @@ integrity checking. We encourage you to visit this section and tune your
|
|
220 |
security needs as you see fit.
|
221 |
|
222 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
223 |
|
224 |
== Changelog ==
|
225 |
|
|
|
|
|
|
|
226 |
= 1.7.0 =
|
227 |
* Added Hardening option to remove error log files
|
228 |
* Bug fixes on some new registrations.
|
3 |
Donate Link: http://sitecheck.sucuri.net
|
4 |
Tags: malware, security, firewall, scan, spam, virus, sucuri, protection,WordPress Security, Login Security,Security Auditing,File Integrity,htaccess,phishing,backdoors,SQL Injection, RFI, LFI, XSS, CSRF,
|
5 |
Requires at least:3.2
|
6 |
+
Stable tag:1.7.1
|
7 |
Tested up to: 4.0
|
8 |
|
9 |
The Sucuri WordPress Security plugin is the best security toolset for security integrity monitoring, activity monitoring and malware detection. It’s a complementary toolset to your existing security posture.
|
220 |
security needs as you see fit.
|
221 |
|
222 |
|
223 |
+
== FAQ ==
|
224 |
+
|
225 |
+
= If I install the Sucuri Security plugin do I get a Sucuri account? =
|
226 |
+
|
227 |
+
No, this is a free plugin that we offer at no charge. It does not mean you get a free account.
|
228 |
+
|
229 |
+
|
230 |
+
= If I have the premium plugin, do I need the Free plugin? =
|
231 |
+
|
232 |
+
The free plugin will be replacing the Premium plugin in the coming weeks.
|
233 |
+
Eventually, there will only be one plugin. If you have the premium plugin, and
|
234 |
+
install the free version, the free version will overwrite the premium version.
|
235 |
+
|
236 |
+
= Do I still need Sucuri’s products if I have this plugin? =
|
237 |
+
|
238 |
+
Yes. This plugin compliments your existing security toolsets. It is not
|
239 |
+
designed to replace the Sucuri AntiVirus or Firewall products.
|
240 |
+
|
241 |
+
= Where do I get support for this plugin? =
|
242 |
+
|
243 |
+
The best place is to engage us via the <a
|
244 |
+
href=“https://wordpress.org/support/plugin/sucuri-scanner”>Support Forum. If
|
245 |
+
you are a client, <a href=“https://support.sucuri.net/support/?new”you can
|
246 |
+
submit a ticket here</a>.
|
247 |
+
|
248 |
+
= Does your plugin conflict with WordFence? =
|
249 |
+
|
250 |
+
The plugin does not, but there might be issues with our scanners. If you get
|
251 |
+
an “Unable to Properly Scan Your Site” It’s likely because the WordFence
|
252 |
+
plugin is blocking our scanner as an invalid crawler.
|
253 |
+
|
254 |
+
You would have to white list our IP address on the WordFence dashboard.
|
255 |
+
|
256 |
+
|
257 |
+
= What are the Remote Security Malware Scanning Limitations? =
|
258 |
+
|
259 |
+
Because the security malware scanner is remote, it is unable to see things
|
260 |
+
that are on the server but that are not displaying on the browser. If you are
|
261 |
+
interested in this, we encourage you to subscribe to our Website AntiVirus
|
262 |
+
product.
|
263 |
+
|
264 |
+
This issues includes things like Phishing pages, Backdoors, Mailer Scripts,
|
265 |
+
etc…
|
266 |
+
|
267 |
+
= Your plugin didn’t detect this malware? =
|
268 |
+
|
269 |
+
This happens, reference the Remote scanner limitations above. This should not
|
270 |
+
be confused with our Website AntiVirus product. If you have malware, and you
|
271 |
+
are a client, submit a ticket so that <a
|
272 |
+
href=“https://support.sucuri.net/support/?new&mremoval”>we can help you get
|
273 |
+
clean.</a>
|
274 |
+
|
275 |
+
If you are not a client, and you want to share what you have found please send
|
276 |
+
it to <a href=“mailto:labs@sucuri.net”>labs@sucuri.net</a>.
|
277 |
+
|
278 |
+
The plugin is not performing application level malware / security scanning so
|
279 |
+
this is not uncommon.
|
280 |
+
|
281 |
+
= Is it free to enable the Website Firewall option? =
|
282 |
+
|
283 |
+
No, it is not. To enable you must subscribe to the <a
|
284 |
+
href=“https://sucuri.net/website-firewall-signup”>Website Firewall
|
285 |
+
service</a>.
|
286 |
+
|
287 |
+
= Will this plugin impact the performance of my website? =
|
288 |
+
|
289 |
+
No, it will not.
|
290 |
+
|
291 |
+
= Do the logs get stored to my database? =
|
292 |
+
|
293 |
+
No, it does not.
|
294 |
+
|
295 |
+
= Are there any issues installing your plugin with any hosts? =
|
296 |
+
|
297 |
+
Not that we are aware of.
|
298 |
+
|
299 |
+
|
300 |
+
|
301 |
|
302 |
== Changelog ==
|
303 |
|
304 |
+
= 1.7.1 =
|
305 |
+
* Fixed remote scanning that was not loading automatically on some installs.
|
306 |
+
|
307 |
= 1.7.0 =
|
308 |
* Added Hardening option to remove error log files
|
309 |
* Bug fixes on some new registrations.
|
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</a> plugin provides the website owner the best Activity Auditing, SiteCheck Remote Malware Scanning, Effective Security Hardening and Post-Hack features. 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.7.
|
8 |
Author URI: http://sucuri.net
|
9 |
*/
|
10 |
|
@@ -66,7 +66,7 @@ define('SUCURISCAN', 'sucuriscan');
|
|
66 |
/**
|
67 |
* Current version of the plugin's code.
|
68 |
*/
|
69 |
-
define('SUCURISCAN_VERSION', '1.7.
|
70 |
|
71 |
/**
|
72 |
* The name of the Sucuri plugin main file.
|
@@ -560,7 +560,8 @@ class SucuriScan {
|
|
560 |
/**
|
561 |
* Retrieve the real ip address of the user in the current request.
|
562 |
*
|
563 |
-
* @
|
|
|
564 |
*/
|
565 |
public static function get_remote_addr( $return_header=FALSE ){
|
566 |
$remote_addr = '';
|
@@ -692,6 +693,19 @@ class SucuriScan {
|
|
692 |
return FALSE;
|
693 |
}
|
694 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
695 |
/**
|
696 |
* Retrieve the date in localized format, based on timestamp.
|
697 |
*
|
@@ -720,7 +734,7 @@ class SucuriScan {
|
|
720 |
* @return string The date, translated if locale specifies it.
|
721 |
*/
|
722 |
public static function current_datetime(){
|
723 |
-
$local_time =
|
724 |
|
725 |
return self::datetime($local_time);
|
726 |
}
|
@@ -736,7 +750,7 @@ class SucuriScan {
|
|
736 |
$timestamp = strtotime($timestamp);
|
737 |
}
|
738 |
|
739 |
-
$local_time =
|
740 |
$diff = abs( $local_time - intval($timestamp) );
|
741 |
|
742 |
if( $diff == 0 ){ return 'just now'; }
|
@@ -891,6 +905,21 @@ class SucuriScan {
|
|
891 |
return $text;
|
892 |
}
|
893 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
894 |
/**
|
895 |
* Check whether an list is a multidimensional array or not.
|
896 |
*
|
@@ -984,7 +1013,7 @@ class SucuriScanRequest extends SucuriScan {
|
|
984 |
}
|
985 |
|
986 |
// Check the format of the request data with a regex defined above.
|
987 |
-
if( preg_match($pattern, $key_value) ){
|
988 |
return self::escape($key_value);
|
989 |
}
|
990 |
}
|
@@ -1058,6 +1087,16 @@ class SucuriScanFileInfo extends SucuriScan {
|
|
1058 |
*/
|
1059 |
public $ignore_directories = TRUE;
|
1060 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1061 |
/**
|
1062 |
* Whether the filesystem scanner should run recursively or not.
|
1063 |
*
|
@@ -1086,34 +1125,37 @@ class SucuriScanFileInfo extends SucuriScan {
|
|
1086 |
$project_signatures = '';
|
1087 |
$abs_path = rtrim( ABSPATH, '/' );
|
1088 |
$files = $this->get_directory_tree($directory, $scan_with);
|
1089 |
-
sort($files);
|
1090 |
|
1091 |
if( $as_array ){
|
1092 |
$project_signatures = array();
|
1093 |
}
|
1094 |
|
1095 |
-
|
1096 |
-
|
1097 |
-
$filesize = @filesize($filepath);
|
1098 |
|
1099 |
-
|
1100 |
-
$
|
1101 |
-
$
|
1102 |
-
|
1103 |
-
|
1104 |
-
'
|
1105 |
-
|
1106 |
-
|
1107 |
-
|
1108 |
-
|
1109 |
-
|
1110 |
-
|
1111 |
-
|
1112 |
-
|
1113 |
-
$
|
1114 |
-
|
1115 |
-
|
1116 |
-
|
|
|
|
|
|
|
|
|
|
|
1117 |
}
|
1118 |
}
|
1119 |
|
@@ -1132,6 +1174,7 @@ class SucuriScanFileInfo extends SucuriScan {
|
|
1132 |
public function get_directory_tree($directory='', $scan_with='spl'){
|
1133 |
if( file_exists($directory) && is_dir($directory) ){
|
1134 |
$tree = array();
|
|
|
1135 |
|
1136 |
switch( $scan_with ){
|
1137 |
case 'spl':
|
@@ -1333,21 +1376,31 @@ class SucuriScanFileInfo extends SucuriScan {
|
|
1333 |
/**
|
1334 |
* Skip some specific directories and file paths from the filesystem scan.
|
1335 |
*
|
1336 |
-
* @param string $directory
|
1337 |
-
* @param string $filename
|
1338 |
-
* @return boolean
|
1339 |
*/
|
1340 |
private function ignore_folderpath( $directory='', $filename='' ){
|
1341 |
// Ignoring current and parent folders.
|
1342 |
if( $filename == '.' || $filename == '..' ){ return TRUE; }
|
1343 |
|
1344 |
if( $this->ignore_directories ){
|
|
|
1345 |
$filepath = realpath( $directory . '/' . $filename );
|
1346 |
$pattern = '/\/wp-content\/(uploads|cache|backup|w3tc)/';
|
1347 |
|
1348 |
if( preg_match($pattern, $filepath) ){
|
1349 |
return TRUE;
|
1350 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1351 |
}
|
1352 |
|
1353 |
return FALSE;
|
@@ -2381,30 +2434,6 @@ class SucuriScanOption extends SucuriScanRequest {
|
|
2381 |
return $response;
|
2382 |
}
|
2383 |
|
2384 |
-
/**
|
2385 |
-
* Retrieve the last time when the filesystem scan was ran.
|
2386 |
-
*
|
2387 |
-
* @param boolean $format Whether the timestamp must be formatted as date/time or not.
|
2388 |
-
* @return string The timestamp of the runtime, or an string with the date/time.
|
2389 |
-
*/
|
2390 |
-
public static function get_filesystem_runtime( $format=FALSE ){
|
2391 |
-
$runtime = self::get_option(':runtime');
|
2392 |
-
|
2393 |
-
if( $runtime > 0 ){
|
2394 |
-
if( $format ){
|
2395 |
-
return SucuriScan::datetime($runtime);
|
2396 |
-
}
|
2397 |
-
|
2398 |
-
return $runtime;
|
2399 |
-
}
|
2400 |
-
|
2401 |
-
if( $format ){
|
2402 |
-
return '<em>Unknown</em>';
|
2403 |
-
}
|
2404 |
-
|
2405 |
-
return FALSE;
|
2406 |
-
}
|
2407 |
-
|
2408 |
}
|
2409 |
|
2410 |
/**
|
@@ -3455,7 +3484,8 @@ class SucuriScanAPI extends SucuriScanOption {
|
|
3455 |
isset($response['headers']['content-type'])
|
3456 |
&& $response['headers']['content-type'] == 'application/json'
|
3457 |
){
|
3458 |
-
$
|
|
|
3459 |
}
|
3460 |
|
3461 |
// Check if the response data is serialized (which we will consider as insecure).
|
@@ -3899,6 +3929,8 @@ class SucuriScanAPI extends SucuriScanOption {
|
|
3899 |
'fromwp' => 2,
|
3900 |
'clear' => 1,
|
3901 |
'json' => 1,
|
|
|
|
|
3902 |
));
|
3903 |
|
3904 |
if( $response ){
|
@@ -4625,6 +4657,161 @@ class SucuriScanTemplate extends SucuriScanRequest {
|
|
4625 |
|
4626 |
}
|
4627 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4628 |
/**
|
4629 |
* Heartbeat library.
|
4630 |
*
|
@@ -6960,7 +7147,13 @@ function sucuriscan_core_files(){
|
|
6960 |
|
6961 |
foreach( $file_list as $file_path ){
|
6962 |
// Skip files that were marked as fixed.
|
6963 |
-
if(
|
|
|
|
|
|
|
|
|
|
|
|
|
6964 |
|
6965 |
// Generate the HTML code from the snippet template for this file.
|
6966 |
$css_class = ( $counter % 2 == 0 ) ? '' : 'alternate';
|
@@ -8360,6 +8553,8 @@ function sucuriscan_settings_page(){
|
|
8360 |
$template_variables = array(
|
8361 |
'PageTitle' => 'Settings',
|
8362 |
'Settings.General' => sucuriscan_settings_general(),
|
|
|
|
|
8363 |
'Settings.Notifications' => sucuriscan_settings_notifications(),
|
8364 |
'Settings.IgnoreRules' => sucuriscan_settings_ignore_rules(),
|
8365 |
'Settings.Heartbeat' => sucuriscan_settings_heartbeat(),
|
@@ -8443,9 +8638,7 @@ function sucuriscan_settings_form_submissions( $page_nonce=NULL ){
|
|
8443 |
|
8444 |
// Modify the schedule of the filesystem scanner.
|
8445 |
if( $frequency = SucuriScanRequest::post(':scan_frequency') ){
|
8446 |
-
|
8447 |
-
|
8448 |
-
if( in_array($frequency, $allowed_frequency) ){
|
8449 |
SucuriScanOption::update_option(':scan_frequency', $frequency);
|
8450 |
wp_clear_scheduled_hook('sucuriscan_scheduled_scan');
|
8451 |
|
@@ -8453,8 +8646,9 @@ function sucuriscan_settings_form_submissions( $page_nonce=NULL ){
|
|
8453 |
wp_schedule_event( time()+10, $frequency, 'sucuriscan_scheduled_scan' );
|
8454 |
}
|
8455 |
|
8456 |
-
|
8457 |
-
|
|
|
8458 |
}
|
8459 |
}
|
8460 |
|
@@ -8587,6 +8781,31 @@ function sucuriscan_settings_form_submissions( $page_nonce=NULL ){
|
|
8587 |
}
|
8588 |
}
|
8589 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
8590 |
// Update the settings for the heartbeat API.
|
8591 |
if( $heartbeat_status = SucuriScanRequest::post(':heartbeat_status') ){
|
8592 |
$statuses_allowed = SucuriScanHeartbeat::statuses_allowed();
|
@@ -8639,9 +8858,7 @@ function sucuriscan_settings_form_submissions( $page_nonce=NULL ){
|
|
8639 |
*/
|
8640 |
function sucuriscan_settings_general(){
|
8641 |
|
8642 |
-
global $
|
8643 |
-
$sucuriscan_interface_allowed,
|
8644 |
-
$sucuriscan_emails_per_hour,
|
8645 |
$sucuriscan_maximum_failed_logins,
|
8646 |
$sucuriscan_verify_ssl_cert;
|
8647 |
|
@@ -8672,16 +8889,9 @@ function sucuriscan_settings_general(){
|
|
8672 |
|
8673 |
// Get initial variables to decide some things bellow.
|
8674 |
$api_key = SucuriScanAPI::get_plugin_key();
|
8675 |
-
$fs_scanner = SucuriScanOption::get_option(':fs_scanner');
|
8676 |
-
$scan_freq = SucuriScanOption::get_option(':scan_frequency');
|
8677 |
-
$scan_interface = SucuriScanOption::get_option(':scan_interface');
|
8678 |
-
$scan_modfiles = SucuriScanOption::get_option(':scan_modfiles');
|
8679 |
-
$scan_checksums = SucuriScanOption::get_option(':scan_checksums');
|
8680 |
-
$scan_errorlogs = SucuriScanOption::get_option(':scan_errorlogs');
|
8681 |
$emails_per_hour = SucuriScanOption::get_option(':emails_per_hour');
|
8682 |
$maximum_failed_logins = SucuriScanOption::get_option(':maximum_failed_logins');
|
8683 |
$verify_ssl_cert = SucuriScanOption::get_option(':verify_ssl_cert');
|
8684 |
-
$runtime_scan_human = SucuriScanOption::get_filesystem_runtime(TRUE);
|
8685 |
|
8686 |
// Check whether the domain name is valid or not.
|
8687 |
if( !$api_key ){
|
@@ -8691,18 +8901,66 @@ function sucuriscan_settings_general(){
|
|
8691 |
}
|
8692 |
|
8693 |
// Generate the HTML code for the option list in the form select fields.
|
8694 |
-
$scan_freq_options = SucuriScanTemplate::get_select_options( $sucuriscan_schedule_allowed, $scan_freq );
|
8695 |
-
$scan_interface_options = SucuriScanTemplate::get_select_options( $sucuriscan_interface_allowed, $scan_interface );
|
8696 |
$emails_per_hour_options = SucuriScanTemplate::get_select_options( $sucuriscan_emails_per_hour, $emails_per_hour );
|
8697 |
$maximum_failed_logins_options = SucuriScanTemplate::get_select_options( $sucuriscan_maximum_failed_logins, $maximum_failed_logins );
|
8698 |
$verify_ssl_cert_options = SucuriScanTemplate::get_select_options( $sucuriscan_verify_ssl_cert, $verify_ssl_cert );
|
8699 |
|
8700 |
$template_variables = array(
|
8701 |
-
'APIKey' => $api_key,
|
8702 |
'APIKey.RecoverVisibility' => SucuriScanTemplate::visibility( !$api_key && !$display_manual_key_form ),
|
8703 |
'APIKey.ManualKeyFormVisibility' => SucuriScanTemplate::visibility($display_manual_key_form),
|
8704 |
'APIKey.RemoveVisibility' => SucuriScanTemplate::visibility($api_key),
|
8705 |
'InvalidDomainVisibility' => SucuriScanTemplate::visibility($invalid_domain),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
8706 |
/* Filesystem scanner */
|
8707 |
'FsScannerStatus' => 'Enabled',
|
8708 |
'FsScannerSwitchText' => 'Disable',
|
@@ -8728,19 +8986,8 @@ function sucuriscan_settings_general(){
|
|
8728 |
'ScanningFrequencyOptions' => $scan_freq_options,
|
8729 |
'ScanningInterface' => ( $scan_interface ? $sucuriscan_interface_allowed[$scan_interface] : 'Undefined' ),
|
8730 |
'ScanningInterfaceOptions' => $scan_interface_options,
|
8731 |
-
'ScanningInterfaceVisibility' => SucuriScanTemplate::visibility( !SucuriScanFileInfo::is_spl_available() ),
|
8732 |
/* Filesystem scanning runtime. */
|
8733 |
'ScanningRuntimeHuman' => $runtime_scan_human,
|
8734 |
-
'ModalWhenAPIRegistered' => $api_registered_modal,
|
8735 |
-
'NotifyTo' => SucuriScanOption::get_option(':notify_to'),
|
8736 |
-
'EmailsPerHour' => 'Undefined',
|
8737 |
-
'EmailsPerHourOptions' => $emails_per_hour_options,
|
8738 |
-
'MaximumFailedLogins' => 'Undefined',
|
8739 |
-
'MaximumFailedLoginsOptions' => $maximum_failed_logins_options,
|
8740 |
-
'VerifySSLCert' => 'Undefined',
|
8741 |
-
'VerifySSLCertOptions' => $verify_ssl_cert_options,
|
8742 |
-
'RequestTimeout' => SucuriScanOption::get_option(':request_timeout') . ' seconds',
|
8743 |
-
'ModalWhenAPIRegistered' => $api_registered_modal,
|
8744 |
);
|
8745 |
|
8746 |
if( $fs_scanner == 'disabled' ){
|
@@ -8775,19 +9022,7 @@ function sucuriscan_settings_general(){
|
|
8775 |
$template_variables['ScanningFrequency'] = $sucuriscan_schedule_allowed[$scan_freq];
|
8776 |
}
|
8777 |
|
8778 |
-
|
8779 |
-
$template_variables['EmailsPerHour'] = $sucuriscan_emails_per_hour[$emails_per_hour];
|
8780 |
-
}
|
8781 |
-
|
8782 |
-
if( array_key_exists($maximum_failed_logins, $sucuriscan_maximum_failed_logins) ){
|
8783 |
-
$template_variables['MaximumFailedLogins'] = $sucuriscan_maximum_failed_logins[$maximum_failed_logins];
|
8784 |
-
}
|
8785 |
-
|
8786 |
-
if( array_key_exists($verify_ssl_cert, $sucuriscan_verify_ssl_cert) ){
|
8787 |
-
$template_variables['VerifySSLCert'] = $sucuriscan_verify_ssl_cert[$verify_ssl_cert];
|
8788 |
-
}
|
8789 |
-
|
8790 |
-
return SucuriScanTemplate::get_section('settings-general', $template_variables);
|
8791 |
}
|
8792 |
|
8793 |
/**
|
@@ -8883,10 +9118,62 @@ function sucuriscan_settings_ignore_rules(){
|
|
8883 |
return SucuriScanTemplate::get_section('settings-ignorerules', $template_variables);
|
8884 |
}
|
8885 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
8886 |
/**
|
8887 |
* Read and parse the content of the heartbeat settings template.
|
8888 |
*
|
8889 |
-
* @return string Parsed HTML code for the
|
8890 |
*/
|
8891 |
function sucuriscan_settings_heartbeat(){
|
8892 |
// Current values set in the options table.
|
@@ -9269,7 +9556,7 @@ function sucuriscan_server_info(){
|
|
9269 |
$info_vars = array(
|
9270 |
'Plugin_version' => SUCURISCAN_VERSION,
|
9271 |
'Plugin_checksum' => SUCURISCAN_PLUGIN_CHECKSUM,
|
9272 |
-
'Last_filesystem_scan' =>
|
9273 |
'Using_CloudProxy' => 'Unknown',
|
9274 |
'HTTP_Host' => 'Unknown',
|
9275 |
'Host_Name' => 'Unknown',
|
4 |
Plugin URI: http://wordpress.sucuri.net/
|
5 |
Description: The <a href="http://sucuri.net/" target="_blank">Sucuri</a> plugin provides the website owner the best Activity Auditing, SiteCheck Remote Malware Scanning, Effective Security Hardening and Post-Hack features. 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.7.1
|
8 |
Author URI: http://sucuri.net
|
9 |
*/
|
10 |
|
66 |
/**
|
67 |
* Current version of the plugin's code.
|
68 |
*/
|
69 |
+
define('SUCURISCAN_VERSION', '1.7.1');
|
70 |
|
71 |
/**
|
72 |
* The name of the Sucuri plugin main file.
|
560 |
/**
|
561 |
* Retrieve the real ip address of the user in the current request.
|
562 |
*
|
563 |
+
* @param boolean $return_header Whether the header name where the address was found must be returned.
|
564 |
+
* @return string The real ip address of the user in the current request.
|
565 |
*/
|
566 |
public static function get_remote_addr( $return_header=FALSE ){
|
567 |
$remote_addr = '';
|
693 |
return FALSE;
|
694 |
}
|
695 |
|
696 |
+
/**
|
697 |
+
* Returns the current time measured in the number of seconds since the Unix Epoch.
|
698 |
+
*
|
699 |
+
* @return integer Return current Unix timestamp.
|
700 |
+
*/
|
701 |
+
public static function local_time(){
|
702 |
+
if( function_exists('current_time') ){
|
703 |
+
return current_time('timestamp');
|
704 |
+
} else {
|
705 |
+
return time();
|
706 |
+
}
|
707 |
+
}
|
708 |
+
|
709 |
/**
|
710 |
* Retrieve the date in localized format, based on timestamp.
|
711 |
*
|
734 |
* @return string The date, translated if locale specifies it.
|
735 |
*/
|
736 |
public static function current_datetime(){
|
737 |
+
$local_time = self::local_time();
|
738 |
|
739 |
return self::datetime($local_time);
|
740 |
}
|
750 |
$timestamp = strtotime($timestamp);
|
751 |
}
|
752 |
|
753 |
+
$local_time = self::local_time();
|
754 |
$diff = abs( $local_time - intval($timestamp) );
|
755 |
|
756 |
if( $diff == 0 ){ return 'just now'; }
|
905 |
return $text;
|
906 |
}
|
907 |
|
908 |
+
/**
|
909 |
+
* Same as the excerpt method but with the string reversed.
|
910 |
+
*
|
911 |
+
* @param string $text String of characters that will be cut.
|
912 |
+
* @param integer $length Maximum length of the returned string, default is 10.
|
913 |
+
* @return string Short version of the text specified.
|
914 |
+
*/
|
915 |
+
public static function excerpt_rev( $text='', $length=10 ){
|
916 |
+
$str_reversed = strrev($text);
|
917 |
+
$str_excerpt = self::excerpt( $str_reversed, $length );
|
918 |
+
$text_transformed = strrev($str_excerpt);
|
919 |
+
|
920 |
+
return $text_transformed;
|
921 |
+
}
|
922 |
+
|
923 |
/**
|
924 |
* Check whether an list is a multidimensional array or not.
|
925 |
*
|
1013 |
}
|
1014 |
|
1015 |
// Check the format of the request data with a regex defined above.
|
1016 |
+
if( @preg_match($pattern, $key_value) ){
|
1017 |
return self::escape($key_value);
|
1018 |
}
|
1019 |
}
|
1087 |
*/
|
1088 |
public $ignore_directories = TRUE;
|
1089 |
|
1090 |
+
/**
|
1091 |
+
* A list of ignored directory paths, these folders will be skipped during the
|
1092 |
+
* execution of the file system scans, and any sub-directory or files inside
|
1093 |
+
* these paths will be ignored too.
|
1094 |
+
*
|
1095 |
+
* @see SucuriScanFSScanner.get_ignored_directories()
|
1096 |
+
* @var array
|
1097 |
+
*/
|
1098 |
+
private $ignored_directories = array();
|
1099 |
+
|
1100 |
/**
|
1101 |
* Whether the filesystem scanner should run recursively or not.
|
1102 |
*
|
1125 |
$project_signatures = '';
|
1126 |
$abs_path = rtrim( ABSPATH, '/' );
|
1127 |
$files = $this->get_directory_tree($directory, $scan_with);
|
|
|
1128 |
|
1129 |
if( $as_array ){
|
1130 |
$project_signatures = array();
|
1131 |
}
|
1132 |
|
1133 |
+
if( $files ){
|
1134 |
+
sort($files);
|
|
|
1135 |
|
1136 |
+
foreach( $files as $filepath){
|
1137 |
+
$file_checksum = @md5_file($filepath);
|
1138 |
+
$filesize = @filesize($filepath);
|
1139 |
+
|
1140 |
+
if( $as_array ){
|
1141 |
+
$basename = str_replace( $abs_path . '/', '', $filepath );
|
1142 |
+
$project_signatures[$basename] = array(
|
1143 |
+
'filepath' => $filepath,
|
1144 |
+
'checksum' => $file_checksum,
|
1145 |
+
'filesize' => $filesize,
|
1146 |
+
'created_at' => filectime($filepath),
|
1147 |
+
'modified_at' => filemtime($filepath),
|
1148 |
+
);
|
1149 |
+
} else {
|
1150 |
+
$filepath = str_replace( $abs_path, $abs_path . '/', $filepath );
|
1151 |
+
$project_signatures .= sprintf(
|
1152 |
+
"%s%s%s%s\n",
|
1153 |
+
$file_checksum,
|
1154 |
+
$filesize,
|
1155 |
+
chr(32),
|
1156 |
+
$filepath
|
1157 |
+
);
|
1158 |
+
}
|
1159 |
}
|
1160 |
}
|
1161 |
|
1174 |
public function get_directory_tree($directory='', $scan_with='spl'){
|
1175 |
if( file_exists($directory) && is_dir($directory) ){
|
1176 |
$tree = array();
|
1177 |
+
$this->ignored_directories = SucuriScanFSScanner::get_ignored_directories();
|
1178 |
|
1179 |
switch( $scan_with ){
|
1180 |
case 'spl':
|
1376 |
/**
|
1377 |
* Skip some specific directories and file paths from the filesystem scan.
|
1378 |
*
|
1379 |
+
* @param string $directory Directory where the scanner is located at the moment.
|
1380 |
+
* @param string $filename Name of the folder or file being scanned at the moment.
|
1381 |
+
* @return boolean Either TRUE or FALSE representing that the scan should ignore this folder or not.
|
1382 |
*/
|
1383 |
private function ignore_folderpath( $directory='', $filename='' ){
|
1384 |
// Ignoring current and parent folders.
|
1385 |
if( $filename == '.' || $filename == '..' ){ return TRUE; }
|
1386 |
|
1387 |
if( $this->ignore_directories ){
|
1388 |
+
// Ignore directories based on a common regular expression.
|
1389 |
$filepath = realpath( $directory . '/' . $filename );
|
1390 |
$pattern = '/\/wp-content\/(uploads|cache|backup|w3tc)/';
|
1391 |
|
1392 |
if( preg_match($pattern, $filepath) ){
|
1393 |
return TRUE;
|
1394 |
}
|
1395 |
+
|
1396 |
+
// Ignore directories specified by the administrator.
|
1397 |
+
if( !empty($this->ignored_directories) ){
|
1398 |
+
foreach( $this->ignored_directories['directories'] as $ignored_dir ){
|
1399 |
+
if( strpos($directory, $ignored_dir) !== FALSE ){
|
1400 |
+
return TRUE;
|
1401 |
+
}
|
1402 |
+
}
|
1403 |
+
}
|
1404 |
}
|
1405 |
|
1406 |
return FALSE;
|
2434 |
return $response;
|
2435 |
}
|
2436 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2437 |
}
|
2438 |
|
2439 |
/**
|
3484 |
isset($response['headers']['content-type'])
|
3485 |
&& $response['headers']['content-type'] == 'application/json'
|
3486 |
){
|
3487 |
+
$assoc = ( isset($args['assoc']) && $args['assoc'] === TRUE ) ? TRUE : FALSE;
|
3488 |
+
$response['body'] = @json_decode($response['body_raw'], $assoc);
|
3489 |
}
|
3490 |
|
3491 |
// Check if the response data is serialized (which we will consider as insecure).
|
3929 |
'fromwp' => 2,
|
3930 |
'clear' => 1,
|
3931 |
'json' => 1,
|
3932 |
+
), array(
|
3933 |
+
'assoc' => TRUE
|
3934 |
));
|
3935 |
|
3936 |
if( $response ){
|
4657 |
|
4658 |
}
|
4659 |
|
4660 |
+
/**
|
4661 |
+
* File System Scanner
|
4662 |
+
*
|
4663 |
+
* The File System Scanner component performs full and incremental scans over a
|
4664 |
+
* file system folder, maintaining a snapshot of the filesystem and comparing it
|
4665 |
+
* with the current content to establish what content has been updated. Updated
|
4666 |
+
* content is then submitted to the remote server and it is stored for future
|
4667 |
+
* analysis.
|
4668 |
+
*/
|
4669 |
+
class SucuriScanFSScanner extends SucuriScan {
|
4670 |
+
|
4671 |
+
/**
|
4672 |
+
* Retrieve the last time when the filesystem scan was ran.
|
4673 |
+
*
|
4674 |
+
* @param boolean $format Whether the timestamp must be formatted as date/time or not.
|
4675 |
+
* @return string The timestamp of the runtime, or an string with the date/time.
|
4676 |
+
*/
|
4677 |
+
public static function get_filesystem_runtime( $format=FALSE ){
|
4678 |
+
$runtime = SucuriScanOption::get_option(':runtime');
|
4679 |
+
|
4680 |
+
if( $runtime > 0 ){
|
4681 |
+
if( $format ){
|
4682 |
+
return SucuriScan::datetime($runtime);
|
4683 |
+
}
|
4684 |
+
|
4685 |
+
return $runtime;
|
4686 |
+
}
|
4687 |
+
|
4688 |
+
if( $format ){
|
4689 |
+
return '<em>Unknown</em>';
|
4690 |
+
}
|
4691 |
+
|
4692 |
+
return FALSE;
|
4693 |
+
}
|
4694 |
+
|
4695 |
+
/**
|
4696 |
+
* Add a new directory path to the list of ignored paths.
|
4697 |
+
*
|
4698 |
+
* @param string $directory_path The (full) absolute path of a directory.
|
4699 |
+
* @return boolean TRUE if the directory path was added to the list, FALSE otherwise.
|
4700 |
+
*/
|
4701 |
+
public static function ignore_directory( $directory_path='' ){
|
4702 |
+
$cache = new SucuriScanCache('ignorescanning');
|
4703 |
+
|
4704 |
+
// Use the checksum of the directory path as the cache key.
|
4705 |
+
$cache_key = md5($directory_path);
|
4706 |
+
$cache_value = array(
|
4707 |
+
'directory_path' => $directory_path,
|
4708 |
+
'ignored_at' => self::local_time(),
|
4709 |
+
);
|
4710 |
+
$cached = $cache->add( $cache_key, $cache_value );
|
4711 |
+
|
4712 |
+
return $cached;
|
4713 |
+
}
|
4714 |
+
|
4715 |
+
/**
|
4716 |
+
* Remove a directory path from the list of ignored paths.
|
4717 |
+
*
|
4718 |
+
* @param string $directory_path The (full) absolute path of a directory.
|
4719 |
+
* @return boolean TRUE if the directory path was removed to the list, FALSE otherwise.
|
4720 |
+
*/
|
4721 |
+
public static function unignore_directory( $directory_path='' ){
|
4722 |
+
$cache = new SucuriScanCache('ignorescanning');
|
4723 |
+
|
4724 |
+
// Use the checksum of the directory path as the cache key.
|
4725 |
+
$cache_key = md5($directory_path);
|
4726 |
+
$removed = $cache->delete($cache_key);
|
4727 |
+
|
4728 |
+
return $removed;
|
4729 |
+
}
|
4730 |
+
|
4731 |
+
/**
|
4732 |
+
* Retrieve a list of directories ignored.
|
4733 |
+
*
|
4734 |
+
* Retrieve a list of directory paths that will be ignored during the file
|
4735 |
+
* system scans, any sub-directory and files inside these folders will be
|
4736 |
+
* skipped automatically and will not be used to detect malware or modifications
|
4737 |
+
* in the site.
|
4738 |
+
*
|
4739 |
+
* The structure of the array returned by the function will always be composed
|
4740 |
+
* by four (4) indexes which will facilitate the execution of common conditions
|
4741 |
+
* in the implementation code.
|
4742 |
+
*
|
4743 |
+
* <ul>
|
4744 |
+
* <li>raw: Will contains the raw data retrieved from the built-in cache system.</li>
|
4745 |
+
* <li>checksums: Will contains the md5 of all the directory paths.</li>
|
4746 |
+
* <li>directories: Will contains a list of directory paths.</li>
|
4747 |
+
* <li>ignored_at_list: Will contains a list of timestamps for when the directories were ignored.</li>
|
4748 |
+
* </ul>
|
4749 |
+
*
|
4750 |
+
* @return array List of ignored directory paths.
|
4751 |
+
*/
|
4752 |
+
public static function get_ignored_directories(){
|
4753 |
+
$response = array(
|
4754 |
+
'raw' => array(),
|
4755 |
+
'checksums' => array(),
|
4756 |
+
'directories' => array(),
|
4757 |
+
'ignored_at_list' => array(),
|
4758 |
+
);
|
4759 |
+
|
4760 |
+
$cache = new SucuriScanCache('ignorescanning');
|
4761 |
+
$cache_lifetime = 0; // It is not necessary to expire this cache.
|
4762 |
+
$ignored_directories = $cache->get_all( $cache_lifetime, 'array' );
|
4763 |
+
|
4764 |
+
if( $ignored_directories ){
|
4765 |
+
$response['raw'] = $ignored_directories;
|
4766 |
+
|
4767 |
+
foreach( $ignored_directories as $checksum => $data ){
|
4768 |
+
$response['checksums'][] = $checksum;
|
4769 |
+
$response['directories'][] = $data['directory_path'];
|
4770 |
+
$response['ignored_at_list'][] = $data['ignored_at'];
|
4771 |
+
}
|
4772 |
+
}
|
4773 |
+
|
4774 |
+
return $response;
|
4775 |
+
}
|
4776 |
+
|
4777 |
+
/**
|
4778 |
+
* Run file system scan and retrieve ignored folders.
|
4779 |
+
*
|
4780 |
+
* Run a file system scan and retrieve an array with two indexes, the first
|
4781 |
+
* containing a list of ignored directory paths and their respective timestamps
|
4782 |
+
* of when they were added by an administrator user, and the second containing a
|
4783 |
+
* list of directories that are not being ignored.
|
4784 |
+
*
|
4785 |
+
* @return array List of ignored and not ignored directories.
|
4786 |
+
*/
|
4787 |
+
public static function get_ignored_directories_live(){
|
4788 |
+
$response = array(
|
4789 |
+
'is_ignored' => array(),
|
4790 |
+
'is_not_ignored' => array(),
|
4791 |
+
);
|
4792 |
+
|
4793 |
+
// Get the ignored directories from the cache.
|
4794 |
+
$ignored_directories = self::get_ignored_directories();
|
4795 |
+
|
4796 |
+
if( $ignored_directories ){
|
4797 |
+
$response['is_ignored'] = $ignored_directories['raw'];
|
4798 |
+
}
|
4799 |
+
|
4800 |
+
// Scan the project and file all directories.
|
4801 |
+
$sucuri_fileinfo = new SucuriScanFileInfo();
|
4802 |
+
$sucuri_fileinfo->ignore_files = TRUE;
|
4803 |
+
$sucuri_fileinfo->ignore_directories = TRUE;
|
4804 |
+
$directory_list = $sucuri_fileinfo->get_diretories_only(ABSPATH);
|
4805 |
+
|
4806 |
+
if( $directory_list ){
|
4807 |
+
$response['is_not_ignored'] = $directory_list;
|
4808 |
+
}
|
4809 |
+
|
4810 |
+
return $response;
|
4811 |
+
}
|
4812 |
+
|
4813 |
+
}
|
4814 |
+
|
4815 |
/**
|
4816 |
* Heartbeat library.
|
4817 |
*
|
7147 |
|
7148 |
foreach( $file_list as $file_path ){
|
7149 |
// Skip files that were marked as fixed.
|
7150 |
+
if( $ignored_files ){
|
7151 |
+
$file_path_checksum = md5($file_path);
|
7152 |
+
|
7153 |
+
if( array_key_exists($file_path_checksum, $ignored_files) ){
|
7154 |
+
continue;
|
7155 |
+
}
|
7156 |
+
}
|
7157 |
|
7158 |
// Generate the HTML code from the snippet template for this file.
|
7159 |
$css_class = ( $counter % 2 == 0 ) ? '' : 'alternate';
|
8553 |
$template_variables = array(
|
8554 |
'PageTitle' => 'Settings',
|
8555 |
'Settings.General' => sucuriscan_settings_general(),
|
8556 |
+
'Settings.Scanner' => sucuriscan_settings_scanner(),
|
8557 |
+
'Settings.IgnoreScanning' => sucuriscan_settings_ignorescanning(),
|
8558 |
'Settings.Notifications' => sucuriscan_settings_notifications(),
|
8559 |
'Settings.IgnoreRules' => sucuriscan_settings_ignore_rules(),
|
8560 |
'Settings.Heartbeat' => sucuriscan_settings_heartbeat(),
|
8638 |
|
8639 |
// Modify the schedule of the filesystem scanner.
|
8640 |
if( $frequency = SucuriScanRequest::post(':scan_frequency') ){
|
8641 |
+
if( array_key_exists($frequency, $sucuriscan_schedule_allowed) ){
|
|
|
|
|
8642 |
SucuriScanOption::update_option(':scan_frequency', $frequency);
|
8643 |
wp_clear_scheduled_hook('sucuriscan_scheduled_scan');
|
8644 |
|
8646 |
wp_schedule_event( time()+10, $frequency, 'sucuriscan_scheduled_scan' );
|
8647 |
}
|
8648 |
|
8649 |
+
$frequency_title = $sucuriscan_schedule_allowed[$frequency];
|
8650 |
+
SucuriScanEvent::notify_event( 'plugin_change', 'Filesystem scanning frequency changed to: ' . $frequency_title );
|
8651 |
+
SucuriScanInterface::info( 'Filesystem scan scheduled to run <code>'.$frequency_title.'</code>' );
|
8652 |
}
|
8653 |
}
|
8654 |
|
8781 |
}
|
8782 |
}
|
8783 |
|
8784 |
+
// Ignore a new directory path for the file system scans.
|
8785 |
+
if( $action = SucuriScanRequest::post(':ignorescanning_action', '(ignore|unignore)') ){
|
8786 |
+
$ignore_directories = SucuriScanRequest::post(':ignorescanning_dirs', '_array');
|
8787 |
+
|
8788 |
+
if( empty($ignore_directories) ){
|
8789 |
+
SucuriScanInterface::error( 'You did not choose a directory path from the list.' );
|
8790 |
+
}
|
8791 |
+
|
8792 |
+
elseif( $action == 'ignore' ){
|
8793 |
+
foreach( $ignore_directories as $directory_path ){
|
8794 |
+
SucuriScanFSScanner::ignore_directory($directory_path);
|
8795 |
+
}
|
8796 |
+
|
8797 |
+
SucuriScanInterface::info( 'Directories selected from the list will be ignored in future scans.' );
|
8798 |
+
}
|
8799 |
+
|
8800 |
+
elseif( $action == 'unignore' ) {
|
8801 |
+
foreach( $ignore_directories as $directory_path ){
|
8802 |
+
SucuriScanFSScanner::unignore_directory($directory_path);
|
8803 |
+
}
|
8804 |
+
|
8805 |
+
SucuriScanInterface::info( 'Directories selected from the list will not be ignored anymore.' );
|
8806 |
+
}
|
8807 |
+
}
|
8808 |
+
|
8809 |
// Update the settings for the heartbeat API.
|
8810 |
if( $heartbeat_status = SucuriScanRequest::post(':heartbeat_status') ){
|
8811 |
$statuses_allowed = SucuriScanHeartbeat::statuses_allowed();
|
8858 |
*/
|
8859 |
function sucuriscan_settings_general(){
|
8860 |
|
8861 |
+
global $sucuriscan_emails_per_hour,
|
|
|
|
|
8862 |
$sucuriscan_maximum_failed_logins,
|
8863 |
$sucuriscan_verify_ssl_cert;
|
8864 |
|
8889 |
|
8890 |
// Get initial variables to decide some things bellow.
|
8891 |
$api_key = SucuriScanAPI::get_plugin_key();
|
|
|
|
|
|
|
|
|
|
|
|
|
8892 |
$emails_per_hour = SucuriScanOption::get_option(':emails_per_hour');
|
8893 |
$maximum_failed_logins = SucuriScanOption::get_option(':maximum_failed_logins');
|
8894 |
$verify_ssl_cert = SucuriScanOption::get_option(':verify_ssl_cert');
|
|
|
8895 |
|
8896 |
// Check whether the domain name is valid or not.
|
8897 |
if( !$api_key ){
|
8901 |
}
|
8902 |
|
8903 |
// Generate the HTML code for the option list in the form select fields.
|
|
|
|
|
8904 |
$emails_per_hour_options = SucuriScanTemplate::get_select_options( $sucuriscan_emails_per_hour, $emails_per_hour );
|
8905 |
$maximum_failed_logins_options = SucuriScanTemplate::get_select_options( $sucuriscan_maximum_failed_logins, $maximum_failed_logins );
|
8906 |
$verify_ssl_cert_options = SucuriScanTemplate::get_select_options( $sucuriscan_verify_ssl_cert, $verify_ssl_cert );
|
8907 |
|
8908 |
$template_variables = array(
|
8909 |
+
'APIKey' => ( !$api_key ? '<em>(not set)</em>' : $api_key ),
|
8910 |
'APIKey.RecoverVisibility' => SucuriScanTemplate::visibility( !$api_key && !$display_manual_key_form ),
|
8911 |
'APIKey.ManualKeyFormVisibility' => SucuriScanTemplate::visibility($display_manual_key_form),
|
8912 |
'APIKey.RemoveVisibility' => SucuriScanTemplate::visibility($api_key),
|
8913 |
'InvalidDomainVisibility' => SucuriScanTemplate::visibility($invalid_domain),
|
8914 |
+
'NotifyTo' => SucuriScanOption::get_option(':notify_to'),
|
8915 |
+
'EmailsPerHour' => 'Undefined',
|
8916 |
+
'EmailsPerHourOptions' => $emails_per_hour_options,
|
8917 |
+
'MaximumFailedLogins' => 'Undefined',
|
8918 |
+
'MaximumFailedLoginsOptions' => $maximum_failed_logins_options,
|
8919 |
+
'VerifySSLCert' => 'Undefined',
|
8920 |
+
'VerifySSLCertOptions' => $verify_ssl_cert_options,
|
8921 |
+
'RequestTimeout' => SucuriScanOption::get_option(':request_timeout') . ' seconds',
|
8922 |
+
'ModalWhenAPIRegistered' => $api_registered_modal,
|
8923 |
+
);
|
8924 |
+
|
8925 |
+
if( array_key_exists($emails_per_hour, $sucuriscan_emails_per_hour) ){
|
8926 |
+
$template_variables['EmailsPerHour'] = $sucuriscan_emails_per_hour[$emails_per_hour];
|
8927 |
+
}
|
8928 |
+
|
8929 |
+
if( array_key_exists($maximum_failed_logins, $sucuriscan_maximum_failed_logins) ){
|
8930 |
+
$template_variables['MaximumFailedLogins'] = $sucuriscan_maximum_failed_logins[$maximum_failed_logins];
|
8931 |
+
}
|
8932 |
+
|
8933 |
+
if( array_key_exists($verify_ssl_cert, $sucuriscan_verify_ssl_cert) ){
|
8934 |
+
$template_variables['VerifySSLCert'] = $sucuriscan_verify_ssl_cert[$verify_ssl_cert];
|
8935 |
+
}
|
8936 |
+
|
8937 |
+
return SucuriScanTemplate::get_section('settings-general', $template_variables);
|
8938 |
+
}
|
8939 |
+
|
8940 |
+
/**
|
8941 |
+
* Read and parse the content of the scanner settings template.
|
8942 |
+
*
|
8943 |
+
* @return string Parsed HTML code for the scanner settings panel.
|
8944 |
+
*/
|
8945 |
+
function sucuriscan_settings_scanner(){
|
8946 |
+
|
8947 |
+
global $sucuriscan_schedule_allowed,
|
8948 |
+
$sucuriscan_interface_allowed;
|
8949 |
+
|
8950 |
+
// Get initial variables to decide some things bellow.
|
8951 |
+
$fs_scanner = SucuriScanOption::get_option(':fs_scanner');
|
8952 |
+
$scan_freq = SucuriScanOption::get_option(':scan_frequency');
|
8953 |
+
$scan_interface = SucuriScanOption::get_option(':scan_interface');
|
8954 |
+
$scan_modfiles = SucuriScanOption::get_option(':scan_modfiles');
|
8955 |
+
$scan_checksums = SucuriScanOption::get_option(':scan_checksums');
|
8956 |
+
$scan_errorlogs = SucuriScanOption::get_option(':scan_errorlogs');
|
8957 |
+
$runtime_scan_human = SucuriScanFSScanner::get_filesystem_runtime(TRUE);
|
8958 |
+
|
8959 |
+
// Generate the HTML code for the option list in the form select fields.
|
8960 |
+
$scan_freq_options = SucuriScanTemplate::get_select_options( $sucuriscan_schedule_allowed, $scan_freq );
|
8961 |
+
$scan_interface_options = SucuriScanTemplate::get_select_options( $sucuriscan_interface_allowed, $scan_interface );
|
8962 |
+
|
8963 |
+
$template_variables = array(
|
8964 |
/* Filesystem scanner */
|
8965 |
'FsScannerStatus' => 'Enabled',
|
8966 |
'FsScannerSwitchText' => 'Disable',
|
8986 |
'ScanningFrequencyOptions' => $scan_freq_options,
|
8987 |
'ScanningInterface' => ( $scan_interface ? $sucuriscan_interface_allowed[$scan_interface] : 'Undefined' ),
|
8988 |
'ScanningInterfaceOptions' => $scan_interface_options,
|
|
|
8989 |
/* Filesystem scanning runtime. */
|
8990 |
'ScanningRuntimeHuman' => $runtime_scan_human,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
8991 |
);
|
8992 |
|
8993 |
if( $fs_scanner == 'disabled' ){
|
9022 |
$template_variables['ScanningFrequency'] = $sucuriscan_schedule_allowed[$scan_freq];
|
9023 |
}
|
9024 |
|
9025 |
+
return SucuriScanTemplate::get_section('settings-scanner', $template_variables);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
9026 |
}
|
9027 |
|
9028 |
/**
|
9118 |
return SucuriScanTemplate::get_section('settings-ignorerules', $template_variables);
|
9119 |
}
|
9120 |
|
9121 |
+
/**
|
9122 |
+
* Read and parse the content of the ignore-scanning settings template.
|
9123 |
+
*
|
9124 |
+
* @return string Parsed HTML code for the ignore-scanning settings panel.
|
9125 |
+
*/
|
9126 |
+
function sucuriscan_settings_ignorescanning(){
|
9127 |
+
$template_variables = array(
|
9128 |
+
'IgnoreScanning.ResourceList' => '',
|
9129 |
+
);
|
9130 |
+
|
9131 |
+
$dir_list_list = SucuriScanFSScanner::get_ignored_directories_live();
|
9132 |
+
$counter = 0;
|
9133 |
+
|
9134 |
+
foreach( $dir_list_list as $group => $dir_list ){
|
9135 |
+
foreach( $dir_list as $dir_data ){
|
9136 |
+
$valid_entry = FALSE;
|
9137 |
+
$snippet_data = array(
|
9138 |
+
'IgnoreScanning.CssClass' => '',
|
9139 |
+
'IgnoreScanning.Directory' => '',
|
9140 |
+
'IgnoreScanning.DirectoryPath' => '',
|
9141 |
+
'IgnoreScanning.IgnoredAt' => '',
|
9142 |
+
'IgnoreScanning.IgnoredAtText' => 'ok',
|
9143 |
+
'IgnoreScanning.IgnoredCssClass' => 'success',
|
9144 |
+
);
|
9145 |
+
|
9146 |
+
if( $group == 'is_ignored' ){
|
9147 |
+
$valid_entry = TRUE;
|
9148 |
+
$snippet_data['IgnoreScanning.Directory'] = urlencode($dir_data['directory_path']);
|
9149 |
+
$snippet_data['IgnoreScanning.DirectoryPath'] = SucuriScan::escape($dir_data['directory_path']);
|
9150 |
+
$snippet_data['IgnoreScanning.IgnoredAt'] = SucuriScan::datetime($dir_data['ignored_at']);
|
9151 |
+
$snippet_data['IgnoreScanning.IgnoredAtText'] = 'ignored';
|
9152 |
+
$snippet_data['IgnoreScanning.IgnoredCssClass'] = 'warning';
|
9153 |
+
}
|
9154 |
+
|
9155 |
+
elseif( $group == 'is_not_ignored' ){
|
9156 |
+
$valid_entry = TRUE;
|
9157 |
+
$snippet_data['IgnoreScanning.Directory'] = urlencode($dir_data);
|
9158 |
+
$snippet_data['IgnoreScanning.DirectoryPath'] = SucuriScan::escape($dir_data);
|
9159 |
+
}
|
9160 |
+
|
9161 |
+
if( $valid_entry ){
|
9162 |
+
$css_class = ( $counter %2 == 0 ) ? '' : 'alternate';
|
9163 |
+
$snippet_data['IgnoreScanning.CssClass'] = $css_class;
|
9164 |
+
$template_variables['IgnoreScanning.ResourceList'] .= SucuriScanTemplate::get_snippet('settings-ignorescanning', $snippet_data);
|
9165 |
+
$counter += 1;
|
9166 |
+
}
|
9167 |
+
}
|
9168 |
+
}
|
9169 |
+
|
9170 |
+
return SucuriScanTemplate::get_section('settings-ignorescanning', $template_variables);
|
9171 |
+
}
|
9172 |
+
|
9173 |
/**
|
9174 |
* Read and parse the content of the heartbeat settings template.
|
9175 |
*
|
9176 |
+
* @return string Parsed HTML code for the heartbeat settings panel.
|
9177 |
*/
|
9178 |
function sucuriscan_settings_heartbeat(){
|
9179 |
// Current values set in the options table.
|
9556 |
$info_vars = array(
|
9557 |
'Plugin_version' => SUCURISCAN_VERSION,
|
9558 |
'Plugin_checksum' => SUCURISCAN_PLUGIN_CHECKSUM,
|
9559 |
+
'Last_filesystem_scan' => SucuriScanFSScanner::get_filesystem_runtime(TRUE),
|
9560 |
'Using_CloudProxy' => 'Unknown',
|
9561 |
'HTTP_Host' => 'Unknown',
|
9562 |
'Host_Name' => 'Unknown',
|