Version Description
Download this release
Release Info
Developer | paultgoodchild |
Plugin | Shield Security for WordPress |
Version | 12.0.9 |
Comparing to | |
See all releases |
Code changes from version 12.0.8 to 12.0.9
- cl.json +12 -0
- icwp-wpsf.php +1 -1
- plugin-spec.php +3 -3
- plugin.json +3 -3
- readme.txt +1 -1
- src/lib/src/Controller/Controller.php +1 -1
- src/lib/src/Modules/Firewall/Lib/Scan/ParametersToScan.php +12 -3
- src/lib/src/Modules/HackGuard/Lib/Snapshots/StoreAction/ScheduleBuildAll.php +3 -3
- src/lib/src/Modules/LoginGuard/Lib/TwoFactor/Provider/Yubikey.php +2 -1
- src/lib/src/Modules/Plugin/Lib/Debug/Collate.php +9 -8
- src/lib/vendor/fernleafsystems/wordpress-plugin-core/src/Databases/Base/Select.php +1 -1
- src/lib/vendor/fernleafsystems/wordpress-services/src/Core/Db.php +1 -1
- src/lib/vendor/fernleafsystems/wordpress-services/src/Core/Request.php +16 -2
- src/lib/vendor/ramsey/uuid/src/Uuid.php +29 -0
cl.json
CHANGED
@@ -134,6 +134,18 @@
|
|
134 |
"title": "Ensure Shield runs only on supported MySQL servers.",
|
135 |
"description": [],
|
136 |
"patch": "12.0.8"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
137 |
}
|
138 |
]
|
139 |
},
|
134 |
"title": "Ensure Shield runs only on supported MySQL servers.",
|
135 |
"description": [],
|
136 |
"patch": "12.0.8"
|
137 |
+
},
|
138 |
+
{
|
139 |
+
"type": "fixed",
|
140 |
+
"title": "Error when processing certain types of query strings in the firewall.",
|
141 |
+
"description": [],
|
142 |
+
"patch": "12.0.9"
|
143 |
+
},
|
144 |
+
{
|
145 |
+
"type": "fixed",
|
146 |
+
"title": "Yubikey 2FA verification was failing with a nonce less than 16 characters. Who knew?",
|
147 |
+
"description": [],
|
148 |
+
"patch": "12.0.9"
|
149 |
}
|
150 |
]
|
151 |
},
|
icwp-wpsf.php
CHANGED
@@ -3,7 +3,7 @@
|
|
3 |
* Plugin Name: Shield Security
|
4 |
* Plugin URI: https://shsec.io/2f
|
5 |
* Description: Powerful, Easy-To-Use #1 Rated WordPress Security System
|
6 |
-
* Version: 12.0.
|
7 |
* Text Domain: wp-simple-firewall
|
8 |
* Domain Path: /languages
|
9 |
* Author: Shield Security
|
3 |
* Plugin Name: Shield Security
|
4 |
* Plugin URI: https://shsec.io/2f
|
5 |
* Description: Powerful, Easy-To-Use #1 Rated WordPress Security System
|
6 |
+
* Version: 12.0.9
|
7 |
* Text Domain: wp-simple-firewall
|
8 |
* Domain Path: /languages
|
9 |
* Author: Shield Security
|
plugin-spec.php
CHANGED
@@ -1,8 +1,8 @@
|
|
1 |
{
|
2 |
"properties": {
|
3 |
-
"version": "12.0.
|
4 |
-
"release_timestamp":
|
5 |
-
"build": "202109.
|
6 |
"slug_parent": "icwp",
|
7 |
"slug_plugin": "wpsf",
|
8 |
"human_name": "Shield Security",
|
1 |
{
|
2 |
"properties": {
|
3 |
+
"version": "12.0.9",
|
4 |
+
"release_timestamp": 1632903440,
|
5 |
+
"build": "202109.2901",
|
6 |
"slug_parent": "icwp",
|
7 |
"slug_plugin": "wpsf",
|
8 |
"human_name": "Shield Security",
|
plugin.json
CHANGED
@@ -1,8 +1,8 @@
|
|
1 |
{
|
2 |
"properties": {
|
3 |
-
"version": "12.0.
|
4 |
-
"release_timestamp":
|
5 |
-
"build": "202109.
|
6 |
"slug_parent": "icwp",
|
7 |
"slug_plugin": "wpsf",
|
8 |
"human_name": "Shield Security",
|
1 |
{
|
2 |
"properties": {
|
3 |
+
"version": "12.0.9",
|
4 |
+
"release_timestamp": 1632903440,
|
5 |
+
"build": "202109.2901",
|
6 |
"slug_parent": "icwp",
|
7 |
"slug_plugin": "wpsf",
|
8 |
"human_name": "Shield Security",
|
readme.txt
CHANGED
@@ -8,7 +8,7 @@ Requires at least: 3.7
|
|
8 |
Requires PHP: 7.0
|
9 |
Recommended PHP: 7.4
|
10 |
Tested up to: 5.8
|
11 |
-
Stable tag: 12.0.
|
12 |
|
13 |
No-Nonsense Security Hardening that protects WordPress against hackers, malicious bots, and spammers (no captchas!). Now with exclusive ShieldNET Technology.
|
14 |
|
8 |
Requires PHP: 7.0
|
9 |
Recommended PHP: 7.4
|
10 |
Tested up to: 5.8
|
11 |
+
Stable tag: 12.0.9
|
12 |
|
13 |
No-Nonsense Security Hardening that protects WordPress against hackers, malicious bots, and spammers (no captchas!). Now with exclusive ShieldNET Technology.
|
14 |
|
src/lib/src/Controller/Controller.php
CHANGED
@@ -224,7 +224,7 @@ class Controller extends DynPropertiesClass {
|
|
224 |
$mysql = $this->cfg->requirements[ 'mysql' ];
|
225 |
if ( !empty( $mysql ) && !$this->isMysqlVersionSupported( $mysql ) ) {
|
226 |
$reqsMsg[] = sprintf( "Your MySQL database server doesn't support IPv6 addresses. Your Version: %s; Required MySQL Version: %s;",
|
227 |
-
Services::WpDb()->
|
228 |
}
|
229 |
|
230 |
if ( !empty( $reqsMsg ) ) {
|
224 |
$mysql = $this->cfg->requirements[ 'mysql' ];
|
225 |
if ( !empty( $mysql ) && !$this->isMysqlVersionSupported( $mysql ) ) {
|
226 |
$reqsMsg[] = sprintf( "Your MySQL database server doesn't support IPv6 addresses. Your Version: %s; Required MySQL Version: %s;",
|
227 |
+
Services::WpDb()->getMysqlServerInfo(), $mysql );
|
228 |
}
|
229 |
|
230 |
if ( !empty( $reqsMsg ) ) {
|
src/lib/src/Modules/Firewall/Lib/Scan/ParametersToScan.php
CHANGED
@@ -31,6 +31,12 @@ class ParametersToScan {
|
|
31 |
if ( !empty( self::$params ) ) {
|
32 |
$this->removeAllPageParams();
|
33 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
34 |
}
|
35 |
|
36 |
return self::$params;
|
@@ -40,9 +46,12 @@ class ParametersToScan {
|
|
40 |
foreach ( $this->getAllPageWhitelistedParameters() as $listParam ) {
|
41 |
|
42 |
if ( preg_match( '#^/.+/$#', $listParam ) ) {
|
43 |
-
foreach ( array_keys( self::$params ) as $
|
44 |
-
|
45 |
-
|
|
|
|
|
|
|
46 |
}
|
47 |
}
|
48 |
}
|
31 |
if ( !empty( self::$params ) ) {
|
32 |
$this->removeAllPageParams();
|
33 |
}
|
34 |
+
|
35 |
+
foreach ( self::$params as $key => $param ) {
|
36 |
+
if ( $param === '' ) {
|
37 |
+
unset( self::$params[ $key ] );
|
38 |
+
}
|
39 |
+
}
|
40 |
}
|
41 |
|
42 |
return self::$params;
|
46 |
foreach ( $this->getAllPageWhitelistedParameters() as $listParam ) {
|
47 |
|
48 |
if ( preg_match( '#^/.+/$#', $listParam ) ) {
|
49 |
+
foreach ( array_keys( self::$params ) as $paramKey ) {
|
50 |
+
|
51 |
+
// Turns out you can have numeric parameter keys in query:
|
52 |
+
// e.g. ?asdf=123&456&
|
53 |
+
if ( preg_match( $listParam, (string)$paramKey ) ) {
|
54 |
+
unset( self::$params[ $paramKey ] );
|
55 |
}
|
56 |
}
|
57 |
}
|
src/lib/src/Modules/HackGuard/Lib/Snapshots/StoreAction/ScheduleBuildAll.php
CHANGED
@@ -33,9 +33,9 @@ class ScheduleBuildAll extends BaseBulk {
|
|
33 |
if ( empty( $meta[ 'cs_hashes_at' ] ) ) {
|
34 |
$meta[ 'cs_hashes_at' ] = Services::Request()->ts();
|
35 |
if ( $store->setSnapMeta( $meta )->saveMeta() ) {
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
}
|
40 |
}
|
41 |
}
|
33 |
if ( empty( $meta[ 'cs_hashes_at' ] ) ) {
|
34 |
$meta[ 'cs_hashes_at' ] = Services::Request()->ts();
|
35 |
if ( $store->setSnapMeta( $meta )->saveMeta() ) {
|
36 |
+
( new SubmitHashes() )
|
37 |
+
->setMod( $this->getMod() )
|
38 |
+
->run( $asset );
|
39 |
}
|
40 |
}
|
41 |
}
|
src/lib/src/Modules/LoginGuard/Lib/TwoFactor/Provider/Yubikey.php
CHANGED
@@ -142,9 +142,10 @@ class Yubikey extends BaseProvider {
|
|
142 |
$success = false;
|
143 |
|
144 |
if ( preg_match( '#^[a-z]{44}$#', $otp ) ) {
|
|
|
145 |
$parts = [
|
146 |
'otp' => $otp,
|
147 |
-
'nonce' =>
|
148 |
'id' => $opts->getYubikeyAppId()
|
149 |
];
|
150 |
|
142 |
$success = false;
|
143 |
|
144 |
if ( preg_match( '#^[a-z]{44}$#', $otp ) ) {
|
145 |
+
// 2021-09-27: API requires at least 16 chars in the nonce, or it fails.
|
146 |
$parts = [
|
147 |
'otp' => $otp,
|
148 |
+
'nonce' => md5( uniqid( Services::Request()->getID() ) ),
|
149 |
'id' => $opts->getYubikeyAppId()
|
150 |
];
|
151 |
|
src/lib/src/Modules/Plugin/Lib/Debug/Collate.php
CHANGED
@@ -74,15 +74,15 @@ class Collate {
|
|
74 |
'Server Hostname' => gethostname(),
|
75 |
'Server Time Difference' => $diff,
|
76 |
'Server IPs' => implode( ', ', $aIPs ),
|
77 |
-
'CloudFlare' => empty( $req->server( 'HTTP_CF_REQUEST_ID' ) ) ? 'No' : 'Yes',
|
78 |
'rDNS' => empty( $rDNS ) ? '-' : $rDNS,
|
79 |
'Server Name' => $req->server( 'SERVER_NAME' ),
|
80 |
'Server Signature' => empty( $sig ) ? '-' : $sig,
|
81 |
'Server Software' => empty( $soft ) ? '-' : $soft,
|
82 |
-
'Disk Space (Used/Available/Total)' => sprintf( '%s
|
83 |
FormatBytes::Format( $totalDisk - $freeDisk, 2, '' ),
|
84 |
-
FormatBytes::Format( $
|
85 |
-
FormatBytes::Format( $
|
86 |
)
|
87 |
];
|
88 |
}
|
@@ -102,7 +102,7 @@ class Collate {
|
|
102 |
$root = $req->server( 'DOCUMENT_ROOT' );
|
103 |
return [
|
104 |
'PHP' => $phpV,
|
105 |
-
'MySQL' => Services::WpDb()->
|
106 |
'Memory Limit' => sprintf( '%s (Constant <code>WP_MEMORY_LIMIT: %s</code>)', ini_get( 'memory_limit' ),
|
107 |
defined( 'WP_MEMORY_LIMIT' ) ? WP_MEMORY_LIMIT : 'not defined' ),
|
108 |
'32/64-bit' => ( PHP_INT_SIZE === 4 ) ? 32 : 64,
|
@@ -278,9 +278,10 @@ class Collate {
|
|
278 |
'ABSPATH' => ABSPATH,
|
279 |
'Debug Is On' => $WP->isDebug() ? 'Yes' : 'No',
|
280 |
'Database' => [
|
281 |
-
sprintf( '
|
282 |
-
sprintf( '
|
283 |
-
sprintf( '
|
|
|
284 |
],
|
285 |
];
|
286 |
if ( $WP->isClassicPress() ) {
|
74 |
'Server Hostname' => gethostname(),
|
75 |
'Server Time Difference' => $diff,
|
76 |
'Server IPs' => implode( ', ', $aIPs ),
|
77 |
+
'CloudFlare' => !empty( $req->server( 'HTTP_CF_REQUEST_ID' ) ) ? 'No' : 'Yes',
|
78 |
'rDNS' => empty( $rDNS ) ? '-' : $rDNS,
|
79 |
'Server Name' => $req->server( 'SERVER_NAME' ),
|
80 |
'Server Signature' => empty( $sig ) ? '-' : $sig,
|
81 |
'Server Software' => empty( $soft ) ? '-' : $soft,
|
82 |
+
'Disk Space (Used/Available/Total)' => sprintf( '%s used out of %s (%s free)',
|
83 |
FormatBytes::Format( $totalDisk - $freeDisk, 2, '' ),
|
84 |
+
FormatBytes::Format( $totalDisk, 2, '' ),
|
85 |
+
FormatBytes::Format( $freeDisk, 2, '' )
|
86 |
)
|
87 |
];
|
88 |
}
|
102 |
$root = $req->server( 'DOCUMENT_ROOT' );
|
103 |
return [
|
104 |
'PHP' => $phpV,
|
105 |
+
'MySQL' => Services::WpDb()->getMysqlServerInfo(),
|
106 |
'Memory Limit' => sprintf( '%s (Constant <code>WP_MEMORY_LIMIT: %s</code>)', ini_get( 'memory_limit' ),
|
107 |
defined( 'WP_MEMORY_LIMIT' ) ? WP_MEMORY_LIMIT : 'not defined' ),
|
108 |
'32/64-bit' => ( PHP_INT_SIZE === 4 ) ? 32 : 64,
|
278 |
'ABSPATH' => ABSPATH,
|
279 |
'Debug Is On' => $WP->isDebug() ? 'Yes' : 'No',
|
280 |
'Database' => [
|
281 |
+
sprintf( 'Host: <code>%s</code>', DB_HOST ),
|
282 |
+
sprintf( 'Name: <code>%s</code>', DB_NAME ),
|
283 |
+
sprintf( 'User: <code>%s</code>', DB_USER ),
|
284 |
+
sprintf( 'Prefix: <code>%s</code>', Services::WpDb()->getPrefix() ),
|
285 |
],
|
286 |
];
|
287 |
if ( $WP->isClassicPress() ) {
|
src/lib/vendor/fernleafsystems/wordpress-plugin-core/src/Databases/Base/Select.php
CHANGED
@@ -48,7 +48,7 @@ class Select extends BaseQuery {
|
|
48 |
|
49 |
/**
|
50 |
* @param int $ID
|
51 |
-
* @return \stdClass
|
52 |
*/
|
53 |
public function byId( $ID ) {
|
54 |
$items = $this->reset()
|
48 |
|
49 |
/**
|
50 |
* @param int $ID
|
51 |
+
* @return \stdClass|mixed
|
52 |
*/
|
53 |
public function byId( $ID ) {
|
54 |
$items = $this->reset()
|
src/lib/vendor/fernleafsystems/wordpress-services/src/Core/Db.php
CHANGED
@@ -126,7 +126,7 @@ class Db {
|
|
126 |
public function getMysqlServerInfo() :string {
|
127 |
$db = $this->loadWpdb();
|
128 |
$info = method_exists( $db, 'db_server_info' ) ?
|
129 |
-
$db->db_server_info() : mysqli_get_server_info( $db->dbh );
|
130 |
return (string)$info;
|
131 |
}
|
132 |
|
126 |
public function getMysqlServerInfo() :string {
|
127 |
$db = $this->loadWpdb();
|
128 |
$info = method_exists( $db, 'db_server_info' ) ?
|
129 |
+
$db->db_server_info() : \mysqli_get_server_info( $db->dbh );
|
130 |
return (string)$info;
|
131 |
}
|
132 |
|
src/lib/vendor/fernleafsystems/wordpress-services/src/Core/Request.php
CHANGED
@@ -126,9 +126,23 @@ class Request extends DynPropertiesClass {
|
|
126 |
return $carbon;
|
127 |
}
|
128 |
|
|
|
|
|
|
|
|
|
129 |
public function getRawRequestParams( bool $includeCookies = true ) :array {
|
130 |
-
$params =
|
131 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
132 |
}
|
133 |
|
134 |
public function getHost() :string {
|
126 |
return $carbon;
|
127 |
}
|
128 |
|
129 |
+
/**
|
130 |
+
* Can't use array_merge as we can't be sure as some keys may be numeric.
|
131 |
+
* TODO: test to find the optimal approach for combining these arrays.
|
132 |
+
*/
|
133 |
public function getRawRequestParams( bool $includeCookies = true ) :array {
|
134 |
+
$params = [];
|
135 |
+
|
136 |
+
$toGather = [ $this->query, $this->post ];
|
137 |
+
if ( $includeCookies ) {
|
138 |
+
$toGather[] = $this->cookie_copy;
|
139 |
+
}
|
140 |
+
foreach ( $toGather as $bag ) {
|
141 |
+
foreach ( $bag as $key => $value ) {
|
142 |
+
$params[ $key ] = $value;
|
143 |
+
}
|
144 |
+
}
|
145 |
+
return $params;
|
146 |
}
|
147 |
|
148 |
public function getHost() :string {
|
src/lib/vendor/ramsey/uuid/src/Uuid.php
CHANGED
@@ -22,6 +22,7 @@ use Ramsey\Uuid\Codec\CodecInterface;
|
|
22 |
use Ramsey\Uuid\Exception\InvalidUuidStringException;
|
23 |
use Ramsey\Uuid\Exception\UnsatisfiedDependencyException;
|
24 |
use Ramsey\Uuid\Exception\UnsupportedOperationException;
|
|
|
25 |
|
26 |
/**
|
27 |
* Represents a universally unique identifier (UUID), according to RFC 4122.
|
@@ -224,11 +225,21 @@ class Uuid implements UuidInterface
|
|
224 |
* @return string
|
225 |
* @link http://php.net/manual/en/class.serializable.php
|
226 |
*/
|
|
|
227 |
public function serialize()
|
228 |
{
|
229 |
return $this->toString();
|
230 |
}
|
231 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
232 |
/**
|
233 |
* Re-constructs the object from its serialized form.
|
234 |
*
|
@@ -236,6 +247,7 @@ class Uuid implements UuidInterface
|
|
236 |
* @link http://php.net/manual/en/class.serializable.php
|
237 |
* @throws InvalidUuidStringException
|
238 |
*/
|
|
|
239 |
public function unserialize($serialized)
|
240 |
{
|
241 |
$uuid = self::fromString($serialized);
|
@@ -244,6 +256,23 @@ class Uuid implements UuidInterface
|
|
244 |
$this->fields = $uuid->fields;
|
245 |
}
|
246 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
247 |
public function compareTo(UuidInterface $other)
|
248 |
{
|
249 |
if ($this->getMostSignificantBitsHex() < $other->getMostSignificantBitsHex()) {
|
22 |
use Ramsey\Uuid\Exception\InvalidUuidStringException;
|
23 |
use Ramsey\Uuid\Exception\UnsatisfiedDependencyException;
|
24 |
use Ramsey\Uuid\Exception\UnsupportedOperationException;
|
25 |
+
use ReturnTypeWillChange;
|
26 |
|
27 |
/**
|
28 |
* Represents a universally unique identifier (UUID), according to RFC 4122.
|
225 |
* @return string
|
226 |
* @link http://php.net/manual/en/class.serializable.php
|
227 |
*/
|
228 |
+
#[ReturnTypeWillChange]
|
229 |
public function serialize()
|
230 |
{
|
231 |
return $this->toString();
|
232 |
}
|
233 |
|
234 |
+
/**
|
235 |
+
* @return array{string: string}
|
236 |
+
*/
|
237 |
+
#[ReturnTypeWillChange]
|
238 |
+
public function __serialize()
|
239 |
+
{
|
240 |
+
return ['string' => $this->toString()];
|
241 |
+
}
|
242 |
+
|
243 |
/**
|
244 |
* Re-constructs the object from its serialized form.
|
245 |
*
|
247 |
* @link http://php.net/manual/en/class.serializable.php
|
248 |
* @throws InvalidUuidStringException
|
249 |
*/
|
250 |
+
#[ReturnTypeWillChange]
|
251 |
public function unserialize($serialized)
|
252 |
{
|
253 |
$uuid = self::fromString($serialized);
|
256 |
$this->fields = $uuid->fields;
|
257 |
}
|
258 |
|
259 |
+
/**
|
260 |
+
* @param array{string: string} $serialized
|
261 |
+
* @return void
|
262 |
+
* @throws InvalidUuidStringException
|
263 |
+
*/
|
264 |
+
#[ReturnTypeWillChange]
|
265 |
+
public function __unserialize(array $serialized)
|
266 |
+
{
|
267 |
+
// @codeCoverageIgnoreStart
|
268 |
+
if (!isset($serialized['string'])) {
|
269 |
+
throw new InvalidUuidStringException();
|
270 |
+
}
|
271 |
+
// @codeCoverageIgnoreEnd
|
272 |
+
|
273 |
+
$this->unserialize($serialized['string']);
|
274 |
+
}
|
275 |
+
|
276 |
public function compareTo(UuidInterface $other)
|
277 |
{
|
278 |
if ($this->getMostSignificantBitsHex() < $other->getMostSignificantBitsHex()) {
|