Version Description
This version adds support for the latest version of WordPress. Introduces new features and fixes some bugs reported by the WordPress community as well as bugs found by our automated testing system.
=
Download this release
Release Info
Developer | yorman |
Plugin | Sucuri Security – Auditing, Malware Scanner and Security Hardening |
Version | 1.8.12 |
Comparing to | |
See all releases |
Code changes from version 1.8.11 to 1.8.12
- inc/css/styles.css +8 -7
- inc/js/scripts.js +61 -28
- inc/tpl/lastlogins-failedlogins.html.tpl +2 -3
- inc/tpl/lastlogins-failedlogins.snippet.tpl +0 -2
- inc/tpl/notification-pretty.html.tpl +1 -0
- inc/tpl/notification-simple.html.tpl +1 -0
- inc/tpl/settings-alerts-ignore-posts.html.tpl +30 -24
- inc/tpl/settings-apiservice-status.html.tpl +8 -0
- readme.txt +23 -3
- src/api.lib.php +2 -5
- src/auditlogs.lib.php +1 -2
- src/cli.lib.php +93 -0
- src/fileinfo.lib.php +28 -18
- src/firewall.lib.php +15 -2
- src/hook.lib.php +1 -7
- src/integrity.lib.php +6 -0
- src/interface.lib.php +3 -3
- src/lastlogins-failed.php +3 -23
- src/mail.lib.php +1 -0
- src/option.lib.php +11 -2
- src/settings-alerts.php +3 -10
- src/settings-apiservice.php +4 -0
- src/settings-general.php +28 -1
- src/sucuriscan.lib.php +20 -6
- sucuri.php +7 -2
inc/css/styles.css
CHANGED
@@ -46,7 +46,7 @@ body.sucuri-security_page_sucuriscan_hardening {
|
|
46 |
height: 30px;
|
47 |
line-height: normal;
|
48 |
}
|
49 |
-
.sucuriscan-container input[type=text] {
|
50 |
margin: 0;
|
51 |
padding: 0 7px;
|
52 |
line-height: 28px;
|
@@ -62,6 +62,7 @@ body.sucuri-security_page_sucuriscan_hardening {
|
|
62 |
text-transform: uppercase;
|
63 |
line-height: 30px;
|
64 |
font-weight: 700;
|
|
|
65 |
}
|
66 |
.sucuriscan-container fieldset span {
|
67 |
line-height: 30px;
|
@@ -71,8 +72,8 @@ body.sucuri-security_page_sucuriscan_hardening {
|
|
71 |
.sucuriscan-container fieldset label,
|
72 |
.sucuriscan-container fieldset select,
|
73 |
.sucuriscan-container fieldset button,
|
74 |
-
.sucuriscan-container fieldset input[type=text],
|
75 |
-
.sucuriscan-container fieldset input[type=checkbox],
|
76 |
.wp-core-ui .sucuriscan-container fieldset .button,
|
77 |
.wp-core-ui .sucuriscan-container fieldset .button-primary,
|
78 |
.wp-core-ui .sucuriscan-container fieldset .button-secondary {
|
@@ -83,13 +84,13 @@ body.sucuri-security_page_sucuriscan_hardening {
|
|
83 |
.sucuriscan-container fieldset label {
|
84 |
margin-left: 0;
|
85 |
}
|
86 |
-
.sucuriscan-container fieldset input[type=checkbox] {
|
87 |
margin-top: 7px;
|
88 |
margin-bottom: 7px;
|
89 |
}
|
90 |
.sucuriscan-container .sucuriscan-full-textarea {
|
91 |
width: 100%;
|
92 |
-
min-height:
|
93 |
background: #efefef;
|
94 |
word-break: break-all;
|
95 |
padding: 20px;
|
@@ -898,8 +899,8 @@ body.sucuri-security_page_sucuriscan_hardening {
|
|
898 |
.rtl .sucuriscan-container fieldset label,
|
899 |
.rtl .sucuriscan-container fieldset select,
|
900 |
.rtl .sucuriscan-container fieldset button,
|
901 |
-
.rtl .sucuriscan-container fieldset input[type=text],
|
902 |
-
.rtl .sucuriscan-container fieldset input[type=checkbox],
|
903 |
.rtl .wp-core-ui .sucuriscan-container fieldset .button,
|
904 |
.rtl .wp-core-ui .sucuriscan-container fieldset .button-primary,
|
905 |
.rtl .wp-core-ui .sucuriscan-container fieldset .button-secondary {
|
46 |
height: 30px;
|
47 |
line-height: normal;
|
48 |
}
|
49 |
+
.sucuriscan-container input[type='text'] {
|
50 |
margin: 0;
|
51 |
padding: 0 7px;
|
52 |
line-height: 28px;
|
62 |
text-transform: uppercase;
|
63 |
line-height: 30px;
|
64 |
font-weight: 700;
|
65 |
+
cursor: initial;
|
66 |
}
|
67 |
.sucuriscan-container fieldset span {
|
68 |
line-height: 30px;
|
72 |
.sucuriscan-container fieldset label,
|
73 |
.sucuriscan-container fieldset select,
|
74 |
.sucuriscan-container fieldset button,
|
75 |
+
.sucuriscan-container fieldset input[type='text'],
|
76 |
+
.sucuriscan-container fieldset input[type='checkbox'],
|
77 |
.wp-core-ui .sucuriscan-container fieldset .button,
|
78 |
.wp-core-ui .sucuriscan-container fieldset .button-primary,
|
79 |
.wp-core-ui .sucuriscan-container fieldset .button-secondary {
|
84 |
.sucuriscan-container fieldset label {
|
85 |
margin-left: 0;
|
86 |
}
|
87 |
+
.sucuriscan-container fieldset input[type='checkbox'] {
|
88 |
margin-top: 7px;
|
89 |
margin-bottom: 7px;
|
90 |
}
|
91 |
.sucuriscan-container .sucuriscan-full-textarea {
|
92 |
width: 100%;
|
93 |
+
min-height: 400px;
|
94 |
background: #efefef;
|
95 |
word-break: break-all;
|
96 |
padding: 20px;
|
899 |
.rtl .sucuriscan-container fieldset label,
|
900 |
.rtl .sucuriscan-container fieldset select,
|
901 |
.rtl .sucuriscan-container fieldset button,
|
902 |
+
.rtl .sucuriscan-container fieldset input[type='text'],
|
903 |
+
.rtl .sucuriscan-container fieldset input[type='checkbox'],
|
904 |
.rtl .wp-core-ui .sucuriscan-container fieldset .button,
|
905 |
.rtl .wp-core-ui .sucuriscan-container fieldset .button-primary,
|
906 |
.rtl .wp-core-ui .sucuriscan-container fieldset .button-secondary {
|
inc/js/scripts.js
CHANGED
@@ -1,29 +1,35 @@
|
|
1 |
/* global jQuery */
|
2 |
-
/* jshint unused:false */
|
3 |
|
4 |
-
|
|
|
5 |
var element = document.getElementById('sucuriscan-alert-' + id);
|
6 |
element.parentNode.removeChild(element);
|
7 |
}
|
|
|
8 |
|
9 |
-
jQuery(document).ready(function
|
10 |
-
$('.sucuriscan-container').on('click', '.sucuriscan-modal-button', function
|
11 |
event.preventDefault();
|
|
|
12 |
var modalid = $(this).data('modalid');
|
|
|
13 |
$('div.' + modalid + '-modal').removeClass('sucuriscan-hidden');
|
14 |
});
|
15 |
|
16 |
-
$('.sucuriscan-container').on('click', '.sucuriscan-overlay, .sucuriscan-modal-close', function
|
17 |
event.preventDefault();
|
|
|
18 |
$('.sucuriscan-overlay').addClass('sucuriscan-hidden');
|
19 |
$('.sucuriscan-modal').addClass('sucuriscan-hidden');
|
20 |
});
|
21 |
|
22 |
-
$('.sucuriscan-container').on('click', '.sucuriscan-show-more', function
|
23 |
event.preventDefault();
|
|
|
24 |
var button = $(this);
|
25 |
var target = button.attr('data-target');
|
26 |
var status = button.attr('data-status');
|
|
|
27 |
if (status === 'more') {
|
28 |
button.attr('data-status', 'less');
|
29 |
$(target).removeClass('sucuriscan-hidden');
|
@@ -41,36 +47,44 @@ jQuery(document).ready(function ($) {
|
|
41 |
var activeState = 'sucuriscan-tab-active';
|
42 |
var locationHash = location.href.split('#')[1];
|
43 |
|
44 |
-
$('.sucuriscan-container').on('click', '.sucuriscan-tabs-buttons a', function
|
45 |
event.preventDefault();
|
46 |
|
47 |
var button = $(this);
|
48 |
var uniqueid = button.attr('href').split('#')[1];
|
49 |
|
50 |
-
if (uniqueid
|
51 |
-
|
|
|
52 |
|
53 |
-
|
54 |
-
var rawurl = location.href.replace(location.hash, '');
|
55 |
-
var newurl = rawurl + '#' + uniqueid;
|
56 |
|
57 |
-
|
|
|
|
|
58 |
|
59 |
-
|
60 |
-
|
61 |
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
|
|
|
|
|
|
67 |
});
|
68 |
|
69 |
$('.sucuriscan-tabs-containers > div').addClass(hiddenState);
|
70 |
|
71 |
if (locationHash !== undefined) {
|
72 |
-
$('.sucuriscan-tabs-buttons a').each(function
|
73 |
-
|
|
|
|
|
|
|
|
|
74 |
$(button).trigger('click');
|
75 |
}
|
76 |
});
|
@@ -79,7 +93,7 @@ jQuery(document).ready(function ($) {
|
|
79 |
}
|
80 |
}
|
81 |
|
82 |
-
$('.sucuriscan-container').on('mouseover', '.sucuriscan-tooltip', function
|
83 |
var element = $(this);
|
84 |
var content = element.attr('content');
|
85 |
|
@@ -88,7 +102,7 @@ jQuery(document).ready(function ($) {
|
|
88 |
}
|
89 |
|
90 |
/* create instance of tooltip container */
|
91 |
-
var tooltip = $('<div>', {
|
92 |
|
93 |
if (element.attr('tooltip-width')) {
|
94 |
var customWidth = element.attr('tooltip-width');
|
@@ -107,7 +121,6 @@ jQuery(document).ready(function ($) {
|
|
107 |
var tooltipHeight = tooltip.outerHeight();
|
108 |
tooltip.css('top', (tooltipHeight + arrowHeight) * -1);
|
109 |
|
110 |
-
var positionLeft = 0;
|
111 |
var elementWidth = element.outerWidth();
|
112 |
var tooltipWidth = tooltip.outerWidth();
|
113 |
|
@@ -116,11 +129,31 @@ jQuery(document).ready(function ($) {
|
|
116 |
} else if (elementWidth > tooltipWidth) {
|
117 |
tooltip.css('left', (elementWidth - tooltipWidth) / 2);
|
118 |
} else if (elementWidth < tooltipWidth) {
|
119 |
-
tooltip.css('left', (
|
120 |
}
|
121 |
});
|
122 |
|
123 |
-
$('.sucuriscan-container').on('mouseout', '.sucuriscan-tooltip', function
|
124 |
-
$(this)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
125 |
});
|
126 |
});
|
1 |
/* global jQuery */
|
|
|
2 |
|
3 |
+
/* jshint ignore:start */
|
4 |
+
function sucuriscanAlertClose(id) {
|
5 |
var element = document.getElementById('sucuriscan-alert-' + id);
|
6 |
element.parentNode.removeChild(element);
|
7 |
}
|
8 |
+
/* jshint ignore:end */
|
9 |
|
10 |
+
jQuery(document).ready(function($) {
|
11 |
+
$('.sucuriscan-container').on('click', '.sucuriscan-modal-button', function(event) {
|
12 |
event.preventDefault();
|
13 |
+
|
14 |
var modalid = $(this).data('modalid');
|
15 |
+
|
16 |
$('div.' + modalid + '-modal').removeClass('sucuriscan-hidden');
|
17 |
});
|
18 |
|
19 |
+
$('.sucuriscan-container').on('click', '.sucuriscan-overlay, .sucuriscan-modal-close', function(event) {
|
20 |
event.preventDefault();
|
21 |
+
|
22 |
$('.sucuriscan-overlay').addClass('sucuriscan-hidden');
|
23 |
$('.sucuriscan-modal').addClass('sucuriscan-hidden');
|
24 |
});
|
25 |
|
26 |
+
$('.sucuriscan-container').on('click', '.sucuriscan-show-more', function(event) {
|
27 |
event.preventDefault();
|
28 |
+
|
29 |
var button = $(this);
|
30 |
var target = button.attr('data-target');
|
31 |
var status = button.attr('data-status');
|
32 |
+
|
33 |
if (status === 'more') {
|
34 |
button.attr('data-status', 'less');
|
35 |
$(target).removeClass('sucuriscan-hidden');
|
47 |
var activeState = 'sucuriscan-tab-active';
|
48 |
var locationHash = location.href.split('#')[1];
|
49 |
|
50 |
+
$('.sucuriscan-container').on('click', '.sucuriscan-tabs-buttons a', function(event) {
|
51 |
event.preventDefault();
|
52 |
|
53 |
var button = $(this);
|
54 |
var uniqueid = button.attr('href').split('#')[1];
|
55 |
|
56 |
+
if (!uniqueid) {
|
57 |
+
return;
|
58 |
+
}
|
59 |
|
60 |
+
var container = $('.sucuriscan-tabs-containers > #sucuriscan-tabs-' + uniqueid);
|
|
|
|
|
61 |
|
62 |
+
if (!container.length) {
|
63 |
+
return;
|
64 |
+
}
|
65 |
|
66 |
+
var rawurl = location.href.replace(location.hash, '');
|
67 |
+
var newurl = rawurl + '#' + uniqueid;
|
68 |
|
69 |
+
window.history.pushState({}, document.title, newurl);
|
70 |
+
|
71 |
+
$('.sucuriscan-tabs-buttons a').removeClass(activeState);
|
72 |
+
$('.sucuriscan-tabs-containers > div').addClass(hiddenState);
|
73 |
+
|
74 |
+
button.addClass(activeState);
|
75 |
+
container.addClass(visibleState);
|
76 |
+
container.removeClass(hiddenState);
|
77 |
});
|
78 |
|
79 |
$('.sucuriscan-tabs-containers > div').addClass(hiddenState);
|
80 |
|
81 |
if (locationHash !== undefined) {
|
82 |
+
$('.sucuriscan-tabs-buttons a').each(function(e, button) {
|
83 |
+
var buttonHash = $(button)
|
84 |
+
.attr('href')
|
85 |
+
.split('#')[1];
|
86 |
+
|
87 |
+
if (buttonHash === locationHash) {
|
88 |
$(button).trigger('click');
|
89 |
}
|
90 |
});
|
93 |
}
|
94 |
}
|
95 |
|
96 |
+
$('.sucuriscan-container').on('mouseover', '.sucuriscan-tooltip', function() {
|
97 |
var element = $(this);
|
98 |
var content = element.attr('content');
|
99 |
|
102 |
}
|
103 |
|
104 |
/* create instance of tooltip container */
|
105 |
+
var tooltip = $('<div>', { class: 'sucuriscan-tooltip-object' });
|
106 |
|
107 |
if (element.attr('tooltip-width')) {
|
108 |
var customWidth = element.attr('tooltip-width');
|
121 |
var tooltipHeight = tooltip.outerHeight();
|
122 |
tooltip.css('top', (tooltipHeight + arrowHeight) * -1);
|
123 |
|
|
|
124 |
var elementWidth = element.outerWidth();
|
125 |
var tooltipWidth = tooltip.outerWidth();
|
126 |
|
129 |
} else if (elementWidth > tooltipWidth) {
|
130 |
tooltip.css('left', (elementWidth - tooltipWidth) / 2);
|
131 |
} else if (elementWidth < tooltipWidth) {
|
132 |
+
tooltip.css('left', (tooltipWidth - elementWidth) / 2 * -1);
|
133 |
}
|
134 |
});
|
135 |
|
136 |
+
$('.sucuriscan-container').on('mouseout', '.sucuriscan-tooltip', function() {
|
137 |
+
$(this)
|
138 |
+
.find('.sucuriscan-tooltip-object')
|
139 |
+
.remove();
|
140 |
+
});
|
141 |
+
|
142 |
+
$('.sucuriscan-container').on('click', 'button.sucuriscan-show-section', function(event) {
|
143 |
+
event.preventDefault();
|
144 |
+
|
145 |
+
var button = $(this);
|
146 |
+
var current = button.text();
|
147 |
+
var onText = button.attr('on');
|
148 |
+
var offText = button.attr('off');
|
149 |
+
var section = button.attr('section');
|
150 |
+
|
151 |
+
if (current === onText) {
|
152 |
+
$('#' + section).removeClass('sucuriscan-hidden');
|
153 |
+
button.html(offText);
|
154 |
+
} else {
|
155 |
+
$('#' + section).addClass('sucuriscan-hidden');
|
156 |
+
button.html(onText);
|
157 |
+
}
|
158 |
});
|
159 |
});
|
inc/tpl/lastlogins-failedlogins.html.tpl
CHANGED
@@ -16,7 +16,6 @@
|
|
16 |
<input id="cb-select-all-1" type="checkbox">
|
17 |
</td>
|
18 |
<th class="manage-column">Username</th>
|
19 |
-
<th class="manage-column">Password</th>
|
20 |
<th class="manage-column">IP Address</th>
|
21 |
<th class="manage-column">Date/Time</th>
|
22 |
<th class="manage-column" width="300">Web Browser</th>
|
@@ -27,13 +26,13 @@
|
|
27 |
%%%SUCURI.FailedLogins.List%%%
|
28 |
|
29 |
<tr class="sucuriscan-%%SUCURI.FailedLogins.NoItemsVisibility%%">
|
30 |
-
<td colspan="
|
31 |
<em>no data available</em>
|
32 |
</td>
|
33 |
</tr>
|
34 |
|
35 |
<tr class="sucuriscan-%%SUCURI.FailedLogins.PaginationVisibility%%">
|
36 |
-
<td colspan="
|
37 |
<ul class="sucuriscan-pagination">
|
38 |
%%%SUCURI.FailedLogins.PaginationLinks%%%
|
39 |
</ul>
|
16 |
<input id="cb-select-all-1" type="checkbox">
|
17 |
</td>
|
18 |
<th class="manage-column">Username</th>
|
|
|
19 |
<th class="manage-column">IP Address</th>
|
20 |
<th class="manage-column">Date/Time</th>
|
21 |
<th class="manage-column" width="300">Web Browser</th>
|
26 |
%%%SUCURI.FailedLogins.List%%%
|
27 |
|
28 |
<tr class="sucuriscan-%%SUCURI.FailedLogins.NoItemsVisibility%%">
|
29 |
+
<td colspan="5">
|
30 |
<em>no data available</em>
|
31 |
</td>
|
32 |
</tr>
|
33 |
|
34 |
<tr class="sucuriscan-%%SUCURI.FailedLogins.PaginationVisibility%%">
|
35 |
+
<td colspan="5">
|
36 |
<ul class="sucuriscan-pagination">
|
37 |
%%%SUCURI.FailedLogins.PaginationLinks%%%
|
38 |
</ul>
|
inc/tpl/lastlogins-failedlogins.snippet.tpl
CHANGED
@@ -6,8 +6,6 @@
|
|
6 |
|
7 |
<td><span class="sucuriscan-monospace">%%SUCURI.FailedLogins.Username%%</span></td>
|
8 |
|
9 |
-
<td><span class="sucuriscan-monospace">%%SUCURI.FailedLogins.Password%%</span></td>
|
10 |
-
|
11 |
<td><span class="sucuriscan-monospace">%%SUCURI.FailedLogins.RemoteAddr%%</span></td>
|
12 |
|
13 |
<td><em>%%SUCURI.FailedLogins.Datetime%%</em></td>
|
6 |
|
7 |
<td><span class="sucuriscan-monospace">%%SUCURI.FailedLogins.Username%%</span></td>
|
8 |
|
|
|
|
|
9 |
<td><span class="sucuriscan-monospace">%%SUCURI.FailedLogins.RemoteAddr%%</span></td>
|
10 |
|
11 |
<td><em>%%SUCURI.FailedLogins.Datetime%%</em></td>
|
inc/tpl/notification-pretty.html.tpl
CHANGED
@@ -18,6 +18,7 @@
|
|
18 |
<p style="margin:0 0 10px 0">
|
19 |
Website: <a href="http://%%SUCURI.Website%%">%%SUCURI.Website%%</a><br>
|
20 |
IP Address: %%SUCURI.RemoteAddress%%<br>
|
|
|
21 |
Date/Time: %%SUCURI.Time%%<br>
|
22 |
%%SUCURI.User%%
|
23 |
</p>
|
18 |
<p style="margin:0 0 10px 0">
|
19 |
Website: <a href="http://%%SUCURI.Website%%">%%SUCURI.Website%%</a><br>
|
20 |
IP Address: %%SUCURI.RemoteAddress%%<br>
|
21 |
+
Reverse IP: %%SUCURI.ReverseAddress%%<br>
|
22 |
Date/Time: %%SUCURI.Time%%<br>
|
23 |
%%SUCURI.User%%
|
24 |
</p>
|
inc/tpl/notification-simple.html.tpl
CHANGED
@@ -2,6 +2,7 @@
|
|
2 |
Event: %%SUCURI.Subject%%
|
3 |
Website: http://%%SUCURI.Website%%
|
4 |
IP Address: %%SUCURI.RemoteAddress%%
|
|
|
5 |
Date/Time: %%SUCURI.Time%%
|
6 |
%%SUCURI.User%%
|
7 |
|
2 |
Event: %%SUCURI.Subject%%
|
3 |
Website: http://%%SUCURI.Website%%
|
4 |
IP Address: %%SUCURI.RemoteAddress%%
|
5 |
+
Reverse IP: %%SUCURI.ReverseAddress%%
|
6 |
Date/Time: %%SUCURI.Time%%
|
7 |
%%SUCURI.User%%
|
8 |
|
inc/tpl/settings-alerts-ignore-posts.html.tpl
CHANGED
@@ -22,29 +22,35 @@
|
|
22 |
|
23 |
<hr>
|
24 |
|
25 |
-
<
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
<
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
49 |
</div>
|
50 |
</div>
|
22 |
|
23 |
<hr>
|
24 |
|
25 |
+
<button class="button button-primary sucuriscan-show-section" section="sucuriscan-ignorerules" on="Show Post-Types Table" off="Hide Post-Types Table">Show Post-Types Table</button>
|
26 |
+
|
27 |
+
<div class="sucuriscan-hidden" id="sucuriscan-ignorerules">
|
28 |
+
<hr>
|
29 |
+
|
30 |
+
<form action="%%SUCURI.URL.Settings%%#alerts" method="post">
|
31 |
+
<input type="hidden" name="sucuriscan_page_nonce" value="%%SUCURI.PageNonce%%" />
|
32 |
+
<input type="hidden" name="sucuriscan_ignorerule_action" value="batch" />
|
33 |
+
|
34 |
+
<table class="wp-list-table widefat sucuriscan-table sucuriscan-settings-ignorerules">
|
35 |
+
<thead>
|
36 |
+
<tr>
|
37 |
+
<td id="cb" class="manage-column column-cb check-column">
|
38 |
+
<label class="screen-reader-text" for="cb-select-all-1">Select All</label>
|
39 |
+
<input id="cb-select-all-1" type="checkbox">
|
40 |
+
</td>
|
41 |
+
<th class="manage-column">Post Type</th>
|
42 |
+
<th class="manage-column">Post Type ID</th>
|
43 |
+
<th class="manage-column">Ignored At (optional)</th>
|
44 |
+
</tr>
|
45 |
+
</thead>
|
46 |
+
|
47 |
+
<tbody>
|
48 |
+
%%%SUCURI.PostTypes.List%%%
|
49 |
+
</tbody>
|
50 |
+
</table>
|
51 |
+
|
52 |
+
<button type="submit" class="button button-primary">Submit</button>
|
53 |
+
</form>
|
54 |
+
</div>
|
55 |
</div>
|
56 |
</div>
|
inc/tpl/settings-apiservice-status.html.tpl
CHANGED
@@ -18,5 +18,13 @@
|
|
18 |
<button type="submit" class="button button-primary">%%SUCURI.ApiStatus.SwitchText%%</button>
|
19 |
</form>
|
20 |
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
21 |
</div>
|
22 |
</div>
|
18 |
<button type="submit" class="button button-primary">%%SUCURI.ApiStatus.SwitchText%%</button>
|
19 |
</form>
|
20 |
</div>
|
21 |
+
|
22 |
+
<p>
|
23 |
+
<strong>Are you a developer?</strong> You may be interested in our API. Feel free to use the URL shown below to access the latest 50 entries in your security log, change the value for the parameter <code>l=N</code> if you need more. Be aware that the API doesn't provides an offset parameter, so if you have the intension to query specific sections of the log you will need to wrap the HTTP request around your own cache mechanism. We <strong>DO NOT</strong> take feature requests for the API, this is a semi-private service tailored for the specific needs of the plugin and not intended to be used by 3rd-party apps, we may change the behavior of each API endpoint without previous notice, use it at your own risk.
|
24 |
+
</p>
|
25 |
+
|
26 |
+
<div class="sucuriscan-hstatus sucuriscan-hstatus-2 sucuriscan-monospace">
|
27 |
+
<span>curl -s "https://wordpress.sucuri.net/api/?k=%%SUCURI.ApiStatus.ApiKey%%&a=get_logs&l=50" | python -m json.tool</span>
|
28 |
+
</div>
|
29 |
</div>
|
30 |
</div>
|
readme.txt
CHANGED
@@ -3,8 +3,8 @@ Contributors: dd@sucuri.net
|
|
3 |
Donate Link: https://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 Security, Website Firewall, Website AntiVirus, Security Response, Security Detection, Security Prevention
|
5 |
Requires at least: 3.6
|
6 |
-
Tested up to: 4.
|
7 |
-
Stable tag: 1.8.
|
8 |
|
9 |
The Sucuri WordPress Security plugin is a security toolset for security integrity monitoring, malware detection and security hardening.
|
10 |
|
@@ -181,11 +181,31 @@ No, it is not required. The Website Firewall runs in the cloud without the need
|
|
181 |
|
182 |
== Upgrade Notice ==
|
183 |
|
184 |
-
= 1.8.
|
185 |
This version adds support for the latest version of WordPress. Introduces new features and fixes some bugs reported by the WordPress community as well as bugs found by our automated testing system.
|
186 |
|
187 |
== Changelog ==
|
188 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
189 |
= 1.8.11 =
|
190 |
* Modify Sucuri firewall detection with regular expressions
|
191 |
* Modify option to force scanner to ignore directories
|
3 |
Donate Link: https://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 Security, Website Firewall, Website AntiVirus, Security Response, Security Detection, Security Prevention
|
5 |
Requires at least: 3.6
|
6 |
+
Tested up to: 4.9.4
|
7 |
+
Stable tag: 1.8.12
|
8 |
|
9 |
The Sucuri WordPress Security plugin is a security toolset for security integrity monitoring, malware detection and security hardening.
|
10 |
|
181 |
|
182 |
== Upgrade Notice ==
|
183 |
|
184 |
+
= 1.8.12 =
|
185 |
This version adds support for the latest version of WordPress. Introduces new features and fixes some bugs reported by the WordPress community as well as bugs found by our automated testing system.
|
186 |
|
187 |
== Changelog ==
|
188 |
|
189 |
+
= 1.8.12 =
|
190 |
+
* Fix invalid array when deselecting all security alerts
|
191 |
+
* Add language files to the list of ignored changes
|
192 |
+
* Modify internal response to the log file not found error
|
193 |
+
* Add option to force the firewall cache flush
|
194 |
+
* Fix unexpected exception when open_basedir is in place
|
195 |
+
* Add support to export and import trusted IP addresses
|
196 |
+
* Add link to the audit logs API endpoint for developers
|
197 |
+
* Add reverse ip address in all email alerts from visitor
|
198 |
+
* Remove API key from the settings that can be exported
|
199 |
+
* Modify code to make default plugin options filterable
|
200 |
+
* Add ability to store the settings in the object cache
|
201 |
+
* Add support for wp-cli and command to generate an API key
|
202 |
+
* Fix missing documentation tags in the command line library
|
203 |
+
* Fix format and coding standard in CSS and JavaScript files
|
204 |
+
* Add button to toggle the visibility of the post-types table
|
205 |
+
* Modify order of the added, modified, removed core files
|
206 |
+
* Fix relative file path when ABSPATH is point to root
|
207 |
+
* Add additional notifications for changes on users
|
208 |
+
|
209 |
= 1.8.11 =
|
210 |
* Modify Sucuri firewall detection with regular expressions
|
211 |
* Modify option to force scanner to ignore directories
|
src/api.lib.php
CHANGED
@@ -284,12 +284,9 @@ class SucuriScanAPI extends SucuriScanOption
|
|
284 |
if (stripos($raw, 'log file not found') !== false) {
|
285 |
$key = SucuriScanOption::getOption(':api_key');
|
286 |
$msg .= '; this generally happens when you use an invalid API key,'
|
287 |
-
. '
|
288 |
-
. ' recover it go to the settings page and follow the instructions'
|
289 |
-
. ' in the "API Key" section: <code>' . SucuriScan::escape($key)
|
290 |
-
. '</code>';
|
291 |
|
292 |
-
|
293 |
}
|
294 |
|
295 |
// Special response for invalid firewall API keys.
|
284 |
if (stripos($raw, 'log file not found') !== false) {
|
285 |
$key = SucuriScanOption::getOption(':api_key');
|
286 |
$msg .= '; this generally happens when you use an invalid API key,'
|
287 |
+
. ' or when the connection with the API service suddently closes.';
|
|
|
|
|
|
|
288 |
|
289 |
+
SucuriScanEvent::reportCriticalEvent($msg);
|
290 |
}
|
291 |
|
292 |
// Special response for invalid firewall API keys.
|
src/auditlogs.lib.php
CHANGED
@@ -170,7 +170,6 @@ class SucuriScanAuditLogs
|
|
170 |
$outdata = (array) $auditlogs['output_data'];
|
171 |
$todaysDate = SucuriScan::datetime(null, 'M d, Y');
|
172 |
$iterator_start = ($pageNumber - 1) * $maxPerPage;
|
173 |
-
$show_password = SucuriScanOption::isEnabled(':notify_failed_password');
|
174 |
$total_items = count($outdata);
|
175 |
|
176 |
usort($outdata, array('SucuriScanAuditLogs', 'sortByDate'));
|
@@ -186,7 +185,7 @@ class SucuriScanAuditLogs
|
|
186 |
|
187 |
$audit_log = (array) $outdata[$i];
|
188 |
|
189 |
-
if (
|
190 |
$idx = strpos($audit_log['message'], ";\x20password:");
|
191 |
$audit_log['message'] = substr($audit_log['message'], 0, $idx);
|
192 |
}
|
170 |
$outdata = (array) $auditlogs['output_data'];
|
171 |
$todaysDate = SucuriScan::datetime(null, 'M d, Y');
|
172 |
$iterator_start = ($pageNumber - 1) * $maxPerPage;
|
|
|
173 |
$total_items = count($outdata);
|
174 |
|
175 |
usort($outdata, array('SucuriScanAuditLogs', 'sortByDate'));
|
185 |
|
186 |
$audit_log = (array) $outdata[$i];
|
187 |
|
188 |
+
if (strpos($audit_log['message'], ";\x20password:")) {
|
189 |
$idx = strpos($audit_log['message'], ";\x20password:");
|
190 |
$audit_log['message'] = substr($audit_log['message'], 0, $idx);
|
191 |
}
|
src/cli.lib.php
ADDED
@@ -0,0 +1,93 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Code related to the cli.lib.php interface.
|
5 |
+
*
|
6 |
+
* PHP version 5
|
7 |
+
*
|
8 |
+
* @category Library
|
9 |
+
* @package Sucuri
|
10 |
+
* @subpackage SucuriScanCLI
|
11 |
+
* @author Daniel Cid <dcid@sucuri.net>
|
12 |
+
* @copyright 2010-2017 Sucuri Inc.
|
13 |
+
* @license https://www.gnu.org/licenses/gpl-2.0.txt GPL2
|
14 |
+
* @link https://wordpress.org/plugins/sucuri-scanner
|
15 |
+
*/
|
16 |
+
|
17 |
+
if (!defined('SUCURISCAN_INIT') || SUCURISCAN_INIT !== true) {
|
18 |
+
if (!headers_sent()) {
|
19 |
+
/* Report invalid access if possible. */
|
20 |
+
header('HTTP/1.1 403 Forbidden');
|
21 |
+
}
|
22 |
+
exit(1);
|
23 |
+
}
|
24 |
+
|
25 |
+
/**
|
26 |
+
* Manage Sucuri API registration.
|
27 |
+
*
|
28 |
+
* @category Library
|
29 |
+
* @package Sucuri
|
30 |
+
* @subpackage SucuriScanner
|
31 |
+
* @author Daniel Cid <dcid@sucuri.net>
|
32 |
+
* @copyright 2010-2017 Sucuri Inc.
|
33 |
+
* @license https://www.gnu.org/licenses/gpl-2.0.txt GPL2
|
34 |
+
* @link https://wordpress.org/plugins/sucuri-scanner
|
35 |
+
*/
|
36 |
+
class SucuriScanCLI extends WP_CLI_Command
|
37 |
+
{
|
38 |
+
/**
|
39 |
+
* Register and connect to the Sucuri API.
|
40 |
+
*
|
41 |
+
* ## OPTIONS
|
42 |
+
*
|
43 |
+
* [<api_key>]
|
44 |
+
* : Sucuri API key to register with.
|
45 |
+
*
|
46 |
+
* ## EXAMPLES
|
47 |
+
*
|
48 |
+
* # New registration
|
49 |
+
* wp sucuri register
|
50 |
+
* API key: 99e656abef7a123d1cffe73f91ba63702
|
51 |
+
* Success: The API key for your site was successfully generated and saved.
|
52 |
+
*
|
53 |
+
* # Existing key registration
|
54 |
+
* wp sucuri register 99e656abef7a123d1cffe73f91ba63702
|
55 |
+
* Success: The API key for your site was successfully saved.
|
56 |
+
*
|
57 |
+
* # Registration recovery
|
58 |
+
* wp sucuri register
|
59 |
+
* Warning: We already have an API key created for this site. It has been sent to the email admin@example.com for recovery.
|
60 |
+
*
|
61 |
+
* @param array $args Arguments from the command line interface.
|
62 |
+
* @return void
|
63 |
+
*/
|
64 |
+
public function register($args)
|
65 |
+
{
|
66 |
+
list($api_key) = $args;
|
67 |
+
|
68 |
+
ob_start();
|
69 |
+
$registered = $api_key ? SucuriScanAPI::setPluginKey($api_key, true) : SucuriScanAPI::registerSite();
|
70 |
+
$output = ob_get_clean();
|
71 |
+
|
72 |
+
preg_match_all('/<p><b>SUCURI:<\/b>(.+)<\/p>/', $output, $matches);
|
73 |
+
|
74 |
+
$message = isset($matches[1][0]) ? trim(strip_tags($matches[1][0])) : 'An unknown error occurred during registration.';
|
75 |
+
|
76 |
+
if (! $registered) {
|
77 |
+
WP_CLI::error($message);
|
78 |
+
}
|
79 |
+
|
80 |
+
if ($registered && $api_key) {
|
81 |
+
WP_CLI::success('The API key for your site was successfully saved.');
|
82 |
+
return;
|
83 |
+
}
|
84 |
+
|
85 |
+
$api_key = SucuriScanAPI::getPluginKey();
|
86 |
+
|
87 |
+
WP_CLI::line("API key: $api_key");
|
88 |
+
|
89 |
+
WP_CLI::success($message);
|
90 |
+
}
|
91 |
+
}
|
92 |
+
|
93 |
+
WP_CLI::add_command('sucuri', 'SucuriScanCLI');
|
src/fileinfo.lib.php
CHANGED
@@ -235,23 +235,27 @@ class SucuriScanFileInfo extends SucuriScan
|
|
235 |
continue;
|
236 |
}
|
237 |
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
-
|
|
|
|
|
|
|
|
|
255 |
}
|
256 |
}
|
257 |
|
@@ -293,7 +297,13 @@ class SucuriScanFileInfo extends SucuriScan
|
|
293 |
$filesize = @filesize($filepath);
|
294 |
|
295 |
if ($as_array) {
|
296 |
-
$basename =
|
|
|
|
|
|
|
|
|
|
|
|
|
297 |
$signatures[$basename] = array(
|
298 |
'filepath' => $filepath,
|
299 |
'checksum' => $file_checksum,
|
235 |
continue;
|
236 |
}
|
237 |
|
238 |
+
try {
|
239 |
+
/* check only files */
|
240 |
+
if ($fifo->isFile()
|
241 |
+
&& $filterby === 'file'
|
242 |
+
&& !$this->ignoreFile($filepath)
|
243 |
+
&& !$this->ignoreFolder($filepath)
|
244 |
+
) {
|
245 |
+
$files[] = $filepath;
|
246 |
+
continue;
|
247 |
+
}
|
248 |
+
|
249 |
+
/* check only directories */
|
250 |
+
if ($fifo->isDir()
|
251 |
+
&& $filterby === 'directory'
|
252 |
+
&& !$this->ignoreFolder($filepath)
|
253 |
+
) {
|
254 |
+
$files[] = $filepath;
|
255 |
+
continue;
|
256 |
+
}
|
257 |
+
} catch (RuntimeException $e) {
|
258 |
+
SucuriScanEvent::reportCriticalEvent($e->getMessage());
|
259 |
}
|
260 |
}
|
261 |
|
297 |
$filesize = @filesize($filepath);
|
298 |
|
299 |
if ($as_array) {
|
300 |
+
$basename = $filepath;
|
301 |
+
|
302 |
+
if (strlen($abspath . '/') > 1) {
|
303 |
+
/* convert absolute path into relative path */
|
304 |
+
$basename = str_replace($abspath . '/', '', $filepath);
|
305 |
+
}
|
306 |
+
|
307 |
$signatures[$basename] = array(
|
308 |
'filepath' => $filepath,
|
309 |
'checksum' => $file_checksum,
|
src/firewall.lib.php
CHANGED
@@ -691,7 +691,7 @@ class SucuriScanFirewall extends SucuriScanAPI
|
|
691 |
|
692 |
$params['FirewallAutoClearCache'] = 'data-status="disabled"';
|
693 |
|
694 |
-
if (
|
695 |
$params['FirewallAutoClearCache'] = 'checked="checked"';
|
696 |
}
|
697 |
|
@@ -711,7 +711,7 @@ class SucuriScanFirewall extends SucuriScanAPI
|
|
711 |
*/
|
712 |
public static function clearCacheHook()
|
713 |
{
|
714 |
-
if (
|
715 |
ob_start();
|
716 |
self::clearCache();
|
717 |
$error = ob_get_clean();
|
@@ -776,4 +776,17 @@ class SucuriScanFirewall extends SucuriScanAPI
|
|
776 |
|
777 |
wp_send_json($response, 200);
|
778 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
779 |
}
|
691 |
|
692 |
$params['FirewallAutoClearCache'] = 'data-status="disabled"';
|
693 |
|
694 |
+
if (self::shouldAutoClearCache()) {
|
695 |
$params['FirewallAutoClearCache'] = 'checked="checked"';
|
696 |
}
|
697 |
|
711 |
*/
|
712 |
public static function clearCacheHook()
|
713 |
{
|
714 |
+
if (self::shouldAutoClearCache()) {
|
715 |
ob_start();
|
716 |
self::clearCache();
|
717 |
$error = ob_get_clean();
|
776 |
|
777 |
wp_send_json($response, 200);
|
778 |
}
|
779 |
+
|
780 |
+
/**
|
781 |
+
* Returns true if the plugin should flush the firewall cache.
|
782 |
+
*
|
783 |
+
* @return bool True if the plugin should flush the firewall cache.
|
784 |
+
*/
|
785 |
+
private static function shouldAutoClearCache()
|
786 |
+
{
|
787 |
+
return (bool) (
|
788 |
+
defined('SUCURI_CLEAR_CACHE_ON_PUBLISH')
|
789 |
+
|| SucuriScanOption::isEnabled(':auto_clear_cache')
|
790 |
+
);
|
791 |
+
}
|
792 |
}
|
src/hook.lib.php
CHANGED
@@ -176,13 +176,7 @@ class SucuriScanHook extends SucuriScanEvent
|
|
176 |
$title = empty($title) ? 'Unknown' : sanitize_user($title, true);
|
177 |
$message = 'User authentication failed: ' . $title;
|
178 |
|
179 |
-
|
180 |
-
if (SucuriScanOption::isEnabled(':notify_failed_password')) {
|
181 |
-
$message .= '; password: ' . $password;
|
182 |
-
sucuriscan_log_failed_login($title, $password);
|
183 |
-
} else {
|
184 |
-
sucuriscan_log_failed_login($title, '[hidden]');
|
185 |
-
}
|
186 |
|
187 |
self::reportErrorEvent($message);
|
188 |
|
176 |
$title = empty($title) ? 'Unknown' : sanitize_user($title, true);
|
177 |
$message = 'User authentication failed: ' . $title;
|
178 |
|
179 |
+
sucuriscan_log_failed_login($title);
|
|
|
|
|
|
|
|
|
|
|
|
|
180 |
|
181 |
self::reportErrorEvent($message);
|
182 |
|
src/integrity.lib.php
CHANGED
@@ -586,6 +586,10 @@ class SucuriScanIntegrity
|
|
586 |
}
|
587 |
}
|
588 |
|
|
|
|
|
|
|
|
|
589 |
return $output;
|
590 |
}
|
591 |
|
@@ -662,6 +666,8 @@ class SucuriScanIntegrity
|
|
662 |
'^wp-content\/(themes|plugins)\/.+',
|
663 |
'^google[0-9a-z]{16}\.html$',
|
664 |
'^pinterest-[0-9a-z]{5}\.html$',
|
|
|
|
|
665 |
'\.ico$',
|
666 |
);
|
667 |
|
586 |
}
|
587 |
}
|
588 |
|
589 |
+
sort($output['added']);
|
590 |
+
sort($output['removed']);
|
591 |
+
sort($output['modified']);
|
592 |
+
|
593 |
return $output;
|
594 |
}
|
595 |
|
666 |
'^wp-content\/(themes|plugins)\/.+',
|
667 |
'^google[0-9a-z]{16}\.html$',
|
668 |
'^pinterest-[0-9a-z]{5}\.html$',
|
669 |
+
'^wp-content\/languages\/.+\.mo$',
|
670 |
+
'^wp-content\/languages\/.+\.po$',
|
671 |
'\.ico$',
|
672 |
);
|
673 |
|
src/interface.lib.php
CHANGED
@@ -67,7 +67,7 @@ class SucuriScanInterface
|
|
67 |
'sucuriscan1',
|
68 |
SUCURISCAN_URL . '/inc/css/styles.css',
|
69 |
array(/* empty */),
|
70 |
-
'
|
71 |
);
|
72 |
wp_enqueue_style('sucuriscan1');
|
73 |
|
@@ -75,7 +75,7 @@ class SucuriScanInterface
|
|
75 |
'sucuriscan1',
|
76 |
SUCURISCAN_URL . '/inc/js/scripts.js',
|
77 |
array(/* empty */),
|
78 |
-
'
|
79 |
);
|
80 |
wp_enqueue_script('sucuriscan1');
|
81 |
|
@@ -84,7 +84,7 @@ class SucuriScanInterface
|
|
84 |
'sucuriscan3',
|
85 |
SUCURISCAN_URL . '/inc/css/flags.min.css',
|
86 |
array(/* empty */),
|
87 |
-
|
88 |
);
|
89 |
wp_enqueue_style('sucuriscan3');
|
90 |
}
|
67 |
'sucuriscan1',
|
68 |
SUCURISCAN_URL . '/inc/css/styles.css',
|
69 |
array(/* empty */),
|
70 |
+
SucuriScan::fileVersion('inc/css/styles.css')
|
71 |
);
|
72 |
wp_enqueue_style('sucuriscan1');
|
73 |
|
75 |
'sucuriscan1',
|
76 |
SUCURISCAN_URL . '/inc/js/scripts.js',
|
77 |
array(/* empty */),
|
78 |
+
SucuriScan::fileVersion('inc/js/scripts.js')
|
79 |
);
|
80 |
wp_enqueue_script('sucuriscan1');
|
81 |
|
84 |
'sucuriscan3',
|
85 |
SUCURISCAN_URL . '/inc/css/flags.min.css',
|
86 |
array(/* empty */),
|
87 |
+
SucuriScan::fileVersion('inc/css/flags.min.css')
|
88 |
);
|
89 |
wp_enqueue_style('sucuriscan3');
|
90 |
}
|
src/lastlogins-failed.php
CHANGED
@@ -57,7 +57,6 @@ function sucuriscan_failed_logins_panel()
|
|
57 |
$max_failed_logins = SucuriScanOption::getOption(':maximum_failed_logins');
|
58 |
$notify_bruteforce_attack = SucuriScanOption::getOption(':notify_bruteforce_attack');
|
59 |
$failed_logins = sucuriscan_get_all_failed_logins($page_offset, $max_per_page);
|
60 |
-
$show_password = SucuriScanOption::isEnabled(':notify_failed_password');
|
61 |
|
62 |
if ($failed_logins) {
|
63 |
$counter = 0;
|
@@ -70,21 +69,6 @@ function sucuriscan_failed_logins_panel()
|
|
70 |
continue;
|
71 |
}
|
72 |
|
73 |
-
$wrong_user_password = 'hidden';
|
74 |
-
$wrong_user_password_color = 'default';
|
75 |
-
|
76 |
-
if (isset($login_data['user_password']) && !empty($login_data['user_password'])) {
|
77 |
-
$wrong_user_password = $login_data['user_password'];
|
78 |
-
$wrong_user_password_color = 'danger';
|
79 |
-
} else {
|
80 |
-
$wrong_user_password = 'empty';
|
81 |
-
$wrong_user_password_color = 'info';
|
82 |
-
}
|
83 |
-
|
84 |
-
if (!$show_password) {
|
85 |
-
$wrong_user_password = 'hidden';
|
86 |
-
}
|
87 |
-
|
88 |
$template_variables['FailedLogins.List'] .= SucuriScanTemplate::getSnippet(
|
89 |
'lastlogins-failedlogins',
|
90 |
array(
|
@@ -92,8 +76,6 @@ function sucuriscan_failed_logins_panel()
|
|
92 |
'FailedLogins.Username' => $login_data['user_login'],
|
93 |
'FailedLogins.RemoteAddr' => $login_data['remote_addr'],
|
94 |
'FailedLogins.UserAgent' => $login_data['user_agent'],
|
95 |
-
'FailedLogins.Password' => $wrong_user_password,
|
96 |
-
'FailedLogins.PasswordColor' => $wrong_user_password_color,
|
97 |
'FailedLogins.Datetime' => SucuriScan::datetime($login_data['attempt_time']),
|
98 |
)
|
99 |
);
|
@@ -314,11 +296,10 @@ function sucuriscan_get_failed_logins($get_old_logs = false, $offset = 0, $limit
|
|
314 |
* this entry will contain the username, timestamp of the login attempt, remote
|
315 |
* address of the computer sending the request, and the user-agent.
|
316 |
*
|
317 |
-
* @param string $user_login
|
318 |
-
* @
|
319 |
-
* @return bool Whether the information of the current failed login event was stored or not.
|
320 |
*/
|
321 |
-
function sucuriscan_log_failed_login($user_login = ''
|
322 |
{
|
323 |
$storage = sucuriscan_failed_logins_datastore_path();
|
324 |
|
@@ -329,7 +310,6 @@ function sucuriscan_log_failed_login($user_login = '', $wrong_password = '')
|
|
329 |
$login_data = json_encode(
|
330 |
array(
|
331 |
'user_login' => $user_login,
|
332 |
-
'user_password' => $wrong_password,
|
333 |
'attempt_time' => time(),
|
334 |
'remote_addr' => SucuriScan::getRemoteAddr(),
|
335 |
'user_agent' => SucuriScan::getUserAgent(),
|
57 |
$max_failed_logins = SucuriScanOption::getOption(':maximum_failed_logins');
|
58 |
$notify_bruteforce_attack = SucuriScanOption::getOption(':notify_bruteforce_attack');
|
59 |
$failed_logins = sucuriscan_get_all_failed_logins($page_offset, $max_per_page);
|
|
|
60 |
|
61 |
if ($failed_logins) {
|
62 |
$counter = 0;
|
69 |
continue;
|
70 |
}
|
71 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
72 |
$template_variables['FailedLogins.List'] .= SucuriScanTemplate::getSnippet(
|
73 |
'lastlogins-failedlogins',
|
74 |
array(
|
76 |
'FailedLogins.Username' => $login_data['user_login'],
|
77 |
'FailedLogins.RemoteAddr' => $login_data['remote_addr'],
|
78 |
'FailedLogins.UserAgent' => $login_data['user_agent'],
|
|
|
|
|
79 |
'FailedLogins.Datetime' => SucuriScan::datetime($login_data['attempt_time']),
|
80 |
)
|
81 |
);
|
296 |
* this entry will contain the username, timestamp of the login attempt, remote
|
297 |
* address of the computer sending the request, and the user-agent.
|
298 |
*
|
299 |
+
* @param string $user_login Information from the current failed login event.
|
300 |
+
* @return bool True if the information was saved, false otherwise.
|
|
|
301 |
*/
|
302 |
+
function sucuriscan_log_failed_login($user_login = '')
|
303 |
{
|
304 |
$storage = sucuriscan_failed_logins_datastore_path();
|
305 |
|
310 |
$login_data = json_encode(
|
311 |
array(
|
312 |
'user_login' => $user_login,
|
|
|
313 |
'attempt_time' => time(),
|
314 |
'remote_addr' => SucuriScan::getRemoteAddr(),
|
315 |
'user_agent' => SucuriScan::getUserAgent(),
|
src/mail.lib.php
CHANGED
@@ -204,6 +204,7 @@ class SucuriScanMail extends SucuriScanOption
|
|
204 |
$params['Subject'] = $subject;
|
205 |
$params['Website'] = $website;
|
206 |
$params['RemoteAddress'] = self::getRemoteAddr();
|
|
|
207 |
$params['Message'] = $message;
|
208 |
$params['User'] = $display_name;
|
209 |
$params['Time'] = SucuriScan::datetime();
|
204 |
$params['Subject'] = $subject;
|
205 |
$params['Website'] = $website;
|
206 |
$params['RemoteAddress'] = self::getRemoteAddr();
|
207 |
+
$params['ReverseAddress'] = gethostbyaddr($params['RemoteAddress']);
|
208 |
$params['Message'] = $message;
|
209 |
$params['User'] = $display_name;
|
210 |
$params['Time'] = SucuriScan::datetime();
|
src/option.lib.php
CHANGED
@@ -82,7 +82,6 @@ class SucuriScanOption extends SucuriScanRequest
|
|
82 |
'sucuriscan_notify_available_updates' => 'disabled',
|
83 |
'sucuriscan_notify_bruteforce_attack' => 'disabled',
|
84 |
'sucuriscan_notify_failed_login' => 'enabled',
|
85 |
-
'sucuriscan_notify_failed_password' => 'disabled',
|
86 |
'sucuriscan_notify_plugin_activated' => 'enabled',
|
87 |
'sucuriscan_notify_plugin_change' => 'enabled',
|
88 |
'sucuriscan_notify_plugin_deactivated' => 'disabled',
|
@@ -115,7 +114,7 @@ class SucuriScanOption extends SucuriScanRequest
|
|
115 |
'sucuriscan_use_wpmail' => 'enabled',
|
116 |
);
|
117 |
|
118 |
-
return $defaults;
|
119 |
}
|
120 |
|
121 |
/**
|
@@ -179,6 +178,12 @@ class SucuriScanOption extends SucuriScanRequest
|
|
179 |
*/
|
180 |
public static function getAllOptions()
|
181 |
{
|
|
|
|
|
|
|
|
|
|
|
|
|
182 |
$options = array();
|
183 |
$fpath = self::optionsFilePath();
|
184 |
|
@@ -198,6 +203,8 @@ class SucuriScanOption extends SucuriScanRequest
|
|
198 |
}
|
199 |
}
|
200 |
|
|
|
|
|
201 |
return $options;
|
202 |
}
|
203 |
|
@@ -209,6 +216,8 @@ class SucuriScanOption extends SucuriScanRequest
|
|
209 |
*/
|
210 |
public static function writeNewOptions($options = array())
|
211 |
{
|
|
|
|
|
212 |
$fpath = self::optionsFilePath();
|
213 |
$content = "<?php exit(0); ?>\n";
|
214 |
$content .= @json_encode($options) . "\n";
|
82 |
'sucuriscan_notify_available_updates' => 'disabled',
|
83 |
'sucuriscan_notify_bruteforce_attack' => 'disabled',
|
84 |
'sucuriscan_notify_failed_login' => 'enabled',
|
|
|
85 |
'sucuriscan_notify_plugin_activated' => 'enabled',
|
86 |
'sucuriscan_notify_plugin_change' => 'enabled',
|
87 |
'sucuriscan_notify_plugin_deactivated' => 'disabled',
|
114 |
'sucuriscan_use_wpmail' => 'enabled',
|
115 |
);
|
116 |
|
117 |
+
return (array) apply_filters('sucuriscan_option_defaults', $defaults);
|
118 |
}
|
119 |
|
120 |
/**
|
178 |
*/
|
179 |
public static function getAllOptions()
|
180 |
{
|
181 |
+
$options = wp_cache_get('alloptions', SUCURISCAN, WP_DEBUG);
|
182 |
+
|
183 |
+
if ($options && is_array($options)) {
|
184 |
+
return $options;
|
185 |
+
}
|
186 |
+
|
187 |
$options = array();
|
188 |
$fpath = self::optionsFilePath();
|
189 |
|
203 |
}
|
204 |
}
|
205 |
|
206 |
+
wp_cache_set('alloptions', $options, SUCURISCAN);
|
207 |
+
|
208 |
return $options;
|
209 |
}
|
210 |
|
216 |
*/
|
217 |
public static function writeNewOptions($options = array())
|
218 |
{
|
219 |
+
wp_cache_delete('alloptions', SUCURISCAN);
|
220 |
+
|
221 |
$fpath = self::optionsFilePath();
|
222 |
$content = "<?php exit(0); ?>\n";
|
223 |
$content .= @json_encode($options) . "\n";
|
src/settings-alerts.php
CHANGED
@@ -139,8 +139,8 @@ function sucuriscan_settings_alerts_trustedips()
|
|
139 |
if ($trust_ip) {
|
140 |
if (SucuriScan::isValidIP($trust_ip) || SucuriScan::isValidCIDR($trust_ip)) {
|
141 |
$ip_info = SucuriScan::getIPInfo($trust_ip);
|
142 |
-
$ip_info['added_at'] = time();
|
143 |
$cache_key = md5($ip_info['remote_addr']);
|
|
|
144 |
|
145 |
if ($cache->exists($cache_key)) {
|
146 |
SucuriScanInterface::error('The IP specified address was already added.');
|
@@ -405,7 +405,6 @@ function sucuriscan_settings_alerts_events($nonce)
|
|
405 |
'sucuriscan_notify_user_registration' => 'user:' . 'Receive email alerts for new user registration',
|
406 |
'sucuriscan_notify_success_login' => 'user:' . 'Receive email alerts for successful login attempts',
|
407 |
'sucuriscan_notify_failed_login' => 'user:' . 'Receive email alerts for failed login attempts <em>(you may receive tons of emails)</em>',
|
408 |
-
'sucuriscan_notify_failed_password' => 'user:' . 'Receive email alerts for failed login attempts including the submitted password',
|
409 |
'sucuriscan_notify_bruteforce_attack' => 'user:' . 'Receive email alerts for password guessing attacks <em>(summary of failed logins per hour)</em>',
|
410 |
'sucuriscan_notify_post_publication' => 'setting:' . 'Receive email alerts for changes in the post status <em>(configure from Ignore Posts Changes)</em>',
|
411 |
'sucuriscan_notify_website_updated' => 'setting:' . 'Receive email alerts when the WordPress version is updated',
|
@@ -441,7 +440,6 @@ function sucuriscan_settings_alerts_events($nonce)
|
|
441 |
$params['Alerts.NoAlertsVisibility'] = 'visible';
|
442 |
unset($notify_options['sucuriscan_notify_success_login']);
|
443 |
unset($notify_options['sucuriscan_notify_failed_login']);
|
444 |
-
unset($notify_options['sucuriscan_notify_failed_password']);
|
445 |
}
|
446 |
|
447 |
// Process form submission to change the alert settings.
|
@@ -450,11 +448,6 @@ function sucuriscan_settings_alerts_events($nonce)
|
|
450 |
if (SucuriScanRequest::post(':save_alert_events') !== false) {
|
451 |
$ucounter = 0;
|
452 |
|
453 |
-
/* disable password tracker for failed logins as well */
|
454 |
-
if (SucuriScanRequest::post(':notify_failed_login') === '0') {
|
455 |
-
$_POST['sucuriscan_notify_failed_password'] = '0';
|
456 |
-
}
|
457 |
-
|
458 |
foreach ($notify_options as $alert_type => $alert_label) {
|
459 |
$option_value = SucuriScanRequest::post($alert_type, '(1|0)');
|
460 |
|
@@ -545,7 +538,7 @@ function sucuriscan_settings_alerts_ignore_posts()
|
|
545 |
// Ignore a new event for email alerts.
|
546 |
$action = SucuriScanRequest::post(':ignorerule_action');
|
547 |
$ignore_rule = SucuriScanRequest::post(':ignorerule');
|
548 |
-
$
|
549 |
|
550 |
if ($action === 'add') {
|
551 |
if (!preg_match('/^[a-z_\-]+$/', $ignore_rule)) {
|
@@ -567,7 +560,7 @@ function sucuriscan_settings_alerts_ignore_posts()
|
|
567 |
$timestamp = time();
|
568 |
|
569 |
foreach ($post_types as $post_type) {
|
570 |
-
if (!in_array($post_type, $
|
571 |
$ignored_events[$post_type] = $timestamp;
|
572 |
}
|
573 |
}
|
139 |
if ($trust_ip) {
|
140 |
if (SucuriScan::isValidIP($trust_ip) || SucuriScan::isValidCIDR($trust_ip)) {
|
141 |
$ip_info = SucuriScan::getIPInfo($trust_ip);
|
|
|
142 |
$cache_key = md5($ip_info['remote_addr']);
|
143 |
+
$ip_info['added_at'] = time();
|
144 |
|
145 |
if ($cache->exists($cache_key)) {
|
146 |
SucuriScanInterface::error('The IP specified address was already added.');
|
405 |
'sucuriscan_notify_user_registration' => 'user:' . 'Receive email alerts for new user registration',
|
406 |
'sucuriscan_notify_success_login' => 'user:' . 'Receive email alerts for successful login attempts',
|
407 |
'sucuriscan_notify_failed_login' => 'user:' . 'Receive email alerts for failed login attempts <em>(you may receive tons of emails)</em>',
|
|
|
408 |
'sucuriscan_notify_bruteforce_attack' => 'user:' . 'Receive email alerts for password guessing attacks <em>(summary of failed logins per hour)</em>',
|
409 |
'sucuriscan_notify_post_publication' => 'setting:' . 'Receive email alerts for changes in the post status <em>(configure from Ignore Posts Changes)</em>',
|
410 |
'sucuriscan_notify_website_updated' => 'setting:' . 'Receive email alerts when the WordPress version is updated',
|
440 |
$params['Alerts.NoAlertsVisibility'] = 'visible';
|
441 |
unset($notify_options['sucuriscan_notify_success_login']);
|
442 |
unset($notify_options['sucuriscan_notify_failed_login']);
|
|
|
443 |
}
|
444 |
|
445 |
// Process form submission to change the alert settings.
|
448 |
if (SucuriScanRequest::post(':save_alert_events') !== false) {
|
449 |
$ucounter = 0;
|
450 |
|
|
|
|
|
|
|
|
|
|
|
451 |
foreach ($notify_options as $alert_type => $alert_label) {
|
452 |
$option_value = SucuriScanRequest::post($alert_type, '(1|0)');
|
453 |
|
538 |
// Ignore a new event for email alerts.
|
539 |
$action = SucuriScanRequest::post(':ignorerule_action');
|
540 |
$ignore_rule = SucuriScanRequest::post(':ignorerule');
|
541 |
+
$selected = SucuriScanRequest::post(':posttypes', '_array');
|
542 |
|
543 |
if ($action === 'add') {
|
544 |
if (!preg_match('/^[a-z_\-]+$/', $ignore_rule)) {
|
560 |
$timestamp = time();
|
561 |
|
562 |
foreach ($post_types as $post_type) {
|
563 |
+
if (is_array($selected) && !in_array($post_type, $selected)) {
|
564 |
$ignored_events[$post_type] = $timestamp;
|
565 |
}
|
566 |
}
|
src/settings-apiservice.php
CHANGED
@@ -39,6 +39,7 @@ function sucuriscan_settings_apiservice_status($nonce)
|
|
39 |
$params['ApiStatus.WarningVisibility'] = 'visible';
|
40 |
$params['ApiStatus.ErrorVisibility'] = 'hidden';
|
41 |
$params['ApiStatus.ServiceURL'] = SUCURISCAN_API_URL;
|
|
|
42 |
|
43 |
if ($nonce) {
|
44 |
// Enable or disable the API service communication.
|
@@ -66,6 +67,9 @@ function sucuriscan_settings_apiservice_status($nonce)
|
|
66 |
$params['ApiStatus.ErrorVisibility'] = 'visible';
|
67 |
}
|
68 |
|
|
|
|
|
|
|
69 |
return SucuriScanTemplate::getSection('settings-apiservice-status', $params);
|
70 |
}
|
71 |
|
39 |
$params['ApiStatus.WarningVisibility'] = 'visible';
|
40 |
$params['ApiStatus.ErrorVisibility'] = 'hidden';
|
41 |
$params['ApiStatus.ServiceURL'] = SUCURISCAN_API_URL;
|
42 |
+
$params['ApiStatus.ApiKey'] = '';
|
43 |
|
44 |
if ($nonce) {
|
45 |
// Enable or disable the API service communication.
|
67 |
$params['ApiStatus.ErrorVisibility'] = 'visible';
|
68 |
}
|
69 |
|
70 |
+
$api_key = SucuriScanAPI::getPluginKey();
|
71 |
+
$params['ApiStatus.ApiKey'] = $api_key ? $api_key : 'NONE';
|
72 |
+
|
73 |
return SucuriScanTemplate::getSection('settings-apiservice-status', $params);
|
74 |
}
|
75 |
|
src/settings-general.php
CHANGED
@@ -476,7 +476,6 @@ function sucuriscan_settings_general_importexport($nonce)
|
|
476 |
$params = array();
|
477 |
$allowed = array(
|
478 |
':addr_header',
|
479 |
-
':api_key',
|
480 |
':api_protocol',
|
481 |
':api_service',
|
482 |
':cloudproxy_apikey',
|
@@ -549,6 +548,26 @@ function sucuriscan_settings_general_importexport($nonce)
|
|
549 |
$count++;
|
550 |
}
|
551 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
552 |
SucuriScanInterface::info(
|
553 |
sprintf(
|
554 |
'%d out of %d option have been successfully imported',
|
@@ -569,6 +588,14 @@ function sucuriscan_settings_general_importexport($nonce)
|
|
569 |
$settings[$option_name] = SucuriScanOption::getOption($option);
|
570 |
}
|
571 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
572 |
$params['Export'] = @json_encode($settings);
|
573 |
|
574 |
return SucuriScanTemplate::getSection('settings-general-importexport', $params);
|
476 |
$params = array();
|
477 |
$allowed = array(
|
478 |
':addr_header',
|
|
|
479 |
':api_protocol',
|
480 |
':api_service',
|
481 |
':cloudproxy_apikey',
|
548 |
$count++;
|
549 |
}
|
550 |
|
551 |
+
/* import trusted ip addresses */
|
552 |
+
if (array_key_exists('trusted_ips', $data) && is_array($data)) {
|
553 |
+
$cache = new SucuriScanCache('trustip');
|
554 |
+
|
555 |
+
foreach ($data['trusted_ips'] as $trustedIP) {
|
556 |
+
$trustedIP = str_replace('\/', '/', $trustedIP);
|
557 |
+
$trustedIP = str_replace('/32', '', $trustedIP);
|
558 |
+
|
559 |
+
if (SucuriScan::isValidIP($trustedIP) || SucuriScan::isValidCIDR($trustedIP)) {
|
560 |
+
$ipInfo = SucuriScan::getIPInfo($trustedIP);
|
561 |
+
$cacheKey = md5($ipInfo['remote_addr']);
|
562 |
+
$ipInfo['added_at'] = time();
|
563 |
+
|
564 |
+
if (!$cache->exists($cacheKey)) {
|
565 |
+
$cache->add($cacheKey, $ipInfo);
|
566 |
+
}
|
567 |
+
}
|
568 |
+
}
|
569 |
+
}
|
570 |
+
|
571 |
SucuriScanInterface::info(
|
572 |
sprintf(
|
573 |
'%d out of %d option have been successfully imported',
|
588 |
$settings[$option_name] = SucuriScanOption::getOption($option);
|
589 |
}
|
590 |
|
591 |
+
/* include the trusted IP address list */
|
592 |
+
$settings['trusted_ips'] = array();
|
593 |
+
$cache = new SucuriScanCache('trustip');
|
594 |
+
$trusted = $cache->getAll();
|
595 |
+
foreach ($trusted as $trustedIP) {
|
596 |
+
$settings['trusted_ips'][] = $trustedIP->cidr_format;
|
597 |
+
}
|
598 |
+
|
599 |
$params['Export'] = @json_encode($settings);
|
600 |
|
601 |
return SucuriScanTemplate::getSection('settings-general-importexport', $params);
|
src/sucuriscan.lib.php
CHANGED
@@ -259,7 +259,10 @@ class SucuriScan
|
|
259 |
*/
|
260 |
public static function fixPath($path = '')
|
261 |
{
|
262 |
-
|
|
|
|
|
|
|
263 |
}
|
264 |
|
265 |
/**
|
@@ -770,15 +773,15 @@ class SucuriScan
|
|
770 |
*/
|
771 |
public static function isValidCIDR($remote_addr = '')
|
772 |
{
|
773 |
-
$
|
|
|
|
|
774 |
|
775 |
if (preg_match('/^([0-9\.]{7,15})\/(8|16|24)$/', $remote_addr, $match)) {
|
776 |
-
|
777 |
-
$status = true;
|
778 |
-
}
|
779 |
}
|
780 |
|
781 |
-
return
|
782 |
}
|
783 |
|
784 |
/**
|
@@ -906,4 +909,15 @@ class SucuriScan
|
|
906 |
{
|
907 |
return (bool) (stripos(@$_SERVER['SERVER_SOFTWARE'], 'Microsoft-IIS') !== false);
|
908 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
909 |
}
|
259 |
*/
|
260 |
public static function fixPath($path = '')
|
261 |
{
|
262 |
+
$new = str_replace(DIRECTORY_SEPARATOR, '/', $path);
|
263 |
+
$new = rtrim($new, '/'); /* purge right side. */
|
264 |
+
|
265 |
+
return empty($new) ? '/' : $new;
|
266 |
}
|
267 |
|
268 |
/**
|
773 |
*/
|
774 |
public static function isValidCIDR($remote_addr = '')
|
775 |
{
|
776 |
+
if (!is_string($remote_addr)) {
|
777 |
+
return false;
|
778 |
+
}
|
779 |
|
780 |
if (preg_match('/^([0-9\.]{7,15})\/(8|16|24)$/', $remote_addr, $match)) {
|
781 |
+
return self::isValidIP($match[1]);
|
|
|
|
|
782 |
}
|
783 |
|
784 |
+
return false;
|
785 |
}
|
786 |
|
787 |
/**
|
909 |
{
|
910 |
return (bool) (stripos(@$_SERVER['SERVER_SOFTWARE'], 'Microsoft-IIS') !== false);
|
911 |
}
|
912 |
+
|
913 |
+
/**
|
914 |
+
* Returns the md5 hash representing the content of a file.
|
915 |
+
*
|
916 |
+
* @param string $file Relative path to the file.
|
917 |
+
* @return string Seven first characters in the hash of the file.
|
918 |
+
*/
|
919 |
+
public static function fileVersion($file = '')
|
920 |
+
{
|
921 |
+
return substr(md5_file(SUCURISCAN_PLUGIN_PATH . '/' . $file), 0, 7);
|
922 |
+
}
|
923 |
}
|
sucuri.php
CHANGED
@@ -6,7 +6,7 @@
|
|
6 |
* Plugin URI: https://wordpress.sucuri.net/
|
7 |
* Author URI: https://sucuri.net/
|
8 |
* Author: Sucuri Inc.
|
9 |
-
* Version: 1.8.
|
10 |
*
|
11 |
* PHP version 5
|
12 |
*
|
@@ -83,7 +83,7 @@ define('SUCURISCAN', 'sucuriscan');
|
|
83 |
/**
|
84 |
* Current version of the plugin's code.
|
85 |
*/
|
86 |
-
define('SUCURISCAN_VERSION', '1.8.
|
87 |
|
88 |
/**
|
89 |
* The name of the folder where the plugin's files will be located.
|
@@ -232,6 +232,11 @@ require_once 'src/settings-webinfo.php';
|
|
232 |
/* Load global variables and triggers */
|
233 |
require_once 'src/globals.php';
|
234 |
|
|
|
|
|
|
|
|
|
|
|
235 |
/**
|
236 |
* Uninstalls the plugin, its settings and reverts the hardening.
|
237 |
*
|
6 |
* Plugin URI: https://wordpress.sucuri.net/
|
7 |
* Author URI: https://sucuri.net/
|
8 |
* Author: Sucuri Inc.
|
9 |
+
* Version: 1.8.12
|
10 |
*
|
11 |
* PHP version 5
|
12 |
*
|
83 |
/**
|
84 |
* Current version of the plugin's code.
|
85 |
*/
|
86 |
+
define('SUCURISCAN_VERSION', '1.8.12');
|
87 |
|
88 |
/**
|
89 |
* The name of the folder where the plugin's files will be located.
|
232 |
/* Load global variables and triggers */
|
233 |
require_once 'src/globals.php';
|
234 |
|
235 |
+
/* Load WP-CLI command */
|
236 |
+
if (defined('WP_CLI') && WP_CLI) {
|
237 |
+
include_once 'src/cli.lib.php';
|
238 |
+
}
|
239 |
+
|
240 |
/**
|
241 |
* Uninstalls the plugin, its settings and reverts the hardening.
|
242 |
*
|