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

Version Description

  • Added Hardening option to remove error log files
  • Bug fixes on some new registrations.
  • Changed format of the internal logs to json.
Download this release

Release Info

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

Code changes from version 1.6.9 to 1.7.0

inc/tpl/notification-pretty.html.tpl CHANGED
@@ -1,15 +1,10 @@
1
- <!DOCTYPE html>
2
- <html>
3
- <head>
4
- <title>%%SUCURI.TemplateTitle%%</title>
5
- </head>
6
- <body>
7
  <table class="sucuriscan-template" style="width:90%;background:#fff;font-family:Arial,Helvetica,sans-serif;border-spacing:0">
8
  <thead sytle="border-bottom:1px solid #ccc">
9
  <tr style="background-color:#4b4b4b;background-image:-moz-linear-gradient(top, #555555, #3b3b3b);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#555555), to(#3b3b3b));background-image:-webkit-linear-gradient(top, #555555, #3b3b3b);background-image:-o-linear-gradient(top, #555555, #3b3b3b);background-image:linear-gradient(to bottom, #555555, #3b3b3b);background-repeat:repeat-x">
10
  <td sytle="font-size:20px;font-weight:normal;color:#ffffff;padding:10px;border-right:1px solid #2f2f2f;border-left:1px solid #6f6f6f;-webkit-box-shadow:inset 0 1px 0 #888888;-moz-box-shadow:inset 0 1px 0 #888888;box-shadow:inset 0 1px 0 #888888;text-shadow:1px 1px 2px rgba(0, 0, 0, 0.5)">
11
  <a href="http://sucuri.net/" style="text-decoration:none;display:inline-block;margin:8px 0 5px 20px">
12
- <img src="http://sucuri.net/wp-content/themes/sucuri-two/images/main-logo.png" style="border:none" />
13
  </a>
14
  <span style="display:inline-block;line-height:46px;margin:0 20px 0 0;float:right;color:#ffffff">%%SUCURI.TemplateTitle%%</span>
15
  </td>
@@ -34,5 +29,3 @@
34
  </tr>
35
  </tbody>
36
  </table>
37
- </body>
38
- </html>
1
+
 
 
 
 
 
2
  <table class="sucuriscan-template" style="width:90%;background:#fff;font-family:Arial,Helvetica,sans-serif;border-spacing:0">
3
  <thead sytle="border-bottom:1px solid #ccc">
4
  <tr style="background-color:#4b4b4b;background-image:-moz-linear-gradient(top, #555555, #3b3b3b);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#555555), to(#3b3b3b));background-image:-webkit-linear-gradient(top, #555555, #3b3b3b);background-image:-o-linear-gradient(top, #555555, #3b3b3b);background-image:linear-gradient(to bottom, #555555, #3b3b3b);background-repeat:repeat-x">
5
  <td sytle="font-size:20px;font-weight:normal;color:#ffffff;padding:10px;border-right:1px solid #2f2f2f;border-left:1px solid #6f6f6f;-webkit-box-shadow:inset 0 1px 0 #888888;-moz-box-shadow:inset 0 1px 0 #888888;box-shadow:inset 0 1px 0 #888888;text-shadow:1px 1px 2px rgba(0, 0, 0, 0.5)">
6
  <a href="http://sucuri.net/" style="text-decoration:none;display:inline-block;margin:8px 0 5px 20px">
7
+ <img src="http://sucuri.net/wp-content/themes/sucuri-two/images/main-logo.png" alt="Sucuri, Inc." style="border:none" />
8
  </a>
9
  <span style="display:inline-block;line-height:46px;margin:0 20px 0 0;float:right;color:#ffffff">%%SUCURI.TemplateTitle%%</span>
10
  </td>
29
  </tr>
30
  </tbody>
31
  </table>
 
 
inc/tpl/settings-general.html.tpl CHANGED
@@ -38,11 +38,11 @@
38
  </tr>
39
 
40
  <tr class="alternate">
41
- <td>API Key</td>
42
  <td>
43
  <span class="sucuriscan-monospace">%%SUCURI.APIKey%%</span>
44
  </td>
45
- <td class="td-with-button">
46
  <form action="%%SUCURI.URL.Settings%%" method="post" class="sucuriscan-%%SUCURI.APIKey.RecoverVisibility%%">
47
  <input type="hidden" name="sucuriscan_page_nonce" value="%%SUCURI.PageNonce%%" />
48
  <button type="submit" name="sucuriscan_recover_key" class="button-primary">Recover</button>
@@ -63,7 +63,7 @@
63
 
64
  <tr>
65
  <td>Notify events to</td>
66
- <td><a href="mailto:%%SUCURI.NotifyTo%%">%%SUCURI.NotifyTo%%</a></td>
67
  <td class="td-with-button">
68
  <form action="%%SUCURI.URL.Settings%%" method="post">
69
  <input type="hidden" name="sucuriscan_page_nonce" value="%%SUCURI.PageNonce%%" />
@@ -164,6 +164,18 @@
164
  </tr>
165
 
166
  <tr>
 
 
 
 
 
 
 
 
 
 
 
 
167
  <td>Last Scanning</td>
168
  <td><span class="sucuriscan-monospace">%%SUCURI.ScanningRuntimeHuman%%</span></td>
169
  <td class="td-with-button">
@@ -174,7 +186,7 @@
174
  </td>
175
  </tr>
176
 
177
- <tr class="alternate">
178
  <td>Scanning frequency</td>
179
  <td>%%SUCURI.ScanningFrequency%%</td>
180
  <td class="td-with-button">
@@ -188,7 +200,7 @@
188
  </td>
189
  </tr>
190
 
191
- <tr class="sucuriscan-%%SUCURI.ScanningInterfaceVisibility%%">
192
  <td>Scanning interface</td>
193
  <td>%%SUCURI.ScanningInterface%%</td>
194
  <td class="td-with-button">
38
  </tr>
39
 
40
  <tr class="alternate">
41
+ <td width="200">API Key</td>
42
  <td>
43
  <span class="sucuriscan-monospace">%%SUCURI.APIKey%%</span>
44
  </td>
45
+ <td width="350" class="td-with-button">
46
  <form action="%%SUCURI.URL.Settings%%" method="post" class="sucuriscan-%%SUCURI.APIKey.RecoverVisibility%%">
47
  <input type="hidden" name="sucuriscan_page_nonce" value="%%SUCURI.PageNonce%%" />
48
  <button type="submit" name="sucuriscan_recover_key" class="button-primary">Recover</button>
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">
69
  <input type="hidden" name="sucuriscan_page_nonce" value="%%SUCURI.PageNonce%%" />
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">
186
  </td>
187
  </tr>
188
 
189
+ <tr>
190
  <td>Scanning frequency</td>
191
  <td>%%SUCURI.ScanningFrequency%%</td>
192
  <td class="td-with-button">
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">
inc/tpl/settings-notifications.html.tpl CHANGED
@@ -1,10 +1,37 @@
1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2
  <form action="%%SUCURI.URL.Settings%%#settings-notifications" method="post">
3
  <table class="wp-list-table widefat sucuriscan-table sucuriscan-settings-notifications">
4
  <thead>
5
  <tr>
6
  <th colspan="3" class="thead-with-button">
7
- <span>Email Alerts Settings</span>
8
  <div class="thead-topright-action">
9
  <input type="hidden" name="sucuriscan_page_nonce" value="%%SUCURI.PageNonce%%" />
10
  <button type="submit" name="sucuriscan_save_notification_settings" class="button-primary">Save</button>
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>
8
+ Check the boxes bellow to receive alerts via email of the events explained in
9
+ the table, by the default the notifications will be sent to the address
10
+ configured during the installation of your site, you can change this in the
11
+ <em>General Settings</em> panel. You can specify multiple recipients separating
12
+ each address with a comma.
13
+ </p>
14
+
15
+ <div class="sucuriscan-inline-alert-warning sucuriscan-%%SUCURI.PrettifyMailsWarningVisibility%%">
16
+ <p>
17
+ Some emails sent by this plugin will be rejected outright by some popular email
18
+ services. To fix this you will need to use a third-party email service, or use a
19
+ plugin to force the site to use SMTP <em>(Simple Mail Transfer Protocol)</em>
20
+ for sending emails, and then configure your SMTP server to properly handle
21
+ messages. You can also <strong>disable HTML alerts</strong> to get notifications
22
+ in <em>text/plain</em> format.
23
+ </p>
24
+ </div>
25
+ </div>
26
+ </div>
27
+ </div>
28
+
29
  <form action="%%SUCURI.URL.Settings%%#settings-notifications" method="post">
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>
readme.txt CHANGED
@@ -1,71 +1,233 @@
1
  === Sucuri Security - Auditing, Malware Scanner and Hardening ===
2
  Contributors: dd@sucuri.net
3
  Donate Link: http://sitecheck.sucuri.net
4
- Tags: malware, security, firewall, scan, spam, virus, sucuri, protection
5
  Requires at least:3.2
6
- Stable tag:1.6.9
7
  Tested up to: 4.0
8
 
9
- The Sucuri WordPress Security plugin provides the website owner the best Activity Auditing, SiteCheck Remote Malware Scanning, Effective Security Hardening and Post-Hack features.
 
10
 
11
  == Description ==
12
 
13
- The Sucuri Security - Auditing, SiteCheck Malware Scanner and Hardening is a security plugin enables you to scan your WordPress site using Sucuri SiteCheck for security and malware issues, and also verifies the security integrity of your core files right in your dashboard. It includes audit trails and post-hack security ions to help you reset passwords and secret keys in case it has been already hacked, or infected with malware.
14
 
15
- You can also run the checks for malware, blacklisting, and overall security status by scanning for free at <a href="http://sitecheck.sucuri.net">SiteCheck.Sucuri.net</a>.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
 
17
- Sucuri SiteCheck detects various types of malware, SPAM injections, website errors, disabled sites, database connection issues and code anomalies that require special attention to include:
18
 
19
- * Obfuscated JavaScript injections
20
- * Cross Site Scripting (XSS)
21
- * Website Defacements
22
- * Hidden & Malicious iFrames
23
- * PHP Mailers
24
- * Phishing Attempts
25
- * Malicious Redirects
26
- * Anomalies
27
- * Drive-by-Downloads
28
- * IP Cloaking
29
- * Social Engineering Attacks
30
 
 
 
 
31
 
32
- There are a number of blacklisting authorities that monitor for malware, SPAM, and phishing attempts. Sucuri SiteCheck leverages the APIs for these authorities to check your website blacklisting status:
33
 
34
- * Sucuri
35
- * Google Safe Browsing
36
- * Norton
37
- * AVG
38
- * Phish Tank (Phishing Specifically)
39
- * ESET
40
- * McAfee SiteAdvisor
41
- * Yandex
42
 
43
- We augment the SiteCheck Malware Scanner with various. 1-click hardening options. Some of these options do not provide a high level of security, but collectively these options do lower your risk floor:
 
 
 
 
 
44
 
45
- * Verify WordPress Version
46
- * Protect Uploads Directory
47
- * Restrict wp-content Access
48
- * Restrict wp-includes Access
49
- * Verify PHP Version
50
- * Disable the theme and plugin editors
51
 
52
- On the newest versions of the plugin we also added an option to verify all WordPress core files for changes,
53
- which can be useful to detect hidden backdoors.
54
 
55
- Note that if your site is compromised and you need urgent help, you can leverage the
56
- Sucuri plans here: http://sucuri.net (even if our free options are not finding
57
- the compromise on your site).
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
58
 
59
 
60
  == Installation ==
61
 
62
- 1. Download the plugin.
63
- 1. Go to the WordPress Plugin menu and activate it.
64
- 1. That's it!
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
65
 
66
 
67
  == Changelog ==
68
 
 
 
 
 
 
69
  = 1.6.9 =
70
  * Multiple bug fixes (as reported on the support forums).
71
  * Added heartbeat for the file scans.
@@ -129,7 +291,8 @@ the compromise on your site).
129
  = 1.5.4 = Bug fixes.
130
 
131
  = 1.5.2 =
132
- * Adding additional information about .htaccess hacks and the server environment.
 
133
 
134
  = 1.5.0 =
135
  * Fixing last login and giving better warns on permission errors.
@@ -151,7 +314,8 @@ the compromise on your site).
151
  * Fixing some issues on the last login and allowing the option to disable it.
152
 
153
  = 1.4.4 =
154
- * Small bug fixes + forcing a re-scan on every scan attempt (not using the cache anymore).
 
155
 
156
  = 1.4.3 =
157
  * Fixing a few PHP warnings.
@@ -210,6 +374,7 @@ the compromise on your site).
210
  = 1.1.1 =
211
  * First public release.
212
 
 
213
  == Credits ==
214
 
215
  * <a href="http://sucuri.net">Sucuri Security</a>
1
  === Sucuri Security - Auditing, Malware Scanner and Hardening ===
2
  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.0
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.
10
+
11
 
12
  == Description ==
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
20
+ offers it’s users four key security features for their website, each designed
21
+ to have a positive affect on their security posture:
22
+
23
+ <ol>
24
+ <li>Security Activity Auditing</li>
25
+ <li>File Integrity Monitoring</li>
26
+ <li>Remote Malware Scanning</li>
27
+ <li>Blacklist Monitoring</li>
28
+ <li>Effective Security Hardening</li>
29
+ <li>Post-Hack Security Actions</li>
30
+ <li>Security Notifications</li>
31
+ <li>Website Firewall (add on)</li>
32
+ </ol>
33
+
34
+
35
+ = Security Activity Monitoring =
36
+
37
+ 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
+ This feature is logging all activity to the Sucuri cloud, for safe keeping.
48
+ This ensures that an attacker is not able to wipe your forensic data and
49
+ prevent further security analysis after a compromise. If an attacker is able
50
+ to bypass your security controls, your security logs will be kept safe within
51
+ the Sucuri Security Operations Center (SOC).
52
+
53
+ This feature is particularly important to website / system administrators and
54
+ security experts looking to understand what is going on with their website and
55
+ when it’s happening.
56
+
57
+
58
+ = Security File Integrity Monitoring =
59
+
60
+ Security File Integrity Monitoring has been fundamental to the world of
61
+ security. It’s the act of comparing a known good with the current state. If
62
+ the current state differs from the known good, you know you have a problem.
63
+ This is the basis of a lot of host Intrusion detection systems. It’s what we
64
+ have built into the plugin.
65
+
66
+ It will create a <strong>known good</strong> the minute the plugin is
67
+ installed. This will be of all the directories at the root of the install,
68
+ this includes plugins, themes and core files.
69
+
70
+
71
+ = Remote Security Malware Scanning =
72
+
73
+ This feature is powered by our very powerful scanning engine, found on our
74
+ free security scanner - <a href="http://sitecheck.sucuri.net">SiteCheck. It’s
75
+ important to take some time to <a
76
+ href="http://blog.sucuri.net/2012/10/ask-sucuri-how-does-sitecheck-work.html">understand
77
+ how this scanner works</a>.
78
+
79
+ There are limitations with the way this scanner works, you can find more info
80
+ on that in the FAQ section.
81
+
82
+
83
+ = Security Blacklist Monitoring =
84
+
85
+ Another very interesting feature of the Security Malware Scanner is that it
86
+ incorporates various blacklist engines. Security blacklist engines include the
87
+ following:
88
+
89
+ <ol>
90
+ <li>Sucuri Labs</li>
91
+ <li>Google Safe Browsing</li>
92
+ <li>Norton</li>
93
+ <li>AVG</li>
94
+ <li>Phish Tank</li>
95
+ <li>ESET</li>
96
+ <li>McAfee Site Advisor</li>
97
+ <li>Yandex</li>
98
+ <li>SpamHaus</li>
99
+ <li>Bitdefender</li>
100
+ </ol>
101
+
102
+ These are some of the largest blacklisting entities, each having the ability
103
+ to directly impact your brands online reputation. By synchronize with their
104
+ environments we’re able to tell you, upon scan, whether any of them are
105
+ negatively flagging your website with a security related issue.
106
+
107
+ If they do, then via our Website AntiVirus product, we’re able to help you get
108
+ off the their security blacklist.
109
+
110
+
111
+ = Effective Security Hardening =
112
+
113
+ It’s easy to get lost in the world of security hardening. At Sucuri we clean
114
+ 100’s of websites a day, many with the various security hardening
115
+ configurations you find in various WordPress Security presentations. In this
116
+ section, we add those that we feel to be most effective, and that complement
117
+ the entire Sucuri suite of products.
118
 
 
119
 
120
+ = Post-Hack Security Actions =
 
 
 
 
 
 
 
 
 
 
121
 
122
+ Regardless of how good your security posture is, sometimes it’s impossible to
123
+ prevent the inevitable. When this happens, we’ve included a section to help
124
+ you walk through the three key things you should do after a compromise.
125
 
 
126
 
127
+ = Security Notifications =
 
 
 
 
 
 
 
128
 
129
+ Having all these security features would be useless unless you were notified
130
+ of the issues. This is why we have made available security notifications. We
131
+ have also expanded the various security related events, to provide website
132
+ owners more flexibility in regards to what they want to know about. As a
133
+ website owner, you have the option to make these security alerts as quiet or
134
+ noisy as you would like.
135
 
 
 
 
 
 
 
136
 
137
+ = Website Firewall (add on) =
 
138
 
139
+ This is by far the coolest security feature Sucuri has to offer everyday
140
+ website owners. It’s an enterprise grade Website Firewall known as CloudProxy.
141
+ It is designed to give you the best security protection any website can hope
142
+ for. It protects your website from a variety of website attacks and security
143
+ events to include:
144
+
145
+ <ol>
146
+ <li>Denial of Service (DOS / DDOS) Attacks</li>
147
+ <li>Exploitation of Software Vulnerabilities</li>
148
+ <li>Zero Day Disclosure Patches</li>
149
+ <li>Brute Force Attacks against your Access Control Mechanisms</li>
150
+ </ol>
151
+
152
+ This is coupled with a number of features like:
153
+
154
+ <ol>
155
+ <li>Performance Optimization</li>
156
+ <li>Advanced Access Control Features</li>
157
+ <li>Failover and Redundancy</li>
158
+ </ol>
159
+
160
+ This is not included as a <strong>Free</strong> option to the plugin, but is
161
+ integrated so that if purchased you are able to activate.
162
+
163
+ The Sucuri Security WordPress Security plugin is built by the team that is
164
+ known for their proactive approach to security. It is built using intelligence
165
+ gathered from thousands upon thousands of remediation cases, millions of
166
+ unique domain scans and 10’s of millions of website security attack blocks.
167
 
168
 
169
  == Installation ==
170
 
171
+ The installation of the Sucuri Security WordPress Security plugin is very
172
+ simple and straight forward. <a
173
+ href="https://sucuri.net/wordpress-security-plugin-installation">A detailed
174
+ breakdown of the process is available, including images,</a> below however we
175
+ outline the bare minimum steps.
176
+
177
+ To install Sucuri Security and complement your Security posture:
178
+
179
+
180
+ 1. You will want to log into your WordPress administration panel - (e.g.,
181
+ http://yourdomain/wp-admin)
182
+
183
+ 2. Navigate to <strong>Plugins Menu</strong> option in your WordPress
184
+ administration panel
185
+
186
+ 3. Select <strong>Add New</strong>
187
+
188
+ 4. Type <strong>Sucuri</strong> in the <strong>Search</strong> box, and click
189
+ <strong>Search</strong> plugins.
190
+
191
+ 5. The first option you get should be for <strong>Sucuri Security - Auditing,
192
+ Malware Scanner and Hardening</strong>
193
+
194
+ 6. Select <strong>Install Now</strong>
195
+
196
+ 7. Now choose to <strong>Activate</strong> the plugin.
197
+
198
+ 8. Once activated, you will need to create an API key, this is done
199
+ automatically for you. Simply click on <strong>Generate API Key for
200
+ XXXXXX</strong>
201
+
202
+ 9. Once the API key is generated the page will redirect you to your dashboard
203
+ and the plugin is automatically configured for you.
204
+
205
+
206
+ To configure the Sucuri WordPress Security plugin for your specific Security
207
+ needs:
208
+
209
+ 1. Navigate to the <strong>Sucuri Security</strong> menu option (left hand
210
+ side).
211
+
212
+ 2. Hover or click on the name.
213
+
214
+ 3. Click on <strong>Settings</strong>
215
+
216
+ The <strong>Settings</strong> page allows you to configure the website to your
217
+ preferred security needs. Some of it’s features include changing the email
218
+ notifications, via the <strong>notification settings</strong> tab or disabling
219
+ 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.
229
+ * Changed format of the internal logs to json.
230
+
231
  = 1.6.9 =
232
  * Multiple bug fixes (as reported on the support forums).
233
  * Added heartbeat for the file scans.
291
  = 1.5.4 = Bug fixes.
292
 
293
  = 1.5.2 =
294
+ * Adding additional information about .htaccess hacks and the server
295
+ * environment.
296
 
297
  = 1.5.0 =
298
  * Fixing last login and giving better warns on permission errors.
314
  * Fixing some issues on the last login and allowing the option to disable it.
315
 
316
  = 1.4.4 =
317
+ * Small bug fixes + forcing a re-scan on every scan attempt (not using the
318
+ * cache anymore).
319
 
320
  = 1.4.3 =
321
  * Fixing a few PHP warnings.
374
  = 1.1.1 =
375
  * First public release.
376
 
377
+
378
  == Credits ==
379
 
380
  * <a href="http://sucuri.net">Sucuri Security</a>
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.6.9
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.6.9');
70
 
71
  /**
72
  * The name of the Sucuri plugin main file.
@@ -182,6 +182,8 @@ if( defined('SUCURISCAN') ){
182
  */
183
 
184
  $sucuriscan_notify_options = array(
 
 
185
  'sucuriscan_notify_user_registration' => 'Enable email alerts for new user registration',
186
  'sucuriscan_notify_success_login' => 'Enable email alerts for successful logins',
187
  'sucuriscan_notify_failed_login' => 'Enable email alerts for failed logins',
@@ -200,8 +202,6 @@ if( defined('SUCURISCAN') ){
200
  'sucuriscan_notify_plugin_updated' => 'Enable email alerts when a plugin is updated',
201
  'sucuriscan_notify_plugin_installed' => 'Enable email alerts when a plugin is installed',
202
  'sucuriscan_notify_plugin_deleted' => 'Enable email alerts when a plugin is deleted',
203
- 'sucuriscan_prettify_mails' => 'Enable email alerts in HTML (uncheck to get email in text/plain)',
204
- 'sucuriscan_lastlogin_redirection' => 'Allow redirection after login to report the last-login information',
205
  );
206
 
207
  $sucuriscan_schedule_allowed = array(
@@ -371,6 +371,31 @@ class SucuriScan {
371
  return $var_name;
372
  }
373
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
374
  /**
375
  * Encodes the less-than, greater-than, ampersand, double quote and single quote
376
  * characters, will never double encode entities.
@@ -537,8 +562,9 @@ class SucuriScan {
537
  *
538
  * @return string The real ip address of the user in the current request.
539
  */
540
- public static function get_remote_addr(){
541
  $remote_addr = '';
 
542
 
543
  if( self::is_behind_cloudproxy() ){
544
  $alternatives = array(
@@ -548,8 +574,9 @@ class SucuriScan {
548
  'HTTP_X_FORWARDED',
549
  'HTTP_FORWARDED_FOR',
550
  'HTTP_FORWARDED',
551
- 'REMOTE_ADDR',
552
  'SUCURI_RIP',
 
553
  );
554
 
555
  foreach( $alternatives as $alternative ){
@@ -558,6 +585,7 @@ class SucuriScan {
558
  && self::is_valid_ip($_SERVER[$alternative])
559
  ){
560
  $remote_addr = $_SERVER[$alternative];
 
561
  break;
562
  }
563
  }
@@ -565,15 +593,29 @@ class SucuriScan {
565
 
566
  elseif( isset($_SERVER['REMOTE_ADDR']) ) {
567
  $remote_addr = $_SERVER['REMOTE_ADDR'];
 
568
  }
569
 
570
  if( $remote_addr == '::1' ){
571
  $remote_addr = '127.0.0.1';
572
  }
573
 
 
 
 
 
574
  return $remote_addr;
575
  }
576
 
 
 
 
 
 
 
 
 
 
577
  /**
578
  * Retrieve the user-agent from the current request.
579
  *
@@ -617,9 +659,9 @@ class SucuriScan {
617
  */
618
  public static function is_behind_cloudproxy( $verbose=FALSE ){
619
  $http_host = self::get_domain();
620
- $host_by_name = @gethostbyname($http_host);
621
- $host_by_addr = @gethostbyaddr($host_by_name);
622
- $status = (bool) preg_match('/^cloudproxy[0-9]+\.sucuri\.net$/', $host_by_addr);
623
 
624
  if( $verbose ){
625
  return array(
@@ -672,6 +714,17 @@ class SucuriScan {
672
  return NULL;
673
  }
674
 
 
 
 
 
 
 
 
 
 
 
 
675
  /**
676
  * Return the time passed since the specified timestamp until now.
677
  *
@@ -683,7 +736,8 @@ class SucuriScan {
683
  $timestamp = strtotime($timestamp);
684
  }
685
 
686
- $diff = abs( time() - intval($timestamp) );
 
687
 
688
  if( $diff == 0 ){ return 'just now'; }
689
 
@@ -724,6 +778,16 @@ class SucuriScan {
724
  return $var_name;
725
  }
726
 
 
 
 
 
 
 
 
 
 
 
727
  /**
728
  * Check whether an IP address has a valid format or not.
729
  *
@@ -773,6 +837,43 @@ class SucuriScan {
773
  }
774
  }
775
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
776
  /**
777
  * Cut a long text to the length specified, and append suspensive points at the end.
778
  *
@@ -856,7 +957,11 @@ class SucuriScanRequest extends SucuriScan {
856
  public static function request( $list=array(), $key='', $pattern='' ){
857
  $key = self::variable_prefix($key);
858
 
859
- if( is_array($list) && isset($list[$key]) ){
 
 
 
 
860
  // Select the key from the list and escape its content.
861
  $key_value = $list[$key];
862
 
@@ -868,7 +973,7 @@ class SucuriScanRequest extends SucuriScan {
868
  case '_nonce': $pattern = '/^[a-z0-9]{10}$/'; break;
869
  case '_page': $pattern = '/^[a-z_]+$/'; break;
870
  case '_array': $pattern = '_array'; break;
871
- case '_yyyymmdd': $pattern = '/^[0-9]{4}\-[0-9]{2}\-[0-9]{2}$/'; break;
872
  default: $pattern = '/^'.$pattern.'$/'; break;
873
  }
874
  }
@@ -1056,6 +1161,36 @@ class SucuriScanFileInfo extends SucuriScan {
1056
  return FALSE;
1057
  }
1058
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1059
  /**
1060
  * Check whether the built-in class SplFileObject is available in the system
1061
  * or not, it is required to have PHP >= 5.1.0. The SplFileObject class offers
@@ -1196,7 +1331,7 @@ class SucuriScanFileInfo extends SucuriScan {
1196
  }
1197
 
1198
  /**
1199
- * Skip some specific directories and filepaths from the filesystem scan.
1200
  *
1201
  * @param string $directory Directory where the scanner is located at the moment.
1202
  * @param string $filename Name of the folder or file being scanned at the moment.
@@ -1803,13 +1938,14 @@ class SucuriScanOption extends SucuriScanRequest {
1803
  'sucuriscan_scan_interface' => 'spl',
1804
  'sucuriscan_scan_modfiles' => 'enabled',
1805
  'sucuriscan_scan_checksums' => 'enabled',
 
1806
  'sucuriscan_runtime' => 0,
1807
  'sucuriscan_lastlogin_redirection' => 'enabled',
1808
  'sucuriscan_notify_to' => '',
1809
  'sucuriscan_emails_sent' => 0,
1810
  'sucuriscan_emails_per_hour' => 5,
1811
  'sucuriscan_last_email_at' => time(),
1812
- 'sucuriscan_prettify_mails' => 'enabled',
1813
  'sucuriscan_notify_success_login' => 'enabled',
1814
  'sucuriscan_notify_failed_login' => 'enabled',
1815
  'sucuriscan_notify_post_publication' => 'enabled',
@@ -2117,7 +2253,23 @@ class SucuriScanOption extends SucuriScanRequest {
2117
  */
2118
  public static function get_ignored_events(){
2119
  $post_types = self::get_option(':ignored_events');
2120
- $post_types_arr = @unserialize($post_types);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2121
 
2122
  if( !is_array($post_types_arr) ){
2123
  $post_types_arr = array();
@@ -2143,7 +2295,7 @@ class SucuriScanOption extends SucuriScanRequest {
2143
  // Check if the event is not ignored already.
2144
  if( !array_key_exists($event_name, $ignored_events) ){
2145
  $ignored_events[$event_name] = time();
2146
- $saved = self::update_option( ':ignored_events', serialize($ignored_events) );
2147
 
2148
  return $saved;
2149
  }
@@ -2164,7 +2316,7 @@ class SucuriScanOption extends SucuriScanRequest {
2164
 
2165
  if( array_key_exists($event_name, $ignored_events) ){
2166
  unset( $ignored_events[$event_name] );
2167
- $saved = self::update_option( ':ignored_events', serialize($ignored_events) );
2168
 
2169
  return $saved;
2170
  }
@@ -3060,9 +3212,11 @@ class SucuriScanHook extends SucuriScanEvent {
3060
  elseif(
3061
  current_user_can('update_themes')
3062
  && SucuriScanRequest::get('action', '(upgrade-theme|do-theme-upgrade)')
3063
- && SucuriScanRequest::post('checked')
3064
  ){
3065
- foreach( (array) $_POST['checked'] as $theme ){
 
 
3066
  $theme_info = wp_get_theme($theme);
3067
  $theme_name = ucwords($theme);
3068
  $theme_version = '0.0';
@@ -3304,9 +3458,10 @@ class SucuriScanAPI extends SucuriScanOption {
3304
  $response['body'] = @json_decode($response['body_raw']);
3305
  }
3306
 
3307
- // Check if the response data is serialized, then unserialize it.
3308
- elseif( preg_match('/^(a|O):[0-9]+:.+/', $response['body']) ){
3309
- $response['body'] = @unserialize($response['body']);
 
3310
  }
3311
 
3312
  return $response;
@@ -3738,12 +3893,12 @@ class SucuriScanAPI extends SucuriScanOption {
3738
  */
3739
  public static function get_sitecheck_results( $domain='' ){
3740
  if( !empty($domain) ){
3741
- $url = 'http://sitecheck.sucuri.net/scanner/';
3742
  $response = self::api_call( $url, 'GET', array(
3743
- 'serialized' => 1,
3744
- 'clear' => 1,
3745
- 'fromwp' => 2,
3746
  'scan' => $domain,
 
 
 
3747
  ));
3748
 
3749
  if( $response ){
@@ -3989,7 +4144,8 @@ class SucuriScanMail extends SucuriScanOption {
3989
  * @return boolean Whether the emails will be in HTML or Plain/Text.
3990
  */
3991
  public static function prettify_mails(){
3992
- return ( self::get_option(':prettify_mails') === 'enabled' );
 
3993
  }
3994
 
3995
  /**
@@ -4028,7 +4184,7 @@ class SucuriScanMail extends SucuriScanOption {
4028
 
4029
  // Check whether the email notifications will be sent in HTML or Plain/Text.
4030
  if( self::prettify_mails() ){
4031
- $headers = array( 'Content-type: text/html' );
4032
  $data_set['PrettifyType'] = 'pretty';
4033
  } else {
4034
  $message = strip_tags($message);
@@ -4040,15 +4196,9 @@ class SucuriScanMail extends SucuriScanOption {
4040
  if( $debug ){ die($message); }
4041
 
4042
  $subject = sprintf( 'Sucuri Alert, %s, %s', $wp_domain, $subject );
 
4043
 
4044
- $email_sent = wp_mail(
4045
- $email,
4046
- $subject,
4047
- $message,
4048
- $headers
4049
- );
4050
-
4051
- if( $email_sent ){
4052
  $emails_sent_num = (int) self::get_option(':emails_sent');
4053
  self::update_option( ':emails_sent', $emails_sent_num + 1 );
4054
  self::update_option( ':last_email_at', time() );
@@ -4071,7 +4221,6 @@ class SucuriScanMail extends SucuriScanOption {
4071
  private static function prettify_mail( $subject='', $message='', $data_set=array() ){
4072
  $prettify_type = isset($data_set['PrettifyType']) ? $data_set['PrettifyType'] : 'simple';
4073
  $template_name = 'notification-' . $prettify_type;
4074
- $remote_addr = self::get_remote_addr();
4075
  $user = wp_get_current_user();
4076
  $display_name = '';
4077
 
@@ -4087,10 +4236,10 @@ class SucuriScanMail extends SucuriScanOption {
4087
  'TemplateTitle' => 'Sucuri Alert',
4088
  'Subject' => $subject,
4089
  'Website' => self::get_option('siteurl'),
4090
- 'RemoteAddress' => $remote_addr,
4091
  'Message' => $message,
4092
  'User' => $display_name,
4093
- 'Time' => date('d/M/Y H:i:s'),
4094
  );
4095
 
4096
  foreach( $data_set as $var_key => $var_value ){
@@ -4936,8 +5085,12 @@ function sucuriscan_sitecheck_info( $res=array() ){
4936
  $res = SucuriScanAPI::get_sitecheck_results($clean_domain);
4937
 
4938
  // Check for error messages in the request's response.
4939
- if( is_string($res) && preg_match('/^ERROR:(.*)/', $res, $error_m) ){
4940
- SucuriScanInterface::error( 'The site <code>' . $clean_domain . '</code> was not scanned: ' . $error_m[1] );
 
 
 
 
4941
  }
4942
 
4943
  else {
@@ -5181,14 +5334,16 @@ function sucuriscan_sitecheck_info( $res=array() ){
5181
  <?php endforeach; ?>
5182
  <?php endif; ?>
5183
 
5184
- <?php foreach( $res['SYSTEM']['NOTICE'] as $j=>$notice ): ?>
5185
- <?php if( is_array($notice) ){ $notice = implode(', ', $notice); } ?>
5186
- <tr>
5187
- <td colspan="2">
5188
- <span class="sucuriscan-monospace"><?php _e($notice) ?></span>
5189
- </td>
5190
- </tr>
5191
- <?php endforeach; ?>
 
 
5192
 
5193
  <!-- Possible recommendations or outdated software on the site. -->
5194
  <?php if( $outdated_warns_exist || $recommendations_exist ): ?>
@@ -5844,6 +5999,7 @@ function sucuriscan_hardening_page(){
5844
  sucuriscan_harden_adminuser();
5845
  sucuriscan_harden_fileeditor();
5846
  sucuriscan_harden_dbtables();
 
5847
  ?>
5848
  </form>
5849
  </div>
@@ -6226,11 +6382,7 @@ function sucuriscan_cloudproxy_enabled(){
6226
 
6227
  $description = 'A WAF is a protection layer for your web site, blocking all sort of attacks (brute force attempts, '
6228
  . 'DDoS, SQL injections, etc) and helping it remain malware and blacklist free. This test checks if your site is '
6229
- . 'using <a href="http://cloudproxy.sucuri.net/" target="_blank">Sucuri\'s CloudProxy WAF</a> to protect your site. '
6230
- . '</p><p>'
6231
- . '<b>HTTP Host:</b> <span class="sucuriscan-monospace">' . $proxy_info['http_host'] . '</span><br>'
6232
- . '<b>Host Name:</b> <span class="sucuriscan-monospace">' . $proxy_info['host_name'] . '</span><br>'
6233
- . '<b>Host Address:</b> <span class="sucuriscan-monospace">' . $proxy_info['host_addr'] . '</span>';
6234
 
6235
  if( $proxy_info['status'] === FALSE ){
6236
  $status = 0;
@@ -6461,6 +6613,76 @@ function sucuriscan_harden_dbtables(){
6461
  );
6462
  }
6463
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6464
  /**
6465
  * WordPress core integrity page.
6466
  *
@@ -7508,7 +7730,7 @@ if( !function_exists('sucuri_set_lastlogin') ){
7508
  'user_lastlogin' => current_time('mysql')
7509
  );
7510
 
7511
- @file_put_contents($datastore_filepath, serialize($login_info)."\n", FILE_APPEND);
7512
  }
7513
  }
7514
  add_action('wp_login', 'sucuriscan_set_lastlogin', 50);
@@ -7563,8 +7785,14 @@ function sucuriscan_get_logins( $limit=10, $offset=0, $user_id=0 ){
7563
  for( $i=$offset; $i<$total_lines; $i++ ){
7564
  $line = $reversed_lines[$i] ? trim($reversed_lines[$i]) : '';
7565
 
7566
- if( preg_match('/^a:[0-9]+:.+/', $line) ){
7567
- $last_login = @unserialize($line);
 
 
 
 
 
 
7568
  $last_login['user_lastlogin_timestamp'] = strtotime($last_login['user_lastlogin']);
7569
  $last_login['user_registered_timestamp'] = 0;
7570
 
@@ -8205,6 +8433,14 @@ function sucuriscan_settings_form_submissions( $page_nonce=NULL ){
8205
  SucuriScanInterface::info( 'Filesystem scanner for file integrity was <code>' . $action_d . '</code>' );
8206
  }
8207
 
 
 
 
 
 
 
 
 
8208
  // Modify the schedule of the filesystem scanner.
8209
  if( $frequency = SucuriScanRequest::post(':scan_frequency') ){
8210
  $allowed_frequency = array_keys($sucuriscan_schedule_allowed);
@@ -8247,8 +8483,10 @@ function sucuriscan_settings_form_submissions( $page_nonce=NULL ){
8247
 
8248
  // Update the email where the event notifications will be sent.
8249
  if( $new_email = SucuriScanRequest::post(':notify_to') ){
8250
- if( SucuriScan::is_valid_email($new_email) ){
8251
- SucuriScanOption::update_option( ':notify_to', $new_email );
 
 
8252
  SucuriScanEvent::notify_event( 'plugin_change', 'Email address to get the event notifications was changed' );
8253
  SucuriScanInterface::info( 'All the event notifications will be sent to the email specified.' );
8254
  } else {
@@ -8439,6 +8677,7 @@ function sucuriscan_settings_general(){
8439
  $scan_interface = SucuriScanOption::get_option(':scan_interface');
8440
  $scan_modfiles = SucuriScanOption::get_option(':scan_modfiles');
8441
  $scan_checksums = SucuriScanOption::get_option(':scan_checksums');
 
8442
  $emails_per_hour = SucuriScanOption::get_option(':emails_per_hour');
8443
  $maximum_failed_logins = SucuriScanOption::get_option(':maximum_failed_logins');
8444
  $verify_ssl_cert = SucuriScanOption::get_option(':verify_ssl_cert');
@@ -8479,6 +8718,11 @@ function sucuriscan_settings_general(){
8479
  'ScanChecksumsSwitchText' => 'Disable',
8480
  'ScanChecksumsSwitchValue' => 'disable',
8481
  'ScanChecksumsSwitchCssClass' => 'button-danger',
 
 
 
 
 
8482
  /* Filsystem scanning frequency. */
8483
  'ScanningFrequency' => 'Undefined',
8484
  'ScanningFrequencyOptions' => $scan_freq_options,
@@ -8520,6 +8764,13 @@ function sucuriscan_settings_general(){
8520
  $template_variables['ScanChecksumsSwitchCssClass'] = 'button-success';
8521
  }
8522
 
 
 
 
 
 
 
 
8523
  if( array_key_exists($scan_freq, $sucuriscan_schedule_allowed) ){
8524
  $template_variables['ScanningFrequency'] = $sucuriscan_schedule_allowed[$scan_freq];
8525
  }
@@ -8549,6 +8800,7 @@ function sucuriscan_settings_notifications(){
8549
 
8550
  $template_variables = array(
8551
  'NotificationOptions' => '',
 
8552
  );
8553
 
8554
  $counter = 0;
@@ -9018,7 +9270,12 @@ function sucuriscan_server_info(){
9018
  'Plugin_version' => SUCURISCAN_VERSION,
9019
  'Plugin_checksum' => SUCURISCAN_PLUGIN_CHECKSUM,
9020
  'Last_filesystem_scan' => SucuriScanOption::get_filesystem_runtime(TRUE),
9021
- 'Using_CloudProxy' => 'No',
 
 
 
 
 
9022
  'Operating_system' => sprintf('%s (%d Bit)', PHP_OS, PHP_INT_SIZE*8),
9023
  'Server' => 'Unknown',
9024
  'Developer_mode' => 'OFF',
@@ -9028,9 +9285,11 @@ function sucuriscan_server_info(){
9028
  'PHP_version' => PHP_VERSION,
9029
  );
9030
 
9031
- if( SucuriScan::is_behind_cloudproxy() ){
9032
- $info_vars['Using_CloudProxy'] = 'Yes';
9033
- }
 
 
9034
 
9035
  if( defined('WP_DEBUG') && WP_DEBUG ){
9036
  $info_vars['Developer_mode'] = 'ON';
@@ -9064,7 +9323,7 @@ function sucuriscan_server_info(){
9064
  );
9065
 
9066
  foreach( $field_names as $php_flag ){
9067
- $php_flag_value = ini_get($php_flag);
9068
  $php_flag_name = 'PHP_' . $php_flag;
9069
  $info_vars[$php_flag_name] = $php_flag_value ? $php_flag_value : 'N/A';
9070
  }
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.0
8
  Author URI: http://sucuri.net
9
  */
10
 
66
  /**
67
  * Current version of the plugin's code.
68
  */
69
+ define('SUCURISCAN_VERSION', '1.7.0');
70
 
71
  /**
72
  * The name of the Sucuri plugin main file.
182
  */
183
 
184
  $sucuriscan_notify_options = array(
185
+ // 'sucuriscan_prettify_mails' => 'Enable email alerts in HTML (uncheck to get email in text/plain)', // TODO: Investigate HTML mails issues.
186
+ 'sucuriscan_lastlogin_redirection' => 'Allow redirection after login to report the last-login information',
187
  'sucuriscan_notify_user_registration' => 'Enable email alerts for new user registration',
188
  'sucuriscan_notify_success_login' => 'Enable email alerts for successful logins',
189
  'sucuriscan_notify_failed_login' => 'Enable email alerts for failed logins',
202
  'sucuriscan_notify_plugin_updated' => 'Enable email alerts when a plugin is updated',
203
  'sucuriscan_notify_plugin_installed' => 'Enable email alerts when a plugin is installed',
204
  'sucuriscan_notify_plugin_deleted' => 'Enable email alerts when a plugin is deleted',
 
 
205
  );
206
 
207
  $sucuriscan_schedule_allowed = array(
371
  return $var_name;
372
  }
373
 
374
+ /**
375
+ * Gets the value of a configuration option.
376
+ *
377
+ * @param string $property The configuration option name.
378
+ * @return string Value of the configuration option as a string on success.
379
+ */
380
+ public static function ini_get( $property='' ){
381
+ $ini_value = ini_get($property);
382
+
383
+ if( empty($ini_value) || is_null($ini_value) ){
384
+ switch( $property ){
385
+ case 'error_log': $ini_value = 'error_log'; break;
386
+ case 'safe_mode': $ini_value = 'Off'; break;
387
+ case 'allow_url_fopen': $ini_value = '1'; break;
388
+ case 'memory_limit': $ini_value = '128M'; break;
389
+ case 'upload_max_filesize': $ini_value = '2M'; break;
390
+ case 'post_max_size': $ini_value = '8M'; break;
391
+ case 'max_execution_time': $ini_value = '30'; break;
392
+ case 'max_input_time': $ini_value = '-1'; break;
393
+ }
394
+ }
395
+
396
+ return $ini_value;
397
+ }
398
+
399
  /**
400
  * Encodes the less-than, greater-than, ampersand, double quote and single quote
401
  * characters, will never double encode entities.
562
  *
563
  * @return string The real ip address of the user in the current request.
564
  */
565
+ public static function get_remote_addr( $return_header=FALSE ){
566
  $remote_addr = '';
567
+ $header_used = 'unknown';
568
 
569
  if( self::is_behind_cloudproxy() ){
570
  $alternatives = array(
574
  'HTTP_X_FORWARDED',
575
  'HTTP_FORWARDED_FOR',
576
  'HTTP_FORWARDED',
577
+ 'HTTP_X_SUCURI_CLIENTIP',
578
  'SUCURI_RIP',
579
+ 'REMOTE_ADDR',
580
  );
581
 
582
  foreach( $alternatives as $alternative ){
585
  && self::is_valid_ip($_SERVER[$alternative])
586
  ){
587
  $remote_addr = $_SERVER[$alternative];
588
+ $header_used = $alternative;
589
  break;
590
  }
591
  }
593
 
594
  elseif( isset($_SERVER['REMOTE_ADDR']) ) {
595
  $remote_addr = $_SERVER['REMOTE_ADDR'];
596
+ $header_used = 'REMOTE_ADDR';
597
  }
598
 
599
  if( $remote_addr == '::1' ){
600
  $remote_addr = '127.0.0.1';
601
  }
602
 
603
+ if( $return_header ){
604
+ return $header_used;
605
+ }
606
+
607
  return $remote_addr;
608
  }
609
 
610
+ /**
611
+ * Return the HTTP header used to retrieve the remote address.
612
+ *
613
+ * @return string The HTTP header used to retrieve the remote address.
614
+ */
615
+ public static function get_remote_addr_header(){
616
+ return self::get_remote_addr(TRUE);
617
+ }
618
+
619
  /**
620
  * Retrieve the user-agent from the current request.
621
  *
659
  */
660
  public static function is_behind_cloudproxy( $verbose=FALSE ){
661
  $http_host = self::get_domain();
662
+ $host_by_addr = @gethostbyname($http_host);
663
+ $host_by_name = @gethostbyaddr($host_by_addr);
664
+ $status = (bool) preg_match('/^cloudproxy[0-9]+\.sucuri\.net$/', $host_by_name);
665
 
666
  if( $verbose ){
667
  return array(
714
  return NULL;
715
  }
716
 
717
+ /**
718
+ * Retrieve the date in localized format based on the current time.
719
+ *
720
+ * @return string The date, translated if locale specifies it.
721
+ */
722
+ public static function current_datetime(){
723
+ $local_time = current_time('timestamp');
724
+
725
+ return self::datetime($local_time);
726
+ }
727
+
728
  /**
729
  * Return the time passed since the specified timestamp until now.
730
  *
736
  $timestamp = strtotime($timestamp);
737
  }
738
 
739
+ $local_time = current_time('timestamp');
740
+ $diff = abs( $local_time - intval($timestamp) );
741
 
742
  if( $diff == 0 ){ return 'just now'; }
743
 
778
  return $var_name;
779
  }
780
 
781
+ /**
782
+ * Check whether a variable contains a serialized data or not.
783
+ *
784
+ * @param string $data The data that will be checked.
785
+ * @return boolean TRUE if the data was serialized, FALSE otherwise.
786
+ */
787
+ public static function is_serialized( $data='' ){
788
+ return ( is_string($data) && preg_match('/^(a|O):[0-9]+:.+/', $data) );
789
+ }
790
+
791
  /**
792
  * Check whether an IP address has a valid format or not.
793
  *
837
  }
838
  }
839
 
840
+ /**
841
+ * Return a string with all the valid email addresses.
842
+ *
843
+ * @param string $email The string that will be validated as an email address.
844
+ * @param boolean $as_array TRUE to return the list of valid email addresses as an array.
845
+ * @return string All the valid email addresses separated by a comma.
846
+ */
847
+ public static function get_valid_email( $email='', $as_array=FALSE ){
848
+ $valid_emails = array();
849
+
850
+ if( strpos($email, ',') !== FALSE ){
851
+ $addresses = explode(',', $email);
852
+
853
+ foreach( $addresses as $address ){
854
+ $address = trim($address);
855
+
856
+ if( self::is_valid_email($address) ){
857
+ $valid_emails[] = $address;
858
+ }
859
+ }
860
+ }
861
+
862
+ elseif( self::is_valid_email($email) ){
863
+ $valid_emails[] = $email;
864
+ }
865
+
866
+ if( !empty($valid_emails) ){
867
+ if( $as_array === TRUE ){
868
+ return $valid_emails;
869
+ }
870
+
871
+ return self::implode(', ', $valid_emails);
872
+ }
873
+
874
+ return FALSE;
875
+ }
876
+
877
  /**
878
  * Cut a long text to the length specified, and append suspensive points at the end.
879
  *
957
  public static function request( $list=array(), $key='', $pattern='' ){
958
  $key = self::variable_prefix($key);
959
 
960
+ if(
961
+ is_array($list)
962
+ && is_string($key)
963
+ && isset($list[$key])
964
+ ){
965
  // Select the key from the list and escape its content.
966
  $key_value = $list[$key];
967
 
973
  case '_nonce': $pattern = '/^[a-z0-9]{10}$/'; break;
974
  case '_page': $pattern = '/^[a-z_]+$/'; break;
975
  case '_array': $pattern = '_array'; break;
976
+ case '_yyyymmdd': $pattern = '/^[0-9]{4}(\-[0-9]{2}){2}$/'; break;
977
  default: $pattern = '/^'.$pattern.'$/'; break;
978
  }
979
  }
1161
  return FALSE;
1162
  }
1163
 
1164
+ /**
1165
+ * Find a file under the directory tree specified.
1166
+ *
1167
+ * @param string $filename Name of the folder or file being scanned at the moment.
1168
+ * @param string $directory Directory where the scanner is located at the moment.
1169
+ * @return array List of file paths where the file was found.
1170
+ */
1171
+ public function find_file( $filename='', $directory=NULL ){
1172
+ $file_paths = array();
1173
+
1174
+ if(
1175
+ is_null($directory)
1176
+ && defined('ABSPATH')
1177
+ ){
1178
+ $directory = ABSPATH;
1179
+ }
1180
+
1181
+ if( is_dir($directory) ){
1182
+ $dir_tree = $this->get_directory_tree( $directory );
1183
+
1184
+ foreach( $dir_tree as $filepath ){
1185
+ if( stripos($filepath, $filename) !== FALSE ){
1186
+ $file_paths[] = $filepath;
1187
+ }
1188
+ }
1189
+ }
1190
+
1191
+ return $file_paths;
1192
+ }
1193
+
1194
  /**
1195
  * Check whether the built-in class SplFileObject is available in the system
1196
  * or not, it is required to have PHP >= 5.1.0. The SplFileObject class offers
1331
  }
1332
 
1333
  /**
1334
+ * Skip some specific directories and file paths from the filesystem scan.
1335
  *
1336
  * @param string $directory Directory where the scanner is located at the moment.
1337
  * @param string $filename Name of the folder or file being scanned at the moment.
1938
  'sucuriscan_scan_interface' => 'spl',
1939
  'sucuriscan_scan_modfiles' => 'enabled',
1940
  'sucuriscan_scan_checksums' => 'enabled',
1941
+ 'sucuriscan_scan_errorlogs' => 'enabled',
1942
  'sucuriscan_runtime' => 0,
1943
  'sucuriscan_lastlogin_redirection' => 'enabled',
1944
  'sucuriscan_notify_to' => '',
1945
  'sucuriscan_emails_sent' => 0,
1946
  'sucuriscan_emails_per_hour' => 5,
1947
  'sucuriscan_last_email_at' => time(),
1948
+ 'sucuriscan_prettify_mails' => 'disabled',
1949
  'sucuriscan_notify_success_login' => 'enabled',
1950
  'sucuriscan_notify_failed_login' => 'enabled',
1951
  'sucuriscan_notify_post_publication' => 'enabled',
2253
  */
2254
  public static function get_ignored_events(){
2255
  $post_types = self::get_option(':ignored_events');
2256
+ $post_types_arr = FALSE;
2257
+
2258
+ // Encode (old) serialized data into JSON.
2259
+ if( self::is_serialized($post_types) ){
2260
+ var_dump($post_types);
2261
+ $post_types_arr = @unserialize($post_types);
2262
+ $post_types_fix = json_encode($post_types_arr);
2263
+ echo 'fixed';
2264
+ self::update_option( ':ignored_events', $post_types_fix );
2265
+
2266
+ return $post_types_arr;
2267
+ }
2268
+
2269
+ // Decode JSON-encoded data as an array.
2270
+ elseif( preg_match('/^\{.+\}$/', $post_types) ){
2271
+ $post_types_arr = @json_decode( $post_types, TRUE );
2272
+ }
2273
 
2274
  if( !is_array($post_types_arr) ){
2275
  $post_types_arr = array();
2295
  // Check if the event is not ignored already.
2296
  if( !array_key_exists($event_name, $ignored_events) ){
2297
  $ignored_events[$event_name] = time();
2298
+ $saved = self::update_option( ':ignored_events', json_encode($ignored_events) );
2299
 
2300
  return $saved;
2301
  }
2316
 
2317
  if( array_key_exists($event_name, $ignored_events) ){
2318
  unset( $ignored_events[$event_name] );
2319
+ $saved = self::update_option( ':ignored_events', json_encode($ignored_events) );
2320
 
2321
  return $saved;
2322
  }
3212
  elseif(
3213
  current_user_can('update_themes')
3214
  && SucuriScanRequest::get('action', '(upgrade-theme|do-theme-upgrade)')
3215
+ && SucuriScanRequest::post('checked', '_array')
3216
  ){
3217
+ $themes = SucuriScanRequest::post('checked', '_array');
3218
+
3219
+ foreach( $themes as $theme ){
3220
  $theme_info = wp_get_theme($theme);
3221
  $theme_name = ucwords($theme);
3222
  $theme_version = '0.0';
3458
  $response['body'] = @json_decode($response['body_raw']);
3459
  }
3460
 
3461
+ // Check if the response data is serialized (which we will consider as insecure).
3462
+ elseif( self::is_serialized($response['body']) ){
3463
+ $response['body_raw'] = NULL;
3464
+ $response['body'] = 'ERROR:Serialized data is not supported.';
3465
  }
3466
 
3467
  return $response;
3893
  */
3894
  public static function get_sitecheck_results( $domain='' ){
3895
  if( !empty($domain) ){
3896
+ $url = 'http://sitecheck.sucuri.net/';
3897
  $response = self::api_call( $url, 'GET', array(
 
 
 
3898
  'scan' => $domain,
3899
+ 'fromwp' => 2,
3900
+ 'clear' => 1,
3901
+ 'json' => 1,
3902
  ));
3903
 
3904
  if( $response ){
4144
  * @return boolean Whether the emails will be in HTML or Plain/Text.
4145
  */
4146
  public static function prettify_mails(){
4147
+ // return ( self::get_option(':prettify_mails') === 'enabled' ); // TODO: Investigate HTML mails issues.
4148
+ return FALSE;
4149
  }
4150
 
4151
  /**
4184
 
4185
  // Check whether the email notifications will be sent in HTML or Plain/Text.
4186
  if( self::prettify_mails() ){
4187
+ $headers = array( 'content-type: text/html' );
4188
  $data_set['PrettifyType'] = 'pretty';
4189
  } else {
4190
  $message = strip_tags($message);
4196
  if( $debug ){ die($message); }
4197
 
4198
  $subject = sprintf( 'Sucuri Alert, %s, %s', $wp_domain, $subject );
4199
+ $mail_sent = wp_mail( $email, $subject, $message, $headers );
4200
 
4201
+ if( $mail_sent ){
 
 
 
 
 
 
 
4202
  $emails_sent_num = (int) self::get_option(':emails_sent');
4203
  self::update_option( ':emails_sent', $emails_sent_num + 1 );
4204
  self::update_option( ':last_email_at', time() );
4221
  private static function prettify_mail( $subject='', $message='', $data_set=array() ){
4222
  $prettify_type = isset($data_set['PrettifyType']) ? $data_set['PrettifyType'] : 'simple';
4223
  $template_name = 'notification-' . $prettify_type;
 
4224
  $user = wp_get_current_user();
4225
  $display_name = '';
4226
 
4236
  'TemplateTitle' => 'Sucuri Alert',
4237
  'Subject' => $subject,
4238
  'Website' => self::get_option('siteurl'),
4239
+ 'RemoteAddress' => self::get_remote_addr(),
4240
  'Message' => $message,
4241
  'User' => $display_name,
4242
+ 'Time' => SucuriScan::current_datetime(),
4243
  );
4244
 
4245
  foreach( $data_set as $var_key => $var_value ){
5085
  $res = SucuriScanAPI::get_sitecheck_results($clean_domain);
5086
 
5087
  // Check for error messages in the request's response.
5088
+ if( is_string($res) ){
5089
+ if( preg_match('/^ERROR:(.*)/', $res, $error_m) ){
5090
+ SucuriScanInterface::error( 'The site <code>' . $clean_domain . '</code> was not scanned: ' . $error_m[1] );
5091
+ } else {
5092
+ SucuriScanInterface::error( 'The API returned data that can not be processed.' );
5093
+ }
5094
  }
5095
 
5096
  else {
5334
  <?php endforeach; ?>
5335
  <?php endif; ?>
5336
 
5337
+ <?php if( isset($res['SYSTEM']['NOTICE']) ): ?>
5338
+ <?php foreach( $res['SYSTEM']['NOTICE'] as $j=>$notice ): ?>
5339
+ <?php if( is_array($notice) ){ $notice = implode(', ', $notice); } ?>
5340
+ <tr>
5341
+ <td colspan="2">
5342
+ <span class="sucuriscan-monospace"><?php _e($notice) ?></span>
5343
+ </td>
5344
+ </tr>
5345
+ <?php endforeach; ?>
5346
+ <?php endif; ?>
5347
 
5348
  <!-- Possible recommendations or outdated software on the site. -->
5349
  <?php if( $outdated_warns_exist || $recommendations_exist ): ?>
5999
  sucuriscan_harden_adminuser();
6000
  sucuriscan_harden_fileeditor();
6001
  sucuriscan_harden_dbtables();
6002
+ sucuriscan_harden_errorlog();
6003
  ?>
6004
  </form>
6005
  </div>
6382
 
6383
  $description = 'A WAF is a protection layer for your web site, blocking all sort of attacks (brute force attempts, '
6384
  . 'DDoS, SQL injections, etc) and helping it remain malware and blacklist free. This test checks if your site is '
6385
+ . 'using <a href="http://cloudproxy.sucuri.net/" target="_blank">Sucuri\'s CloudProxy WAF</a> to protect your site.';
 
 
 
 
6386
 
6387
  if( $proxy_info['status'] === FALSE ){
6388
  $status = 0;
6613
  );
6614
  }
6615
 
6616
+ /**
6617
+ * Check whether an error_log file exists in the project.
6618
+ *
6619
+ * @return void
6620
+ */
6621
+ function sucuriscan_harden_errorlog(){
6622
+ $hardened = 1;
6623
+ $log_filename = SucuriScan::ini_get('error_log');
6624
+ $scan_errorlogs = SucuriScanOption::get_option(':scan_errorlogs');
6625
+
6626
+ $description = 'PHP uses files named as <code>' . $log_filename . '</code> to log errors found in '
6627
+ . 'the code, these files may leak sensitive information of your project allowing an attacker '
6628
+ . 'to find vulnerabilities in the code. You must use these files to fix any bug while using '
6629
+ . 'a development environment, and remove them in production mode.';
6630
+
6631
+ // Search error log files in the project.
6632
+ if( $scan_errorlogs != 'disabled' ){
6633
+ $sucuri_fileinfo = new SucuriScanFileInfo();
6634
+ $sucuri_fileinfo->ignore_files = FALSE;
6635
+ $sucuri_fileinfo->ignore_directories = FALSE;
6636
+ $error_logs = $sucuri_fileinfo->find_file('error_log');
6637
+ $total_log_files = count($error_logs);
6638
+ } else {
6639
+ $error_logs = array();
6640
+ $total_log_files = 0;
6641
+ $description .= '<div class="sucuriscan-inline-alert-error"><p>The filesystem scan for error '
6642
+ . 'log files is disabled, so even if there are logs in your project they will be not '
6643
+ . 'shown here. You can enable the scanner again from the plugin <em>Settings</em> '
6644
+ . 'page.</p></div>';
6645
+ }
6646
+
6647
+ // Remove every error log file found in the filesystem scan.
6648
+ if( SucuriScanRequest::post(':run_hardening') ){
6649
+ if( SucuriScanRequest::post(':harden_errorlog') ){
6650
+ $removed_logs = 0;
6651
+
6652
+ foreach( $error_logs as $i => $error_log_path ){
6653
+ if( unlink($error_log_path) ){
6654
+ unset($error_logs[$i]);
6655
+ $removed_logs += 1;
6656
+ }
6657
+ }
6658
+
6659
+ SucuriScanInterface::info( 'Error log files removed <code>' . $removed_logs . ' out of ' . $total_log_files . '</code>' );
6660
+ }
6661
+ }
6662
+
6663
+ // List the error log files in a HTML table.
6664
+ if( !empty($error_logs) ){
6665
+ $hardened = 0;
6666
+ $description .= '</p><ul class="sucuriscan-list-as-table">';
6667
+
6668
+ foreach( $error_logs as $error_log_path ){
6669
+ $description .= '<li>' . $error_log_path . '</li>';
6670
+ }
6671
+
6672
+ $description .= '</ul><p>';
6673
+ }
6674
+
6675
+ sucuriscan_harden_status(
6676
+ 'Error logs',
6677
+ $hardened,
6678
+ ( $hardened == 0 ? 'sucuriscan_harden_errorlog' : NULL ),
6679
+ 'There are no error log files in your project.',
6680
+ 'There are ' . $total_log_files . ' error log files in your project.',
6681
+ $description,
6682
+ NULL
6683
+ );
6684
+ }
6685
+
6686
  /**
6687
  * WordPress core integrity page.
6688
  *
7730
  'user_lastlogin' => current_time('mysql')
7731
  );
7732
 
7733
+ @file_put_contents($datastore_filepath, json_encode($login_info)."\n", FILE_APPEND);
7734
  }
7735
  }
7736
  add_action('wp_login', 'sucuriscan_set_lastlogin', 50);
7785
  for( $i=$offset; $i<$total_lines; $i++ ){
7786
  $line = $reversed_lines[$i] ? trim($reversed_lines[$i]) : '';
7787
 
7788
+ // Check if the data is serialized (which we will consider as insecure).
7789
+ if( SucuriScan::is_serialized($line) ){
7790
+ $last_login = @unserialize($line); // TODO: Remove after version 1.7.5
7791
+ } else {
7792
+ $last_login = @json_decode($line, TRUE);
7793
+ }
7794
+
7795
+ if( $last_login ){
7796
  $last_login['user_lastlogin_timestamp'] = strtotime($last_login['user_lastlogin']);
7797
  $last_login['user_registered_timestamp'] = 0;
7798
 
8433
  SucuriScanInterface::info( 'Filesystem scanner for file integrity was <code>' . $action_d . '</code>' );
8434
  }
8435
 
8436
+ // Enable or disable the filesystem scanner for error logs.
8437
+ if( $scan_errorlogs = SucuriScanRequest::post(':scan_errorlogs', '(en|dis)able') ){
8438
+ $action_d = $scan_errorlogs . 'd';
8439
+ SucuriScanOption::update_option(':scan_errorlogs', $action_d);
8440
+ SucuriScanEvent::notify_event( 'plugin_change', 'Filesystem scanner for error logs was: ' . $action_d );
8441
+ SucuriScanInterface::info( 'Filesystem scanner for error logs was <code>' . $action_d . '</code>' );
8442
+ }
8443
+
8444
  // Modify the schedule of the filesystem scanner.
8445
  if( $frequency = SucuriScanRequest::post(':scan_frequency') ){
8446
  $allowed_frequency = array_keys($sucuriscan_schedule_allowed);
8483
 
8484
  // Update the email where the event notifications will be sent.
8485
  if( $new_email = SucuriScanRequest::post(':notify_to') ){
8486
+ $valid_email = SucuriScan::get_valid_email($new_email);
8487
+
8488
+ if( $valid_email ){
8489
+ SucuriScanOption::update_option( ':notify_to', $valid_email );
8490
  SucuriScanEvent::notify_event( 'plugin_change', 'Email address to get the event notifications was changed' );
8491
  SucuriScanInterface::info( 'All the event notifications will be sent to the email specified.' );
8492
  } else {
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');
8718
  'ScanChecksumsSwitchText' => 'Disable',
8719
  'ScanChecksumsSwitchValue' => 'disable',
8720
  'ScanChecksumsSwitchCssClass' => 'button-danger',
8721
+ /* Scan error logs. */
8722
+ 'ScanErrorlogsStatus' => 'Enabled',
8723
+ 'ScanErrorlogsSwitchText' => 'Disable',
8724
+ 'ScanErrorlogsSwitchValue' => 'disable',
8725
+ 'ScanErrorlogsSwitchCssClass' => 'button-danger',
8726
  /* Filsystem scanning frequency. */
8727
  'ScanningFrequency' => 'Undefined',
8728
  'ScanningFrequencyOptions' => $scan_freq_options,
8764
  $template_variables['ScanChecksumsSwitchCssClass'] = 'button-success';
8765
  }
8766
 
8767
+ if( $scan_errorlogs == 'disabled' ){
8768
+ $template_variables['ScanErrorlogsStatus'] = 'Disabled';
8769
+ $template_variables['ScanErrorlogsSwitchText'] = 'Enable';
8770
+ $template_variables['ScanErrorlogsSwitchValue'] = 'enable';
8771
+ $template_variables['ScanErrorlogsSwitchCssClass'] = 'button-success';
8772
+ }
8773
+
8774
  if( array_key_exists($scan_freq, $sucuriscan_schedule_allowed) ){
8775
  $template_variables['ScanningFrequency'] = $sucuriscan_schedule_allowed[$scan_freq];
8776
  }
8800
 
8801
  $template_variables = array(
8802
  'NotificationOptions' => '',
8803
+ 'PrettifyMailsWarningVisibility' => SucuriScanTemplate::visibility( SucuriScanMail::prettify_mails() ),
8804
  );
8805
 
8806
  $counter = 0;
9270
  'Plugin_version' => SUCURISCAN_VERSION,
9271
  'Plugin_checksum' => SUCURISCAN_PLUGIN_CHECKSUM,
9272
  'Last_filesystem_scan' => SucuriScanOption::get_filesystem_runtime(TRUE),
9273
+ 'Using_CloudProxy' => 'Unknown',
9274
+ 'HTTP_Host' => 'Unknown',
9275
+ 'Host_Name' => 'Unknown',
9276
+ 'Host_Address' => 'Unknown',
9277
+ 'Remote_Address' => SucuriScan::get_remote_addr(),
9278
+ 'Remote_Address_Header' => SucuriScan::get_remote_addr_header(),
9279
  'Operating_system' => sprintf('%s (%d Bit)', PHP_OS, PHP_INT_SIZE*8),
9280
  'Server' => 'Unknown',
9281
  'Developer_mode' => 'OFF',
9285
  'PHP_version' => PHP_VERSION,
9286
  );
9287
 
9288
+ $proxy_info = SucuriScan::is_behind_cloudproxy(TRUE);
9289
+ $info_vars['HTTP_Host'] = $proxy_info['http_host'];
9290
+ $info_vars['Host_Name'] = $proxy_info['host_name'];
9291
+ $info_vars['Host_Address'] = $proxy_info['host_addr'];
9292
+ $info_vars['Using_CloudProxy'] = $proxy_info['status'] ? 'Yes' : 'No';
9293
 
9294
  if( defined('WP_DEBUG') && WP_DEBUG ){
9295
  $info_vars['Developer_mode'] = 'ON';
9323
  );
9324
 
9325
  foreach( $field_names as $php_flag ){
9326
+ $php_flag_value = SucuriScan::ini_get($php_flag);
9327
  $php_flag_name = 'PHP_' . $php_flag;
9328
  $info_vars[$php_flag_name] = $php_flag_value ? $php_flag_value : 'N/A';
9329
  }