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

Version Description

  • Added option for keeping failed logins until the user removes them.
  • Bugfixes for user reported issues.
Download this release

Release Info

Developer akresic
Plugin Icon 128x128 Sucuri Security – Auditing, Malware Scanner and Security Hardening
Version 1.7.4
Comparing to
See all releases

Code changes from version 1.7.3 to 1.7.4

inc/css/sucuriscan-default-css.css CHANGED
@@ -130,11 +130,13 @@ div.sucuriscan-alert > a.close{position:absolute;top:10px;right:10px;font-size:1
130
  .sucuriscan-malwarescan-message{margin-bottom:20px !important}
131
  .sucuriscan-loading{background:#fff;text-align:center;padding:30px;padding-bottom:15px;border:1px solid #ddd;border-radius:4px}
132
  .sucuriscan-loading p, .sucuriscan-loading h3{margin:0;padding:0}
133
- .sucuriscan-loading .title{font-size:26px;margin-bottom:10px}
134
- .sucuriscan-loading .description{font-size:18px}
135
  .sucuriscan-sitelogo{width:190px;height:100px;background:url('http://sitecheck.sucuri.net/images/sucuri-sprite.png') no-repeat;margin:0 auto}
136
  .sucuriscan-sitecheck-form{margin:20px 0 0 0}
137
  .sucuriscan-sitecheck-form .button.button-hero{padding:0 46px}
 
 
138
  /* Scanner Results */
139
  .sucuriscan-maincontent .sucuriscan-border{border:0;border-left:4px solid #ddd}
140
  .sucuriscan-maincontent .sucuriscan-border > h3, .sucuriscan-maincontent .sucuriscan-border > .inside{border-top:1px solid #e5e5e5;border-right:1px solid #e5e5e5}
@@ -163,7 +165,7 @@ div.sucuriscan-alert > a.close{position:absolute;top:10px;right:10px;font-size:1
163
  .sucuriscan-maincontent .sucuriscan-integrity-message{position:relative}
164
  .sucuriscan-maincontent .sucuriscan-integrity-message .sucuriscan-integrity-mark{position:absolute;top:1px;right:1px;background:#7ad03a;font-weight:bold;color:#fff;line-height:35px;padding:0 10px;border-left:1px solid #ddd}
165
  .sucuriscan-maincontent .sucuriscan-auditlogs{margin-bottom:0}
166
- .sucuriscan-maincontent .sucuriscan-auditlogs td small{font-style:italic}
167
  .sucuriscan-maincontent .sucuriscan-auditlogs .sucuriscan-maxper-page{text-align:right}
168
  .sucuriscan-maincontent .sucuriscan-ignoredfiles{margin-top:0}
169
  .sucuriscan-maincontent .sucuriscan-modifiedfiles .sucuriscan-ellipsis{width:100px}
@@ -231,6 +233,8 @@ div.sucuriscan-alert > a.close{position:absolute;top:10px;right:10px;font-size:1
231
  .sucuriscan-maincontent .sucuriscan-infosys-htaccess .inside .sucuriscan-inline-alert-updated{margin-bottom:10px}
232
  .sucuriscan-maincontent .sucuriscan-errorlogs .inside .sucuriscan-inline-alert-error{margin-top:10px}
233
  .sucuriscan-maincontent .sucuriscan-errorlogs-list{}
 
 
234
  /* Parent Resetter: Midnight */
235
  .admin-color-blue .wrap div.sucuriscan-setup-notice, .admin-color-blue .sucuriscan-ad:nth-child(odd){background:#e5d1ae;border-color:#d39323}
236
  .admin-color-coffee .wrap div.sucuriscan-setup-notice, .admin-color-coffee .sucuriscan-ad:nth-child(odd){background:#e4cfbe;border-color:#b78a66}
130
  .sucuriscan-malwarescan-message{margin-bottom:20px !important}
131
  .sucuriscan-loading{background:#fff;text-align:center;padding:30px;padding-bottom:15px;border:1px solid #ddd;border-radius:4px}
132
  .sucuriscan-loading p, .sucuriscan-loading h3{margin:0;padding:0}
133
+ .sucuriscan-loading .title{font-size:28px;margin-bottom:10px}
134
+ .sucuriscan-loading .description{font-size:16px}
135
  .sucuriscan-sitelogo{width:190px;height:100px;background:url('http://sitecheck.sucuri.net/images/sucuri-sprite.png') no-repeat;margin:0 auto}
136
  .sucuriscan-sitecheck-form{margin:20px 0 0 0}
137
  .sucuriscan-sitecheck-form .button.button-hero{padding:0 46px}
138
+ .sucuriscan-loading .sucuriscan-sitecheck-disclaimer{text-align:justify;padding-top:20px;border-top:1px solid #ddd}
139
+ .sucuriscan-loading .sucuriscan-sitecheck-disclaimer p{font-size:10px}
140
  /* Scanner Results */
141
  .sucuriscan-maincontent .sucuriscan-border{border:0;border-left:4px solid #ddd}
142
  .sucuriscan-maincontent .sucuriscan-border > h3, .sucuriscan-maincontent .sucuriscan-border > .inside{border-top:1px solid #e5e5e5;border-right:1px solid #e5e5e5}
165
  .sucuriscan-maincontent .sucuriscan-integrity-message{position:relative}
166
  .sucuriscan-maincontent .sucuriscan-integrity-message .sucuriscan-integrity-mark{position:absolute;top:1px;right:1px;background:#7ad03a;font-weight:bold;color:#fff;line-height:35px;padding:0 10px;border-left:1px solid #ddd}
167
  .sucuriscan-maincontent .sucuriscan-auditlogs{margin-bottom:0}
168
+ .sucuriscan-maincontent .sucuriscan-auditlogs .sucuriscan-list-as-table{margin-bottom:0}
169
  .sucuriscan-maincontent .sucuriscan-auditlogs .sucuriscan-maxper-page{text-align:right}
170
  .sucuriscan-maincontent .sucuriscan-ignoredfiles{margin-top:0}
171
  .sucuriscan-maincontent .sucuriscan-modifiedfiles .sucuriscan-ellipsis{width:100px}
233
  .sucuriscan-maincontent .sucuriscan-infosys-htaccess .inside .sucuriscan-inline-alert-updated{margin-bottom:10px}
234
  .sucuriscan-maincontent .sucuriscan-errorlogs .inside .sucuriscan-inline-alert-error{margin-top:10px}
235
  .sucuriscan-maincontent .sucuriscan-errorlogs-list{}
236
+ .sucuriscan-maincontent .sucuriscan-subject-formats{margin:0}
237
+ .sucuriscan-maincontent .sucuriscan-subject-formats input[type=text]{width:40%;margin-left:10px}
238
  /* Parent Resetter: Midnight */
239
  .admin-color-blue .wrap div.sucuriscan-setup-notice, .admin-color-blue .sucuriscan-ad:nth-child(odd){background:#e5d1ae;border-color:#d39323}
240
  .admin-color-coffee .wrap div.sucuriscan-setup-notice, .admin-color-coffee .sucuriscan-ad:nth-child(odd){background:#e4cfbe;border-color:#b78a66}
inc/js/sucuriscan-scripts.js CHANGED
@@ -23,6 +23,10 @@ jQuery(document).ready(function($){
23
  var container = $('.sucuriscan-tab-containers > #sucuriscan-'+container_id);
24
 
25
  if( container.length ){
 
 
 
 
26
  $('.sucuriscan-tabs > ul a').removeClass(active_class);
27
  $('.sucuriscan-tab-containers > div').addClass(hidden_class);
28
  button.addClass(active_class);
23
  var container = $('.sucuriscan-tab-containers > #sucuriscan-'+container_id);
24
 
25
  if( container.length ){
26
+ var current_href = location.href.replace(location.hash, '');
27
+ var new_location_href = current_href + '#' + container_id;
28
+ window.history.pushState( {}, document.title, new_location_href );
29
+
30
  $('.sucuriscan-tabs > ul a').removeClass(active_class);
31
  $('.sucuriscan-tab-containers > div').addClass(hidden_class);
32
  button.addClass(active_class);
inc/tpl/malwarescan.html.tpl CHANGED
@@ -11,4 +11,17 @@
11
  </form>
12
 
13
  <div class="sucuriscan-sitelogo">&nbsp;</div>
 
 
 
 
 
 
 
 
 
 
 
 
 
14
  </div>
11
  </form>
12
 
13
  <div class="sucuriscan-sitelogo">&nbsp;</div>
14
+
15
+ <div class="sucuriscan-sitecheck-disclaimer">
16
+ <p>
17
+ The malware scanner is a free tool powered by <a href="http://sitecheck.sucuri.net/" target="_blank">
18
+ Sucuri SiteCheck</a>, it will check your website for known malware, blacklisting
19
+ status, website errors, and out-of-date software. Although we do our best to
20
+ provide the best results, 100% accuracy is not realistic, and not guaranteed.
21
+ You can also <a href="%%SUCURI.URL.Settings%%#settings-scanner">disable this
22
+ feature</a> from the settings page if you do not want to allow any of your
23
+ registered users to use it.
24
+ </p>
25
+ </div>
26
+
27
  </div>
inc/tpl/settings-general.html.tpl CHANGED
@@ -62,7 +62,7 @@
62
  </tr>
63
 
64
  <tr>
65
- <td>Notify events to</td>
66
  <td>%%SUCURI.NotifyTo%%</td>
67
  <td class="td-with-button">
68
  <form action="%%SUCURI.URL.Settings%%" method="post">
@@ -141,7 +141,7 @@
141
 
142
  <tr>
143
  <td>Log storage path</td>
144
- <td><span class="sucuriscan-monospace" title="%%SUCURI.DatastorePath%%">%%SUCURI.DatastorePathShort%%</span></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%%" />
62
  </tr>
63
 
64
  <tr>
65
+ <td>Send alerts to</td>
66
  <td>%%SUCURI.NotifyTo%%</td>
67
  <td class="td-with-button">
68
  <form action="%%SUCURI.URL.Settings%%" method="post">
141
 
142
  <tr>
143
  <td>Log storage path</td>
144
+ <td><span class="sucuriscan-monospace sucuriscan-wraptext" title="%%SUCURI.DatastorePath%%">%%SUCURI.DatastorePath%%</span></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%%" />
inc/tpl/settings-notifications.html.tpl CHANGED
@@ -1,7 +1,7 @@
1
 
2
  <div id="poststuff">
3
  <div class="postbox sucuriscan-border sucuriscan-table-description">
4
- <h3>Notification Settings</h3>
5
 
6
  <div class="inside">
7
  <p>
@@ -30,8 +30,8 @@
30
  <table class="wp-list-table widefat sucuriscan-table sucuriscan-settings-notifications">
31
  <thead>
32
  <tr>
33
- <th colspan="3" class="thead-with-button">
34
- <span>Notification Settings</span>
35
  <div class="thead-topright-action">
36
  <input type="hidden" name="sucuriscan_page_nonce" value="%%SUCURI.PageNonce%%" />
37
  <button type="submit" name="sucuriscan_save_notification_settings" class="button-primary">Save</button>
@@ -42,6 +42,32 @@
42
 
43
  <tbody>
44
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
45
  %%SUCURI.NotificationOptions%%
46
 
47
  </tbody>
1
 
2
  <div id="poststuff">
3
  <div class="postbox sucuriscan-border sucuriscan-table-description">
4
+ <h3>Alert Settings</h3>
5
 
6
  <div class="inside">
7
  <p>
30
  <table class="wp-list-table widefat sucuriscan-table sucuriscan-settings-notifications">
31
  <thead>
32
  <tr>
33
+ <th class="thead-with-button">
34
+ <span>Alert Settings</span>
35
  <div class="thead-topright-action">
36
  <input type="hidden" name="sucuriscan_page_nonce" value="%%SUCURI.PageNonce%%" />
37
  <button type="submit" name="sucuriscan_save_notification_settings" class="button-primary">Save</button>
42
 
43
  <tbody>
44
 
45
+ <tr>
46
+ <td>
47
+ <p>
48
+ Format of the subject for the email alerts, by default the plugin will use the
49
+ domain of the site, and the event that is going to be reported, you can change
50
+ this to also report the remote address of the user involved in the operation
51
+ that is being reported to quickly determine if the event is valid or not reading
52
+ the subject of the email.
53
+ </p>
54
+
55
+ <ul class="sucuriscan-subject-formats">
56
+
57
+ %%SUCURI.EmailSubjectOptions%%
58
+
59
+ <li>
60
+ <label>
61
+ <input type="radio" name="sucuriscan_email_subject" value="custom" %%SUCURI.EmailSubjectCustom.Checked%% />
62
+ <span>Custom format</span>
63
+ <input type="text" name="sucuriscan_custom_email_subject" value="%%SUCURI.EmailSubjectCustom.Value%%" />
64
+ </label>
65
+ </li>
66
+
67
+ </ul>
68
+ </td>
69
+ </tr>
70
+
71
  %%SUCURI.NotificationOptions%%
72
 
73
  </tbody>
inc/tpl/settings-notifications.snippet.tpl CHANGED
@@ -1,6 +1,6 @@
1
 
2
  <tr class="%%SUCURI.Notification.CssClass%%">
3
- <td colspan="3">
4
  <div>
5
  <label>
6
  <input type="hidden" name="%%SUCURI.Notification.Name%%" value="0" />
1
 
2
  <tr class="%%SUCURI.Notification.CssClass%%">
3
+ <td>
4
  <div>
5
  <label>
6
  <input type="hidden" name="%%SUCURI.Notification.Name%%" value="0" />
inc/tpl/settings-scanner.html.tpl CHANGED
@@ -109,6 +109,30 @@
109
  </td>
110
  </tr>
111
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
112
  <tr class="alternate">
113
  <td>Last Scanning</td>
114
  <td><span class="sucuriscan-monospace">%%SUCURI.ScanningRuntimeHuman%%</span></td>
109
  </td>
110
  </tr>
111
 
112
+ <tr class="alternate">
113
+ <td>SiteCheck scanner</td>
114
+ <td>%%SUCURI.SiteCheckScannerStatus%%</td>
115
+ <td class="td-with-button">
116
+ <form action="%%SUCURI.URL.Settings%%#settings-scanner" method="post">
117
+ <input type="hidden" name="sucuriscan_page_nonce" value="%%SUCURI.PageNonce%%" />
118
+ <input type="hidden" name="sucuriscan_sitecheck_scanner" value="%%SUCURI.SiteCheckScannerSwitchValue%%" />
119
+ <button type="submit" class="button-primary %%SUCURI.SiteCheckScannerSwitchCssClass%%">%%SUCURI.SiteCheckScannerSwitchText%%</button>
120
+ </form>
121
+ </td>
122
+ </tr>
123
+
124
+ <tr>
125
+ <td>SiteCheck counter</td>
126
+ <td><span class="sucuriscan-monospace">%%SUCURI.SiteCheckCounter%% scans so far</span></td>
127
+ <td class="td-with-button">
128
+ <form action="%%SUCURI.URL.Scanner%%" method="post">
129
+ <input type="hidden" name="sucuriscan_page_nonce" value="%%SUCURI.PageNonce%%" />
130
+ <input type="hidden" name="sucuriscan_malware_scan" value="1" />
131
+ <button type="submit" class="button-primary">Force Scan</button>
132
+ </form>
133
+ </td>
134
+ </tr>
135
+
136
  <tr class="alternate">
137
  <td>Last Scanning</td>
138
  <td><span class="sucuriscan-monospace">%%SUCURI.ScanningRuntimeHuman%%</span></td>
readme.txt CHANGED
@@ -3,7 +3,7 @@ Contributors: dd@sucuri.net
3
  Donate Link: http://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, website firewall, Website Security, Performance Optimization, Zero Day, Software Vulnerability, Exploits, Hacks, Attackers, Bad Actors, Reverse Proxy, Two Factor Security, Two Factor Authentication, Security Logs, HeatBleed Vulnerability, Website Protection, Bash Vulnerability, RevSlider Vulnerability, MailPoet Vulnerability, Malware Prevention, Website Firewall, Website AntiVirus, Security Response, Security Detection, Security Prevention
5
  Requires at least:3.2
6
- Stable tag:1.7.3
7
  Tested up to: 4.0.1
8
 
9
  The Sucuri WordPress Security plugin is a security toolset for security integrity monitoring, malware detection and security hardening.
@@ -13,7 +13,7 @@ The Sucuri WordPress Security plugin is a security toolset for security integrit
13
 
14
 
15
  Sucuri Inc is a globally recognized authority in all matters related to
16
- website security, with specialization in WordPress Security.
17
 
18
  The Sucuri Security WordPress Security plugin is free to all WordPress users.
19
  It is a security suite meant to complement your existing security posture. It
@@ -38,11 +38,11 @@ This is perhaps the most underutilized security function. It’s the act of
38
  monitoring all security related events within your WordPress install. The
39
  challenge is, what makes up a security event. In the eyes of Sucuri, any
40
  change that occurs within the application could be categorized as a security
41
- event, as such we try to record it.
42
 
43
  This is important because it allows you, the website owner, the ability keep a
44
  good eye on the various changes occurring within your environment. Who is
45
- logging in? What changes are being made?
46
 
47
  Here is a video of the Security Activity Monitoring feature:
48
 
@@ -52,7 +52,7 @@ This feature is logging all activity to the Sucuri cloud, for safe keeping.
52
  This ensures that an attacker is not able to wipe your forensic data and
53
  prevent further security analysis after a compromise. If an attacker is able
54
  to bypass your security controls, your security logs will be kept safe within
55
- the Sucuri Security Operations Center (SOC).
56
 
57
  This feature is particularly important to website / system administrators and
58
  security experts looking to understand what is going on with their website and
@@ -65,11 +65,11 @@ Security File Integrity Monitoring has been fundamental to the world of
65
  security. It’s the act of comparing a known good with the current state. If
66
  the current state differs from the known good, you know you have a problem.
67
  This is the basis of a lot of host Intrusion detection systems. It’s what we
68
- have built into the plugin.
69
 
70
  It will create a <strong>known good</strong> the minute the plugin is
71
  installed. This will be of all the directories at the root of the install,
72
- this includes plugins, themes and core files.
73
 
74
  Here is a video of the Security File Integrity Monitoring feature:
75
 
@@ -82,7 +82,7 @@ This feature is powered by our very powerful scanning engine, found on our
82
  free security scanner - <a href="http://sitecheck.sucuri.net">SiteCheck</a>. It’s
83
  important to take some time to <a
84
  href="http://blog.sucuri.net/2012/10/ask-sucuri-how-does-sitecheck-work.html">understand
85
- how this scanner works</a>.
86
 
87
  Here is a video of the Remote Security Malware Scanning feature:
88
 
@@ -114,10 +114,10 @@ following:
114
  These are some of the largest blacklisting entities, each having the ability
115
  to directly impact your brands online reputation. By synchronize with their
116
  environments we’re able to tell you, upon scan, whether any of them are
117
- negatively flagging your website with a security related issue.
118
 
119
  If they do, then via our Website AntiVirus product, we’re able to help you get
120
- off the their security blacklist.
121
 
122
 
123
  = Effective Security Hardening =
@@ -126,7 +126,7 @@ It’s easy to get lost in the world of security hardening. At Sucuri we clean
126
  100’s of websites a day, many with the various security hardening
127
  configurations you find in various WordPress Security presentations. In this
128
  section, we add those that we feel to be most effective, and that complement
129
- the entire Sucuri suite of products.
130
 
131
  Here is a video of the Effective Security Hardening feature:
132
 
@@ -138,7 +138,7 @@ Here is a video of the Effective Security Hardening feature:
138
 
139
  Regardless of how good your security posture is, sometimes it’s impossible to
140
  prevent the inevitable. When this happens, we’ve included a section to help
141
- you walk through the three key things you should do after a compromise.
142
 
143
  Here is a video of the Post-Hack Security Actions feature:
144
 
@@ -152,7 +152,7 @@ of the issues. This is why we have made available security notifications. We
152
  have also expanded the various security related events, to provide website
153
  owners more flexibility in regards to what they want to know about. As a
154
  website owner, you have the option to make these security alerts as quiet or
155
- noisy as you would like.
156
 
157
 
158
  = Sucuri CloudProxy Website Firewall (Add On Security Service) =
@@ -188,7 +188,7 @@ Here is a video of the Sucuri Security Website Firewall (Add On Security Service
188
  The Sucuri Security WordPress Security plugin is built by the team that is
189
  known for their proactive approach to security. It is built using intelligence
190
  gathered from thousands upon thousands of remediation cases, millions of
191
- unique domain scans and 10’s of millions of website security attack blocks.
192
 
193
 
194
  == Installation ==
@@ -204,7 +204,7 @@ Here is a quick video walking you through the installation and configuration of
204
  [youtube https://www.youtube.com/watch?v=KC3UC_Y27G0]
205
 
206
 
207
- To install Sucuri Security and complement your Security posture:
208
 
209
 
210
  1. You will want to log into your WordPress administration panel - (e.g.,
@@ -230,11 +230,11 @@ automatically for you. Simply click on <strong>Generate API Key for
230
  XXXXXX</strong>
231
 
232
  9. Once the API key is generated the page will redirect you to your dashboard
233
- and the plugin is automatically configured for you.
234
 
235
 
236
  To configure the Sucuri WordPress Security plugin for your specific Security
237
- needs:
238
 
239
  1. Navigate to the <strong>Sucuri Security</strong> menu option (left hand
240
  side).
@@ -247,7 +247,7 @@ The <strong>Settings</strong> page allows you to configure the website to your
247
  preferred security needs. Some of it’s features include changing the email
248
  notifications, via the <strong>notification settings</strong> tab or disabling
249
  integrity checking. We encourage you to visit this section and tune your
250
- security needs as you see fit.
251
 
252
 
253
  == FAQ ==
@@ -282,7 +282,7 @@ install the free version, the free version will overwrite the premium version.
282
  = Do I still need Sucuri’s products if I have this plugin? =
283
 
284
  Yes. This plugin compliments your existing security toolsets. It is not
285
- designed to replace the Sucuri AntiVirus or Firewall products.
286
 
287
  = Where do I get support for this plugin? =
288
 
@@ -295,7 +295,7 @@ submit a ticket here</a>.
295
 
296
  The plugin does not, but there might be issues with our scanners. If you get
297
  an “Unable to Properly Scan Your Site” It’s likely because the WordFence
298
- plugin is blocking our scanner as an invalid crawler.
299
 
300
  You would have to white list our IP address on the WordFence dashboard.
301
 
@@ -305,10 +305,10 @@ You would have to white list our IP address on the WordFence dashboard.
305
  Because the security malware scanner is remote, it is unable to see things
306
  that are on the server but that are not displaying on the browser. If you are
307
  interested in this, we encourage you to subscribe to our Website AntiVirus
308
- product.
309
 
310
  This issues includes things like Phishing pages, Backdoors, Mailer Scripts,
311
- etc…
312
 
313
  = Your plugin didn’t detect this malware? =
314
 
@@ -316,13 +316,13 @@ This happens, reference the Remote scanner limitations above. This should not
316
  be confused with our Website AntiVirus product. If you have malware, and you
317
  are a client, submit a ticket so that <a
318
  href=“https://support.sucuri.net/support/?new&mremoval”>we can help you get
319
- clean.</a>
320
 
321
  If you are not a client, and you want to share what you have found please send
322
- it to <a href=“mailto:labs@sucuri.net”>labs@sucuri.net</a>.
323
 
324
  The plugin is not performing application level malware / security scanning so
325
- this is not uncommon.
326
 
327
  = Is it free to enable the Website Firewall option? =
328
 
@@ -336,7 +336,7 @@ No, it will not.
336
 
337
  = Do the logs get stored to my database? =
338
 
339
- No, it does not.
340
 
341
  = Are there any issues installing your plugin with any hosts? =
342
 
@@ -352,6 +352,14 @@ service from the WordPress dashboard.
352
 
353
  == Changelog ==
354
 
 
 
 
 
 
 
 
 
355
  = 1.7.2 =
356
  * Messaging and FAQ updates.
357
 
@@ -386,11 +394,11 @@ service from the WordPress dashboard.
386
  = 1.6.4 =
387
  * Fixed API generation bug.
388
 
389
- = 1.6.3 =
390
- * Added proper brute force alerts.
391
- * Added option to restrict number of emails.
392
- * Added more description to the emails.
393
- * Added a list of failed login attempts inside the last login tab.
394
 
395
  = 1.6.2 =
396
  * Setting a maximum number of emails per hour.
@@ -418,7 +426,7 @@ service from the WordPress dashboard.
418
  * Added IPv6 support.
419
  * Fixed links and messaging.
420
 
421
- = 1.5.5 =
422
  * Added list of logged in users.
423
  * Added system page.
424
  * Change the integrity checking to use WP API.
@@ -438,7 +446,7 @@ service from the WordPress dashboard.
438
  * Adding a web firewall check on our hardening page.
439
 
440
  = 1.4.7 =
441
- * Cleaning up the code a bit.
442
  * Only displaying last login messages to admin users.
443
  * Storing the logs into a log file instead of the db.
444
 
@@ -504,10 +512,10 @@ service from the WordPress dashboard.
504
  * Added 1-click hardening.
505
 
506
  = 1.1.2 =
507
- * First release that is good to be used (debugging code removed).
508
 
509
- = 1.1.1 =
510
- * First public release.
511
 
512
 
513
  == Credits ==
3
  Donate Link: http://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, website firewall, Website Security, Performance Optimization, Zero Day, Software Vulnerability, Exploits, Hacks, Attackers, Bad Actors, Reverse Proxy, Two Factor Security, Two Factor Authentication, Security Logs, HeatBleed Vulnerability, Website Protection, Bash Vulnerability, RevSlider Vulnerability, MailPoet Vulnerability, Malware Prevention, Website Firewall, Website AntiVirus, Security Response, Security Detection, Security Prevention
5
  Requires at least:3.2
6
+ Stable tag:1.7.4
7
  Tested up to: 4.0.1
8
 
9
  The Sucuri WordPress Security plugin is a security toolset for security integrity monitoring, malware detection and security hardening.
13
 
14
 
15
  Sucuri Inc is a globally recognized authority in all matters related to
16
+ website security, with specialization in WordPress Security.
17
 
18
  The Sucuri Security WordPress Security plugin is free to all WordPress users.
19
  It is a security suite meant to complement your existing security posture. It
38
  monitoring all security related events within your WordPress install. The
39
  challenge is, what makes up a security event. In the eyes of Sucuri, any
40
  change that occurs within the application could be categorized as a security
41
+ event, as such we try to record it.
42
 
43
  This is important because it allows you, the website owner, the ability keep a
44
  good eye on the various changes occurring within your environment. Who is
45
+ logging in? What changes are being made?
46
 
47
  Here is a video of the Security Activity Monitoring feature:
48
 
52
  This ensures that an attacker is not able to wipe your forensic data and
53
  prevent further security analysis after a compromise. If an attacker is able
54
  to bypass your security controls, your security logs will be kept safe within
55
+ the Sucuri Security Operations Center (SOC).
56
 
57
  This feature is particularly important to website / system administrators and
58
  security experts looking to understand what is going on with their website and
65
  security. It’s the act of comparing a known good with the current state. If
66
  the current state differs from the known good, you know you have a problem.
67
  This is the basis of a lot of host Intrusion detection systems. It’s what we
68
+ have built into the plugin.
69
 
70
  It will create a <strong>known good</strong> the minute the plugin is
71
  installed. This will be of all the directories at the root of the install,
72
+ this includes plugins, themes and core files.
73
 
74
  Here is a video of the Security File Integrity Monitoring feature:
75
 
82
  free security scanner - <a href="http://sitecheck.sucuri.net">SiteCheck</a>. It’s
83
  important to take some time to <a
84
  href="http://blog.sucuri.net/2012/10/ask-sucuri-how-does-sitecheck-work.html">understand
85
+ how this scanner works</a>.
86
 
87
  Here is a video of the Remote Security Malware Scanning feature:
88
 
114
  These are some of the largest blacklisting entities, each having the ability
115
  to directly impact your brands online reputation. By synchronize with their
116
  environments we’re able to tell you, upon scan, whether any of them are
117
+ negatively flagging your website with a security related issue.
118
 
119
  If they do, then via our Website AntiVirus product, we’re able to help you get
120
+ off the their security blacklist.
121
 
122
 
123
  = Effective Security Hardening =
126
  100’s of websites a day, many with the various security hardening
127
  configurations you find in various WordPress Security presentations. In this
128
  section, we add those that we feel to be most effective, and that complement
129
+ the entire Sucuri suite of products.
130
 
131
  Here is a video of the Effective Security Hardening feature:
132
 
138
 
139
  Regardless of how good your security posture is, sometimes it’s impossible to
140
  prevent the inevitable. When this happens, we’ve included a section to help
141
+ you walk through the three key things you should do after a compromise.
142
 
143
  Here is a video of the Post-Hack Security Actions feature:
144
 
152
  have also expanded the various security related events, to provide website
153
  owners more flexibility in regards to what they want to know about. As a
154
  website owner, you have the option to make these security alerts as quiet or
155
+ noisy as you would like.
156
 
157
 
158
  = Sucuri CloudProxy Website Firewall (Add On Security Service) =
188
  The Sucuri Security WordPress Security plugin is built by the team that is
189
  known for their proactive approach to security. It is built using intelligence
190
  gathered from thousands upon thousands of remediation cases, millions of
191
+ unique domain scans and 10’s of millions of website security attack blocks.
192
 
193
 
194
  == Installation ==
204
  [youtube https://www.youtube.com/watch?v=KC3UC_Y27G0]
205
 
206
 
207
+ To install Sucuri Security and complement your Security posture:
208
 
209
 
210
  1. You will want to log into your WordPress administration panel - (e.g.,
230
  XXXXXX</strong>
231
 
232
  9. Once the API key is generated the page will redirect you to your dashboard
233
+ and the plugin is automatically configured for you.
234
 
235
 
236
  To configure the Sucuri WordPress Security plugin for your specific Security
237
+ needs:
238
 
239
  1. Navigate to the <strong>Sucuri Security</strong> menu option (left hand
240
  side).
247
  preferred security needs. Some of it’s features include changing the email
248
  notifications, via the <strong>notification settings</strong> tab or disabling
249
  integrity checking. We encourage you to visit this section and tune your
250
+ security needs as you see fit.
251
 
252
 
253
  == FAQ ==
282
  = Do I still need Sucuri’s products if I have this plugin? =
283
 
284
  Yes. This plugin compliments your existing security toolsets. It is not
285
+ designed to replace the Sucuri AntiVirus or Firewall products.
286
 
287
  = Where do I get support for this plugin? =
288
 
295
 
296
  The plugin does not, but there might be issues with our scanners. If you get
297
  an “Unable to Properly Scan Your Site” It’s likely because the WordFence
298
+ plugin is blocking our scanner as an invalid crawler.
299
 
300
  You would have to white list our IP address on the WordFence dashboard.
301
 
305
  Because the security malware scanner is remote, it is unable to see things
306
  that are on the server but that are not displaying on the browser. If you are
307
  interested in this, we encourage you to subscribe to our Website AntiVirus
308
+ product.
309
 
310
  This issues includes things like Phishing pages, Backdoors, Mailer Scripts,
311
+ etc…
312
 
313
  = Your plugin didn’t detect this malware? =
314
 
316
  be confused with our Website AntiVirus product. If you have malware, and you
317
  are a client, submit a ticket so that <a
318
  href=“https://support.sucuri.net/support/?new&mremoval”>we can help you get
319
+ clean.</a>
320
 
321
  If you are not a client, and you want to share what you have found please send
322
+ it to <a href=“mailto:labs@sucuri.net”>labs@sucuri.net</a>.
323
 
324
  The plugin is not performing application level malware / security scanning so
325
+ this is not uncommon.
326
 
327
  = Is it free to enable the Website Firewall option? =
328
 
336
 
337
  = Do the logs get stored to my database? =
338
 
339
+ No, it does not.
340
 
341
  = Are there any issues installing your plugin with any hosts? =
342
 
352
 
353
  == Changelog ==
354
 
355
+ = 1.7.4 =
356
+ * Added option for keeping failed logins until the user removes them.
357
+ * Bugfixes for user reported issues.
358
+
359
+ = 1.7.3 =
360
+ * Error log panel.
361
+ * Various bug fixes.
362
+
363
  = 1.7.2 =
364
  * Messaging and FAQ updates.
365
 
394
  = 1.6.4 =
395
  * Fixed API generation bug.
396
 
397
+ = 1.6.3 =
398
+ * Added proper brute force alerts.
399
+ * Added option to restrict number of emails.
400
+ * Added more description to the emails.
401
+ * Added a list of failed login attempts inside the last login tab.
402
 
403
  = 1.6.2 =
404
  * Setting a maximum number of emails per hour.
426
  * Added IPv6 support.
427
  * Fixed links and messaging.
428
 
429
+ = 1.5.5 =
430
  * Added list of logged in users.
431
  * Added system page.
432
  * Change the integrity checking to use WP API.
446
  * Adding a web firewall check on our hardening page.
447
 
448
  = 1.4.7 =
449
+ * Cleaning up the code a bit.
450
  * Only displaying last login messages to admin users.
451
  * Storing the logs into a log file instead of the db.
452
 
512
  * Added 1-click hardening.
513
 
514
  = 1.1.2 =
515
+ * First release that is good to be used (debugging code removed).
516
 
517
+ = 1.1.1 =
518
+ * First public release.
519
 
520
 
521
  == Credits ==
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.3
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.3');
70
 
71
  /**
72
  * The name of the Sucuri plugin main file.
@@ -187,7 +187,7 @@ if( defined('SUCURISCAN') ){
187
  */
188
 
189
  $sucuriscan_notify_options = array(
190
- // 'sucuriscan_prettify_mails' => 'Enable email alerts in HTML (uncheck to get email in text/plain)', // TODO: Investigate HTML mails issues.
191
  'sucuriscan_lastlogin_redirection' => 'Allow redirection after login to report the last-login information',
192
  'sucuriscan_notify_user_registration' => 'Enable email alerts for new user registration',
193
  'sucuriscan_notify_success_login' => 'Enable email alerts for successful logins',
@@ -248,6 +248,13 @@ if( defined('SUCURISCAN') ){
248
  $sucuriscan_no_notices_in = array(
249
  );
250
 
 
 
 
 
 
 
 
251
  /**
252
  * Remove the WordPress generator meta-tag from the source code.
253
  */
@@ -1386,7 +1393,8 @@ class SucuriScanFileInfo extends SucuriScan {
1386
  | FilesystemIterator::UNIX_PATHS;
1387
  $objects = new RecursiveIteratorIterator(
1388
  new RecursiveDirectoryIterator($filepath, $flags),
1389
- RecursiveIteratorIterator::SELF_FIRST
 
1390
  );
1391
  } else {
1392
  $objects = new DirectoryIterator($filepath);
@@ -2162,6 +2170,8 @@ class SucuriScanOption extends SucuriScanRequest {
2162
  'sucuriscan_scan_modfiles' => 'enabled',
2163
  'sucuriscan_scan_checksums' => 'enabled',
2164
  'sucuriscan_scan_errorlogs' => 'enabled',
 
 
2165
  'sucuriscan_parse_errorlogs' => 'enabled',
2166
  'sucuriscan_errorlogs_limit' => 30,
2167
  'sucuriscan_ignore_scanning' => 'disabled',
@@ -2171,6 +2181,7 @@ class SucuriScanOption extends SucuriScanRequest {
2171
  'sucuriscan_emails_sent' => 0,
2172
  'sucuriscan_emails_per_hour' => 5,
2173
  'sucuriscan_last_email_at' => time(),
 
2174
  'sucuriscan_prettify_mails' => 'disabled',
2175
  'sucuriscan_notify_success_login' => 'enabled',
2176
  'sucuriscan_notify_failed_login' => 'enabled',
@@ -2647,7 +2658,7 @@ class SucuriScanEvent extends SucuriScan {
2647
  * @param boolean $force_scan Whether the filesystem scan was forced by an administrator user or not.
2648
  * @return boolean Either TRUE or FALSE representing the success or fail of the operation respectively.
2649
  */
2650
- private function verify_run( $runtime=0, $force_scan=FALSE ){
2651
  $option_name = ':runtime';
2652
  $last_run = SucuriScanOption::get_option($option_name);
2653
  $current_time = time();
@@ -2680,7 +2691,7 @@ class SucuriScanEvent extends SucuriScan {
2680
  *
2681
  * @return boolean TRUE if the current WordPress version must be reported, FALSE otherwise.
2682
  */
2683
- private function report_site_version(){
2684
  $option_name = ':site_version';
2685
  $reported_version = SucuriScanOption::get_option($option_name);
2686
  $wp_version = self::site_version();
@@ -2860,27 +2871,29 @@ class SucuriScanEvent extends SucuriScan {
2860
  return TRUE;
2861
  }
2862
 
2863
- foreach ( $trusted_ips as $cache_key => $ip_info ) {
2864
- $ip_parts = explode( '.', $ip_info->remote_addr );
2865
- $ip_pattern = FALSE;
 
2866
 
2867
- // Generate the regular expression for CIDR range 24.
2868
- if ( $ip_info->cidr_range == 24 ) {
2869
- $ip_pattern = sprintf( '/^%d\.%d\.%d\.[0-9]{1,3}$/', $ip_parts[0], $ip_parts[1], $ip_parts[2] );
2870
- }
2871
 
2872
- // Generate the regular expression for CIDR range 16.
2873
- elseif ( $ip_info->cidr_range == 16 ) {
2874
- $ip_pattern = sprintf( '/^%d\.%d(\.[0-9]{1,3}){2}$/', $ip_parts[0], $ip_parts[1] );
2875
- }
2876
 
2877
- // Generate the regular expression for CIDR range 8.
2878
- elseif ( $ip_info->cidr_range == 8 ) {
2879
- $ip_pattern = sprintf( '/^%d(\.[0-9]{1,3}){3}$/', $ip_parts[0] );
2880
- }
2881
 
2882
- if ( $ip_pattern && preg_match($ip_pattern, $remote_addr) ) {
2883
- return TRUE;
 
2884
  }
2885
  }
2886
 
@@ -4208,7 +4221,7 @@ class SucuriScanAPI extends SucuriScanOption {
4208
  */
4209
  public static function get_official_checksums( $version=0 ){
4210
  $url = 'http://api.wordpress.org/core/checksums/1.0/';
4211
- $language = defined('WPLANG') ? WPLANG : 'en_US';
4212
  $response = self::api_call( $url, 'GET', array(
4213
  'version' => $version,
4214
  'locale' => $language,
@@ -4411,8 +4424,7 @@ class SucuriScanMail extends SucuriScanOption {
4411
  * @return boolean Whether the emails will be in HTML or Plain/Text.
4412
  */
4413
  public static function prettify_mails(){
4414
- // return ( self::get_option(':prettify_mails') === 'enabled' ); // TODO: Investigate HTML mails issues.
4415
- return FALSE;
4416
  }
4417
 
4418
  /**
@@ -4427,7 +4439,6 @@ class SucuriScanMail extends SucuriScanOption {
4427
  public static function send_mail( $email='', $subject='', $message='', $data_set=array() ){
4428
  $headers = array();
4429
  $subject = ucwords(strtolower($subject));
4430
- $wp_domain = self::get_domain();
4431
  $force = FALSE;
4432
  $debug = FALSE;
4433
 
@@ -4462,7 +4473,7 @@ class SucuriScanMail extends SucuriScanOption {
4462
 
4463
  if( $debug ){ die($message); }
4464
 
4465
- $subject = sprintf( 'Sucuri Alert, %s, %s', $wp_domain, $subject );
4466
  $mail_sent = wp_mail( $email, $subject, $message, $headers );
4467
 
4468
  if( $mail_sent ){
@@ -4477,6 +4488,38 @@ class SucuriScanMail extends SucuriScanOption {
4477
  return FALSE;
4478
  }
4479
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4480
  /**
4481
  * Generate a HTML version of the message that will be sent through an email.
4482
  *
@@ -4655,6 +4698,13 @@ class SucuriScanTemplate extends SucuriScanRequest {
4655
  }
4656
 
4657
  foreach( $sub_pages as $sub_page_func => $sub_page_title ){
 
 
 
 
 
 
 
4658
  $func_parts = explode( '_', $sub_page_func, 2 );
4659
 
4660
  if( isset($func_parts[1]) ){
@@ -4890,6 +4940,24 @@ class SucuriScanTemplate extends SucuriScanRequest {
4890
  return $html_links;
4891
  }
4892
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4893
  }
4894
 
4895
  /**
@@ -5358,6 +5426,13 @@ class SucuriScanInterface {
5358
  $sub_pages = is_array($sucuriscan_pages) ? $sucuriscan_pages : array();
5359
 
5360
  foreach( $sub_pages as $sub_page_func => $sub_page_title ){
 
 
 
 
 
 
 
5361
  $page_func = $sub_page_func . '_page';
5362
 
5363
  add_submenu_page(
@@ -5448,8 +5523,6 @@ class SucuriScanInterface {
5448
  * @return void
5449
  */
5450
  public static function check_permissions(){
5451
- global $sucuriscan_pages;
5452
-
5453
  if(
5454
  !function_exists('current_user_can')
5455
  || !current_user_can('manage_options')
@@ -5592,7 +5665,7 @@ function sucuriscan_sitecheck_info( $res=array() ){
5592
  if( preg_match('/^ERROR:(.*)/', $res, $error_m) ){
5593
  SucuriScanInterface::error( 'The site <code>' . $clean_domain . '</code> was not scanned: ' . $error_m[1] );
5594
  } else {
5595
- SucuriScanInterface::error( 'The API returned data that can not be processed.' );
5596
  }
5597
  }
5598
 
@@ -5607,6 +5680,12 @@ function sucuriscan_sitecheck_info( $res=array() ){
5607
  }
5608
  }
5609
 
 
 
 
 
 
 
5610
  ob_start();
5611
  ?>
5612
 
@@ -5848,6 +5927,12 @@ function sucuriscan_sitecheck_info( $res=array() ){
5848
  <?php endforeach; ?>
5849
  <?php endif; ?>
5850
 
 
 
 
 
 
 
5851
  <!-- Possible recommendations or outdated software on the site. -->
5852
  <?php if( $outdated_warns_exist || $recommendations_exist ): ?>
5853
  <tr>
@@ -5896,29 +5981,39 @@ function sucuriscan_sitecheck_info( $res=array() ){
5896
  <div id="sucuriscan-website-links">
5897
  <table class="wp-list-table widefat sucuriscan-table sucuriscan-scanner-links">
5898
  <tbody>
5899
- <?php foreach( $possible_url_keys as $result_url_key=>$result_url_title ): ?>
5900
 
5901
- <?php if( isset($res['LINKS'][$result_url_key]) ): ?>
5902
- <tr>
5903
- <th colspan="2">
5904
- <?php printf(
5905
- '%s (%d found)',
5906
- __($result_url_title),
5907
- count($res['LINKS'][$result_url_key])
5908
- ) ?>
5909
- </th>
5910
- </tr>
5911
 
5912
- <?php foreach( $res['LINKS'][$result_url_key] as $url_path ): ?>
5913
  <tr>
5914
- <td colspan="2">
5915
- <span class="sucuriscan-monospace sucuriscan-wraptext"><?php _e($url_path) ?></span>
5916
- </td>
 
 
 
 
5917
  </tr>
5918
- <?php endforeach; ?>
5919
- <?php endif; ?>
5920
 
5921
- <?php endforeach; ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5922
  </tbody>
5923
  </table>
5924
  </div>
@@ -7220,7 +7315,7 @@ function sucuriscan_integrity_form_submissions(){
7220
  if( SucuriScanInterface::check_nonce() ){
7221
 
7222
  // Force the execution of the filesystem scanner.
7223
- if( SucuriScanRequest::post(':force_scan') ){
7224
  SucuriScanEvent::notify_event( 'plugin_change', 'Filesystem scan forced at: ' . date('r') );
7225
  SucuriScanEvent::filesystem_scan(TRUE);
7226
  }
@@ -7315,8 +7410,6 @@ function sucuriscan_auditlogs(){
7315
  $logs_limit = $page_number * $max_per_page;
7316
  $audit_logs = SucuriScanAPI::get_logs($logs_limit);
7317
 
7318
- $show_all = TRUE;
7319
-
7320
  $template_variables = array(
7321
  'PageTitle' => 'Audit Logs',
7322
  'AuditLogs.List' => '',
@@ -7359,7 +7452,6 @@ function sucuriscan_auditlogs(){
7359
  $snippet_data['AuditLog.Extra'] .= '<li>' . SucuriScan::escape($log_extra) . '</li>';
7360
  }
7361
  $snippet_data['AuditLog.Extra'] .= '</ul>';
7362
- $snippet_data['AuditLog.Extra'] .= '<small>For Mac users, this is a scrollable container</small>';
7363
  }
7364
 
7365
  $template_variables['AuditLogs.List'] .= SucuriScanTemplate::get_snippet('integrity-auditlogs', $snippet_data);
@@ -7370,19 +7462,21 @@ function sucuriscan_auditlogs(){
7370
  $template_variables['AuditLogs.Count'] = $counter_i;
7371
  $template_variables['AuditLogs.NoItemsVisibility'] = 'hidden';
7372
 
7373
- if( $total_items > 0 ){
7374
  $max_pages = ceil( $audit_logs->total_entries / $max_per_page );
7375
 
7376
  if( $max_pages > SUCURISCAN_MAX_PAGINATION_BUTTONS ){
7377
  $max_pages = SUCURISCAN_MAX_PAGINATION_BUTTONS;
7378
  }
7379
 
7380
- $template_variables['AuditLogs.PaginationVisibility'] = 'visible';
7381
- $template_variables['AuditLogs.PaginationLinks'] = SucuriScanTemplate::get_pagination(
7382
- '%%SUCURI.URL.Home%%',
7383
- $max_per_page * $max_pages,
7384
- $max_per_page
7385
- );
 
 
7386
  }
7387
  }
7388
 
@@ -8989,6 +9083,7 @@ function sucuriscan_settings_form_submissions( $page_nonce=NULL ){
8989
  $sucuriscan_notify_options,
8990
  $sucuriscan_emails_per_hour,
8991
  $sucuriscan_maximum_failed_logins,
 
8992
  $sucuriscan_verify_ssl_cert;
8993
 
8994
  // Use this conditional to avoid double checking.
@@ -9078,6 +9173,14 @@ function sucuriscan_settings_form_submissions( $page_nonce=NULL ){
9078
  }
9079
  }
9080
 
 
 
 
 
 
 
 
 
9081
  // Modify the schedule of the filesystem scanner.
9082
  if( $frequency = SucuriScanRequest::post(':scan_frequency') ){
9083
  if( array_key_exists($frequency, $sucuriscan_schedule_allowed) ){
@@ -9223,6 +9326,41 @@ function sucuriscan_settings_form_submissions( $page_nonce=NULL ){
9223
  }
9224
  }
9225
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9226
  // Reset all the plugin's options.
9227
  if( SucuriScanRequest::post(':reset_options') !== FALSE ){
9228
  // Notify the event before the API key is removed.
@@ -9404,6 +9542,7 @@ function sucuriscan_settings_general(){
9404
  $emails_per_hour = SucuriScanOption::get_option(':emails_per_hour');
9405
  $maximum_failed_logins = SucuriScanOption::get_option(':maximum_failed_logins');
9406
  $verify_ssl_cert = SucuriScanOption::get_option(':verify_ssl_cert');
 
9407
 
9408
  // Check whether the domain name is valid or not.
9409
  if( !$api_key ){
@@ -9432,7 +9571,6 @@ function sucuriscan_settings_general(){
9432
  'VerifySSLCertOptions' => $verify_ssl_cert_options,
9433
  'RequestTimeout' => SucuriScanOption::get_option(':request_timeout') . ' seconds',
9434
  'DatastorePath' => SucuriScanOption::get_option(':datastore_path'),
9435
- 'DatastorePathShort' => '',
9436
  'CollectWrongPasswords' => 'No collect passwords',
9437
  'ModalWhenAPIRegistered' => $api_registered_modal,
9438
  );
@@ -9449,10 +9587,6 @@ function sucuriscan_settings_general(){
9449
  $template_variables['VerifySSLCert'] = $sucuriscan_verify_ssl_cert[$verify_ssl_cert];
9450
  }
9451
 
9452
- if ( !empty($template_variables['DatastorePath']) ) {
9453
- $template_variables['DatastorePathShort'] = SucuriScan::excerpt_rev( $template_variables['DatastorePath'], 30 );
9454
- }
9455
-
9456
  if ( sucuriscan_collect_wrong_passwords() === true ) {
9457
  $template_variables['CollectWrongPasswords'] = '<span class="sucuriscan-label-error">Yes, collect passwords</span>';
9458
  }
@@ -9480,6 +9614,8 @@ function sucuriscan_settings_scanner(){
9480
  $parse_errorlogs = SucuriScanOption::get_option(':parse_errorlogs');
9481
  $errorlogs_limit = SucuriScanOption::get_option(':errorlogs_limit');
9482
  $ignore_scanning = SucuriScanOption::get_option(':ignore_scanning');
 
 
9483
  $runtime_scan_human = SucuriScanFSScanner::get_filesystem_runtime(TRUE);
9484
 
9485
  // Generate the HTML code for the option list in the form select fields.
@@ -9517,6 +9653,11 @@ function sucuriscan_settings_scanner(){
9517
  'ParseErrorLogsSwitchText' => 'Disable',
9518
  'ParseErrorLogsSwitchValue' => 'disable',
9519
  'ParseErrorLogsSwitchCssClass' => 'button-danger',
 
 
 
 
 
9520
  /* Filsystem scanning frequency. */
9521
  'ScanningFrequency' => 'Undefined',
9522
  'ScanningFrequencyOptions' => $scan_freq_options,
@@ -9524,6 +9665,7 @@ function sucuriscan_settings_scanner(){
9524
  'ScanningInterfaceOptions' => $scan_interface_options,
9525
  /* Filesystem scanning runtime. */
9526
  'ScanningRuntimeHuman' => $runtime_scan_human,
 
9527
  'ErrorLogsLimit' => $errorlogs_limit,
9528
  );
9529
 
@@ -9569,6 +9711,13 @@ function sucuriscan_settings_scanner(){
9569
  $template_variables['ParseErrorLogsSwitchCssClass'] = 'button-success';
9570
  }
9571
 
 
 
 
 
 
 
 
9572
  if( array_key_exists($scan_freq, $sucuriscan_schedule_allowed) ){
9573
  $template_variables['ScanningFrequency'] = $sucuriscan_schedule_allowed[$scan_freq];
9574
  }
@@ -9582,13 +9731,42 @@ function sucuriscan_settings_scanner(){
9582
  * @return string Parsed HTML code for the notification settings panel.
9583
  */
9584
  function sucuriscan_settings_notifications(){
9585
- global $sucuriscan_notify_options;
 
9586
 
9587
  $template_variables = array(
9588
  'NotificationOptions' => '',
 
 
 
9589
  'PrettifyMailsWarningVisibility' => SucuriScanTemplate::visibility( SucuriScanMail::prettify_mails() ),
9590
  );
9591
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9592
  $counter = 0;
9593
 
9594
  foreach( $sucuriscan_notify_options as $alert_type => $alert_label ){
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.4
8
  Author URI: http://sucuri.net
9
  */
10
 
66
  /**
67
  * Current version of the plugin's code.
68
  */
69
+ define('SUCURISCAN_VERSION', '1.7.4');
70
 
71
  /**
72
  * The name of the Sucuri plugin main file.
187
  */
188
 
189
  $sucuriscan_notify_options = array(
190
+ 'sucuriscan_prettify_mails' => 'Enable email alerts in HTML <em>(uncheck to get email in plain text format)</em>',
191
  'sucuriscan_lastlogin_redirection' => 'Allow redirection after login to report the last-login information',
192
  'sucuriscan_notify_user_registration' => 'Enable email alerts for new user registration',
193
  'sucuriscan_notify_success_login' => 'Enable email alerts for successful logins',
248
  $sucuriscan_no_notices_in = array(
249
  );
250
 
251
+ $sucuriscan_email_subjects = array(
252
+ 'Sucuri Alert, :domain, :event',
253
+ 'Sucuri Alert, :domain, :event, :remoteaddr',
254
+ 'Sucuri Alert, :event, :remoteaddr',
255
+ 'Sucuri Alert, :event',
256
+ );
257
+
258
  /**
259
  * Remove the WordPress generator meta-tag from the source code.
260
  */
1393
  | FilesystemIterator::UNIX_PATHS;
1394
  $objects = new RecursiveIteratorIterator(
1395
  new RecursiveDirectoryIterator($filepath, $flags),
1396
+ RecursiveIteratorIterator::SELF_FIRST,
1397
+ RecursiveIteratorIterator::CATCH_GET_CHILD
1398
  );
1399
  } else {
1400
  $objects = new DirectoryIterator($filepath);
2170
  'sucuriscan_scan_modfiles' => 'enabled',
2171
  'sucuriscan_scan_checksums' => 'enabled',
2172
  'sucuriscan_scan_errorlogs' => 'enabled',
2173
+ 'sucuriscan_sitecheck_scanner' => 'enabled',
2174
+ 'sucuriscan_sitecheck_counter' => 0,
2175
  'sucuriscan_parse_errorlogs' => 'enabled',
2176
  'sucuriscan_errorlogs_limit' => 30,
2177
  'sucuriscan_ignore_scanning' => 'disabled',
2181
  'sucuriscan_emails_sent' => 0,
2182
  'sucuriscan_emails_per_hour' => 5,
2183
  'sucuriscan_last_email_at' => time(),
2184
+ 'sucuriscan_email_subject' => 'Sucuri Alert, :domain, :event',
2185
  'sucuriscan_prettify_mails' => 'disabled',
2186
  'sucuriscan_notify_success_login' => 'enabled',
2187
  'sucuriscan_notify_failed_login' => 'enabled',
2658
  * @param boolean $force_scan Whether the filesystem scan was forced by an administrator user or not.
2659
  * @return boolean Either TRUE or FALSE representing the success or fail of the operation respectively.
2660
  */
2661
+ private static function verify_run( $runtime=0, $force_scan=FALSE ){
2662
  $option_name = ':runtime';
2663
  $last_run = SucuriScanOption::get_option($option_name);
2664
  $current_time = time();
2691
  *
2692
  * @return boolean TRUE if the current WordPress version must be reported, FALSE otherwise.
2693
  */
2694
+ private static function report_site_version(){
2695
  $option_name = ':site_version';
2696
  $reported_version = SucuriScanOption::get_option($option_name);
2697
  $wp_version = self::site_version();
2871
  return TRUE;
2872
  }
2873
 
2874
+ if ( $trusted_ips ) {
2875
+ foreach ( $trusted_ips as $cache_key => $ip_info ) {
2876
+ $ip_parts = explode( '.', $ip_info->remote_addr );
2877
+ $ip_pattern = FALSE;
2878
 
2879
+ // Generate the regular expression for CIDR range 24.
2880
+ if ( $ip_info->cidr_range == 24 ) {
2881
+ $ip_pattern = sprintf( '/^%d\.%d\.%d\.[0-9]{1,3}$/', $ip_parts[0], $ip_parts[1], $ip_parts[2] );
2882
+ }
2883
 
2884
+ // Generate the regular expression for CIDR range 16.
2885
+ elseif ( $ip_info->cidr_range == 16 ) {
2886
+ $ip_pattern = sprintf( '/^%d\.%d(\.[0-9]{1,3}){2}$/', $ip_parts[0], $ip_parts[1] );
2887
+ }
2888
 
2889
+ // Generate the regular expression for CIDR range 8.
2890
+ elseif ( $ip_info->cidr_range == 8 ) {
2891
+ $ip_pattern = sprintf( '/^%d(\.[0-9]{1,3}){3}$/', $ip_parts[0] );
2892
+ }
2893
 
2894
+ if ( $ip_pattern && preg_match($ip_pattern, $remote_addr) ) {
2895
+ return TRUE;
2896
+ }
2897
  }
2898
  }
2899
 
4221
  */
4222
  public static function get_official_checksums( $version=0 ){
4223
  $url = 'http://api.wordpress.org/core/checksums/1.0/';
4224
+ $language = 'en_US'; /* WPLANG does not works. */
4225
  $response = self::api_call( $url, 'GET', array(
4226
  'version' => $version,
4227
  'locale' => $language,
4424
  * @return boolean Whether the emails will be in HTML or Plain/Text.
4425
  */
4426
  public static function prettify_mails(){
4427
+ return ( self::get_option(':prettify_mails') === 'enabled' );
 
4428
  }
4429
 
4430
  /**
4439
  public static function send_mail( $email='', $subject='', $message='', $data_set=array() ){
4440
  $headers = array();
4441
  $subject = ucwords(strtolower($subject));
 
4442
  $force = FALSE;
4443
  $debug = FALSE;
4444
 
4473
 
4474
  if( $debug ){ die($message); }
4475
 
4476
+ $subject = self::get_email_subject($subject);
4477
  $mail_sent = wp_mail( $email, $subject, $message, $headers );
4478
 
4479
  if( $mail_sent ){
4488
  return FALSE;
4489
  }
4490
 
4491
+ /**
4492
+ * Generate a subject for the email alerts.
4493
+ *
4494
+ * @param string $event The reason of the message that will be sent.
4495
+ * @return string A text with the subject for the email alert.
4496
+ */
4497
+ private static function get_email_subject( $event='' ){
4498
+ $domain_name = self::get_domain();
4499
+ $remote_addr = self::get_remote_addr();
4500
+ $email_subject = self::get_option(':email_subject');
4501
+
4502
+ if ( $email_subject ) {
4503
+ $email_subject = str_replace(
4504
+ array( ':domain', ':event', ':remoteaddr' ),
4505
+ array( $domain_name, $event, $remote_addr ),
4506
+ strip_tags($email_subject)
4507
+ );
4508
+
4509
+ return $email_subject;
4510
+ }
4511
+
4512
+ /**
4513
+ * Probably a bad value in the options table. Delete the entry from the database
4514
+ * and call this function to try again, it will probably fall in an infinite
4515
+ * loop, but this is the easiest way to control this procedure.
4516
+ */
4517
+ else {
4518
+ self::delete_option(':email_subject');
4519
+ return self::get_email_subject($event);
4520
+ }
4521
+ }
4522
+
4523
  /**
4524
  * Generate a HTML version of the message that will be sent through an email.
4525
  *
4698
  }
4699
 
4700
  foreach( $sub_pages as $sub_page_func => $sub_page_title ){
4701
+ if (
4702
+ $sub_page_func == 'sucuriscan_scanner'
4703
+ && self::is_sitecheck_disabled()
4704
+ ) {
4705
+ continue;
4706
+ }
4707
+
4708
  $func_parts = explode( '_', $sub_page_func, 2 );
4709
 
4710
  if( isset($func_parts[1]) ){
4940
  return $html_links;
4941
  }
4942
 
4943
+ /**
4944
+ * Check whether the SiteCheck scanner and the malware scan page are disabled.
4945
+ *
4946
+ * @return boolean TRUE if the SiteCheck scanner and malware scan page are disabled.
4947
+ */
4948
+ public static function is_sitecheck_disabled(){
4949
+ return (bool) ( SucuriScanOption::get_option(':sitecheck_scanner') === 'disabled' );
4950
+ }
4951
+
4952
+ /**
4953
+ * Check whether the SiteCheck scanner and the malware scan page are enabled.
4954
+ *
4955
+ * @return boolean TRUE if the SiteCheck scanner and malware scan page are enabled.
4956
+ */
4957
+ public static function is_sitecheck_enabled(){
4958
+ return (bool) ( SucuriScanOption::get_option(':sitecheck_scanner') !== 'disabled' );
4959
+ }
4960
+
4961
  }
4962
 
4963
  /**
5426
  $sub_pages = is_array($sucuriscan_pages) ? $sucuriscan_pages : array();
5427
 
5428
  foreach( $sub_pages as $sub_page_func => $sub_page_title ){
5429
+ if (
5430
+ $sub_page_func == 'sucuriscan_scanner'
5431
+ && SucuriScanTemplate::is_sitecheck_disabled()
5432
+ ) {
5433
+ continue;
5434
+ }
5435
+
5436
  $page_func = $sub_page_func . '_page';
5437
 
5438
  add_submenu_page(
5523
  * @return void
5524
  */
5525
  public static function check_permissions(){
 
 
5526
  if(
5527
  !function_exists('current_user_can')
5528
  || !current_user_can('manage_options')
5665
  if( preg_match('/^ERROR:(.*)/', $res, $error_m) ){
5666
  SucuriScanInterface::error( 'The site <code>' . $clean_domain . '</code> was not scanned: ' . $error_m[1] );
5667
  } else {
5668
+ SucuriScanInterface::error( 'SiteCheck error: ' . $res );
5669
  }
5670
  }
5671
 
5680
  }
5681
  }
5682
 
5683
+ // Count the number of scans.
5684
+ if ( $display_results === true ) {
5685
+ $sitecheck_counter = (int) SucuriScanOption::get_option(':sitecheck_counter');
5686
+ SucuriScanOption::update_option( ':sitecheck_counter', $sitecheck_counter + 1 );
5687
+ }
5688
+
5689
  ob_start();
5690
  ?>
5691
 
5927
  <?php endforeach; ?>
5928
  <?php endif; ?>
5929
 
5930
+ <?php if ( !isset($res['WEBAPP']) && !isset($res['SYSTEM']['NOTICE']) ): ?>
5931
+ <tr>
5932
+ <td colspan="2"><em>No more information was found.</em></td>
5933
+ </tr>
5934
+ <?php endif; ?>
5935
+
5936
  <!-- Possible recommendations or outdated software on the site. -->
5937
  <?php if( $outdated_warns_exist || $recommendations_exist ): ?>
5938
  <tr>
5981
  <div id="sucuriscan-website-links">
5982
  <table class="wp-list-table widefat sucuriscan-table sucuriscan-scanner-links">
5983
  <tbody>
5984
+ <?php if ( isset($res['LINKS']) ): ?>
5985
 
5986
+ <?php foreach( $possible_url_keys as $result_url_key=>$result_url_title ): ?>
 
 
 
 
 
 
 
 
 
5987
 
5988
+ <?php if( isset($res['LINKS'][$result_url_key]) ): ?>
5989
  <tr>
5990
+ <th colspan="2">
5991
+ <?php printf(
5992
+ '%s (%d found)',
5993
+ __($result_url_title),
5994
+ count($res['LINKS'][$result_url_key])
5995
+ ) ?>
5996
+ </th>
5997
  </tr>
 
 
5998
 
5999
+ <?php foreach( $res['LINKS'][$result_url_key] as $url_path ): ?>
6000
+ <tr>
6001
+ <td colspan="2">
6002
+ <span class="sucuriscan-monospace sucuriscan-wraptext"><?php _e($url_path) ?></span>
6003
+ </td>
6004
+ </tr>
6005
+ <?php endforeach; ?>
6006
+ <?php endif; ?>
6007
+
6008
+ <?php endforeach; ?>
6009
+
6010
+ <?php else: ?>
6011
+
6012
+ <tr>
6013
+ <td><em>No iFrames, links, or script files were found.</em></td>
6014
+ </tr>
6015
+
6016
+ <?php endif; ?>
6017
  </tbody>
6018
  </table>
6019
  </div>
7315
  if( SucuriScanInterface::check_nonce() ){
7316
 
7317
  // Force the execution of the filesystem scanner.
7318
+ if( SucuriScanRequest::post(':force_scan') !== false ){
7319
  SucuriScanEvent::notify_event( 'plugin_change', 'Filesystem scan forced at: ' . date('r') );
7320
  SucuriScanEvent::filesystem_scan(TRUE);
7321
  }
7410
  $logs_limit = $page_number * $max_per_page;
7411
  $audit_logs = SucuriScanAPI::get_logs($logs_limit);
7412
 
 
 
7413
  $template_variables = array(
7414
  'PageTitle' => 'Audit Logs',
7415
  'AuditLogs.List' => '',
7452
  $snippet_data['AuditLog.Extra'] .= '<li>' . SucuriScan::escape($log_extra) . '</li>';
7453
  }
7454
  $snippet_data['AuditLog.Extra'] .= '</ul>';
 
7455
  }
7456
 
7457
  $template_variables['AuditLogs.List'] .= SucuriScanTemplate::get_snippet('integrity-auditlogs', $snippet_data);
7462
  $template_variables['AuditLogs.Count'] = $counter_i;
7463
  $template_variables['AuditLogs.NoItemsVisibility'] = 'hidden';
7464
 
7465
+ if( $total_items > 1 ){
7466
  $max_pages = ceil( $audit_logs->total_entries / $max_per_page );
7467
 
7468
  if( $max_pages > SUCURISCAN_MAX_PAGINATION_BUTTONS ){
7469
  $max_pages = SUCURISCAN_MAX_PAGINATION_BUTTONS;
7470
  }
7471
 
7472
+ if ( $max_pages > 1 ) {
7473
+ $template_variables['AuditLogs.PaginationVisibility'] = 'visible';
7474
+ $template_variables['AuditLogs.PaginationLinks'] = SucuriScanTemplate::get_pagination(
7475
+ '%%SUCURI.URL.Home%%',
7476
+ $max_per_page * $max_pages,
7477
+ $max_per_page
7478
+ );
7479
+ }
7480
  }
7481
  }
7482
 
9083
  $sucuriscan_notify_options,
9084
  $sucuriscan_emails_per_hour,
9085
  $sucuriscan_maximum_failed_logins,
9086
+ $sucuriscan_email_subjects,
9087
  $sucuriscan_verify_ssl_cert;
9088
 
9089
  // Use this conditional to avoid double checking.
9173
  }
9174
  }
9175
 
9176
+ // Enable or disable the SiteCheck scanner and the malware scan page.
9177
+ if( $sitecheck_scanner = SucuriScanRequest::post(':sitecheck_scanner', '(en|dis)able') ){
9178
+ $action_d = $sitecheck_scanner . 'd';
9179
+ SucuriScanOption::update_option(':sitecheck_scanner', $action_d);
9180
+ SucuriScanEvent::notify_event( 'plugin_change', 'SiteCheck scanner and malware scan page were: ' . $action_d );
9181
+ SucuriScanInterface::info( 'SiteCheck scanner and malware scan page were <code>' . $action_d . '</code>' );
9182
+ }
9183
+
9184
  // Modify the schedule of the filesystem scanner.
9185
  if( $frequency = SucuriScanRequest::post(':scan_frequency') ){
9186
  if( array_key_exists($frequency, $sucuriscan_schedule_allowed) ){
9326
  }
9327
  }
9328
 
9329
+ // Update the subject format for the email alerts.
9330
+ if ( $email_subject = SucuriScanRequest::post(':email_subject') ) {
9331
+ $new_email_subject = false;
9332
+
9333
+ // Validate the custom subject format.
9334
+ if ( $email_subject == 'custom' ) {
9335
+ $format_pattern = '/^[0-9a-zA-Z:,\s]+$/';
9336
+ $custom_email_subject = SucuriScanRequest::post(':custom_email_subject');
9337
+
9338
+ if (
9339
+ $custom_email_subject !== false
9340
+ && !empty($custom_email_subject)
9341
+ && preg_match( $format_pattern, $custom_email_subject )
9342
+ ) {
9343
+ $new_email_subject = trim($custom_email_subject);
9344
+ } else {
9345
+ SucuriScanInterface::error( 'Invalid characters found in the email alert subject format.' );
9346
+ }
9347
+ }
9348
+
9349
+ // Check if the email subject format is allowed.
9350
+ elseif (
9351
+ is_array($sucuriscan_email_subjects)
9352
+ && in_array( $email_subject, $sucuriscan_email_subjects )
9353
+ ) {
9354
+ $new_email_subject = $email_subject;
9355
+ }
9356
+
9357
+ // Proceed with the operation saving the new subject.
9358
+ if ( $new_email_subject !== false ) {
9359
+ SucuriScanOption::update_option( ':email_subject', $new_email_subject );
9360
+ SucuriScanInterface::info( 'New email alert subject format saved successfully.' );
9361
+ }
9362
+ }
9363
+
9364
  // Reset all the plugin's options.
9365
  if( SucuriScanRequest::post(':reset_options') !== FALSE ){
9366
  // Notify the event before the API key is removed.
9542
  $emails_per_hour = SucuriScanOption::get_option(':emails_per_hour');
9543
  $maximum_failed_logins = SucuriScanOption::get_option(':maximum_failed_logins');
9544
  $verify_ssl_cert = SucuriScanOption::get_option(':verify_ssl_cert');
9545
+ $invalid_domain = false;
9546
 
9547
  // Check whether the domain name is valid or not.
9548
  if( !$api_key ){
9571
  'VerifySSLCertOptions' => $verify_ssl_cert_options,
9572
  'RequestTimeout' => SucuriScanOption::get_option(':request_timeout') . ' seconds',
9573
  'DatastorePath' => SucuriScanOption::get_option(':datastore_path'),
 
9574
  'CollectWrongPasswords' => 'No collect passwords',
9575
  'ModalWhenAPIRegistered' => $api_registered_modal,
9576
  );
9587
  $template_variables['VerifySSLCert'] = $sucuriscan_verify_ssl_cert[$verify_ssl_cert];
9588
  }
9589
 
 
 
 
 
9590
  if ( sucuriscan_collect_wrong_passwords() === true ) {
9591
  $template_variables['CollectWrongPasswords'] = '<span class="sucuriscan-label-error">Yes, collect passwords</span>';
9592
  }
9614
  $parse_errorlogs = SucuriScanOption::get_option(':parse_errorlogs');
9615
  $errorlogs_limit = SucuriScanOption::get_option(':errorlogs_limit');
9616
  $ignore_scanning = SucuriScanOption::get_option(':ignore_scanning');
9617
+ $sitecheck_scanner = SucuriScanOption::get_option(':sitecheck_scanner');
9618
+ $sitecheck_counter = SucuriScanOption::get_option(':sitecheck_counter');
9619
  $runtime_scan_human = SucuriScanFSScanner::get_filesystem_runtime(TRUE);
9620
 
9621
  // Generate the HTML code for the option list in the form select fields.
9653
  'ParseErrorLogsSwitchText' => 'Disable',
9654
  'ParseErrorLogsSwitchValue' => 'disable',
9655
  'ParseErrorLogsSwitchCssClass' => 'button-danger',
9656
+ /* SiteCheck scanner. */
9657
+ 'SiteCheckScannerStatus' => 'Enabled',
9658
+ 'SiteCheckScannerSwitchText' => 'Disable',
9659
+ 'SiteCheckScannerSwitchValue' => 'disable',
9660
+ 'SiteCheckScannerSwitchCssClass' => 'button-danger',
9661
  /* Filsystem scanning frequency. */
9662
  'ScanningFrequency' => 'Undefined',
9663
  'ScanningFrequencyOptions' => $scan_freq_options,
9665
  'ScanningInterfaceOptions' => $scan_interface_options,
9666
  /* Filesystem scanning runtime. */
9667
  'ScanningRuntimeHuman' => $runtime_scan_human,
9668
+ 'SiteCheckCounter' => $sitecheck_counter,
9669
  'ErrorLogsLimit' => $errorlogs_limit,
9670
  );
9671
 
9711
  $template_variables['ParseErrorLogsSwitchCssClass'] = 'button-success';
9712
  }
9713
 
9714
+ if( $sitecheck_scanner == 'disabled' ){
9715
+ $template_variables['SiteCheckScannerStatus'] = 'Disabled';
9716
+ $template_variables['SiteCheckScannerSwitchText'] = 'Enable';
9717
+ $template_variables['SiteCheckScannerSwitchValue'] = 'enable';
9718
+ $template_variables['SiteCheckScannerSwitchCssClass'] = 'button-success';
9719
+ }
9720
+
9721
  if( array_key_exists($scan_freq, $sucuriscan_schedule_allowed) ){
9722
  $template_variables['ScanningFrequency'] = $sucuriscan_schedule_allowed[$scan_freq];
9723
  }
9731
  * @return string Parsed HTML code for the notification settings panel.
9732
  */
9733
  function sucuriscan_settings_notifications(){
9734
+ global $sucuriscan_notify_options,
9735
+ $sucuriscan_email_subjects;
9736
 
9737
  $template_variables = array(
9738
  'NotificationOptions' => '',
9739
+ 'EmailSubjectOptions' => '',
9740
+ 'EmailSubjectCustom.Checked' => '',
9741
+ 'EmailSubjectCustom.Value' => '',
9742
  'PrettifyMailsWarningVisibility' => SucuriScanTemplate::visibility( SucuriScanMail::prettify_mails() ),
9743
  );
9744
 
9745
+ if ( $sucuriscan_email_subjects ) {
9746
+ $email_subject = SucuriScanOption::get_option(':email_subject');
9747
+ $is_official_subject = false;
9748
+
9749
+ foreach ( $sucuriscan_email_subjects as $subject_format ) {
9750
+ if ( $email_subject == $subject_format ) {
9751
+ $is_official_subject = true;
9752
+ $checked = 'checked="checked"';
9753
+ } else {
9754
+ $checked = '';
9755
+ }
9756
+
9757
+ $template_variables['EmailSubjectOptions'] .= SucuriScanTemplate::get_snippet('settings-emailsubject', array(
9758
+ 'EmailSubject.Name' => $subject_format,
9759
+ 'EmailSubject.Value' => $subject_format,
9760
+ 'EmailSubject.Checked' => $checked,
9761
+ ));
9762
+ }
9763
+
9764
+ if ( $is_official_subject === false ) {
9765
+ $template_variables['EmailSubjectCustom.Checked'] = 'checked="checked"';
9766
+ $template_variables['EmailSubjectCustom.Value'] = SucuriScan::escape($email_subject);
9767
+ }
9768
+ }
9769
+
9770
  $counter = 0;
9771
 
9772
  foreach( $sucuriscan_notify_options as $alert_type => $alert_label ){