PluginProbe
Defender Security – Malware Scanner, Login Security & Firewall / 6.2.2
Defender Security – Malware Scanner, Login Security & Firewall v6.2.2
6.3.0 6.2.3 6.2.4 6.2.0 6.2.1 6.2.2 6.1.0 5.3.1 5.4.0 5.4.1 5.5.0 5.5.1 5.6.0 5.6.1 5.6.2 5.7.0 5.7.1 5.7.2 5.8.0 5.8.1 5.9.0 6.0.0 6.0.1 3.0.1 3.1.0 All 141 releases
defender-security / src / component / security-tweaks / servers / class-iis-7.php

class-iis-7.php in Defender Security – Malware Scanner, Login Security & Firewall 6.2.2, at src/component/security-tweaks/servers/class-iis-7.php

197 lines 5.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Responsible for managing server configurations related to security tweaks .
4 *
5 * @package WP_Defender\Component\Security_Tweaks\Servers
6 */
7
8 namespace WP_Defender\Component\Security_Tweaks\Servers;
9
10 use WP_Error;
11 use DOMXPath;
12 use DOMDocument;
13 use DOMException;
14 use WP_Filesystem_Base;
15
16 /**
17 * Provides methods to apply and revert security rules on servers.
18 */
19 class IIS_7 {
20
21 /**
22 * New htaccess file.
23 *
24 * @var array
25 */
26 private $new_htaccess_config = array();
27
28 /**
29 * Service type.
30 *
31 * @var string
32 */
33 private $type = null;
34
35 /**
36 * Constructor for class.
37 *
38 * @param string $type The type of the security tweak.
39 */
40 public function __construct( $type ) {
41 $this->type = $type;
42 }
43
44 /**
45 * Check whether the issue has been resolved or not.
46 *
47 * @return bool
48 */
49 public function check() {
50 $url = '';
51
52 if ( 'prevent-php-executed' === $this->type ) {
53 $dir = wp_upload_dir();
54 $url = $dir['baseurl'] . '/wp-defender/index.php';
55 }
56
57 if ( 'protect-information' === $this->type ) {
58 $url = defender_asset_url( '/languages/' . WP_DEFENDER_POT_FILENAME );
59 }
60
61 return Server::ping_test_failed( $url );
62 }
63
64 /**
65 * Process the rule.
66 *
67 * @return bool|WP_Error
68 * @throws DOMException If invalid $localName.
69 */
70 public function process() {
71 global $wp_filesystem;
72 // Initialize the WP filesystem, no more using 'file-put-contents' function.
73 if ( ! $wp_filesystem instanceof WP_Filesystem_Base ) {
74 require_once ABSPATH . '/wp-admin/includes/file.php';
75 WP_Filesystem();
76 }
77 $path = WP_CONTENT_DIR . '/uploads';
78 $filename = 'web.config';
79 if ( ! file_exists( $path . '/' . $filename ) ) {
80 $wp_filesystem->put_contents( $path . '/' . $filename, '<configuration/>' );
81 }
82 $formatxml = PHP_EOL;
83 $formatxml .= ' <handlers accessPolicy="Read" />';
84 $formatxml .= PHP_EOL;
85
86 $doc = new DOMDocument();
87 // This property is belongs to DOMDocument. So we can ignore the warning.
88 $doc->preserveWhiteSpace = true; // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
89
90 if ( $doc->load( $path . '/' . $filename ) === false ) {
91 return new WP_Error(
92 'defender_file_not_editable',
93 sprintf(
94 /* translators: %s: File name. */
95 esc_html__( 'The file %s could not be loaded.', 'defender-security' ),
96 $filename
97 )
98 );
99 }
100
101 $xpath = new DOMXPath( $doc );
102 $read_accesspolicy = $xpath->query( '/configuration/system.webServer/handlers[starts-with(@accessPolicy,\'Read\')]' );
103
104 if ( $read_accesspolicy->length > 0 ) {
105 return true;
106 }
107
108 $xmlnodes = $xpath->query( '/configuration/system.webServer/handlers' );
109
110 if ( $xmlnodes->length > 0 ) {
111 $handlers_node = $xmlnodes->item( 0 );
112 } else {
113 $handlers_node = $doc->createElement( 'handlers' );
114 $xmlnodes = $xpath->query( '/configuration/system.webServer' );
115
116 if ( $xmlnodes->length > 0 ) {
117 $system_web_server_node = $xmlnodes->item( 0 );
118 $handler_fragment = $doc->createDocumentFragment();
119 $handler_fragment->appendXML( $formatxml );
120 $system_web_server_node->appendChild( $handler_fragment );
121 } else {
122 $system_web_server_node = $doc->createElement( 'system.webServer' );
123 $handler_fragment = $doc->createDocumentFragment();
124 $handler_fragment->appendXML( $formatxml );
125 $system_web_server_node->appendChild( $handler_fragment );
126 $xmlnodes = $xpath->query( '/configuration' );
127
128 if ( $xmlnodes->length > 0 ) {
129 $config_node = $xmlnodes->item( 0 );
130 $config_node->appendChild( $system_web_server_node );
131 } else {
132 $config_node = $doc->createElement( 'configuration' );
133 $doc->appendChild( $config_node );
134 $config_node->appendChild( $system_web_server_node );
135 }
136 }
137 }
138
139 $rule_fragment = $doc->createDocumentFragment();
140 $rule_fragment->appendXML( $formatxml );
141 $handlers_node->appendChild( $rule_fragment );
142
143 $doc->encoding = 'UTF-8';
144 $doc->formatOutput = true; // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
145 saveDomDocument( $doc, $path . '/' . $filename );
146
147 $settings = array(
148 'new_htaccess_config' => $this->get_new_htaccess_config(),
149 );
150
151 return update_site_option( "defender_security_tweeks_{$this->type}", $settings );
152 }
153
154 /**
155 * Revert the rule.
156 *
157 * @return bool
158 */
159 public function revert() {
160 $path = WP_CONTENT_DIR . '/uploads';
161 $filename = 'web.config';
162
163 if ( ! file_exists( $path . '/' . $filename ) ) {
164 return true;
165 }
166
167 $doc = new DOMDocument();
168 $doc->preserveWhiteSpace = false; // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
169
170 if ( $doc->load( $path . '/' . $filename ) === false ) {
171 return false;
172 }
173
174 $xpath = new DOMXPath( $doc );
175 $handlers = $xpath->query( '/configuration/system.webServer/handlers[contains(@accessPolicy,\'Read\')]' );
176
177 if ( $handlers->length > 0 ) {
178 $child = $handlers->item( 0 );
179 $parent = $child->parentNode; // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
180 $parent->removeChild( $child );
181 $doc->formatOutput = true; // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
182 saveDomDocument( $doc, $path . '/' . $filename );
183 }
184
185 return true;
186 }
187
188 /**
189 * Get the new HT config.
190 *
191 * @return array
192 */
193 public function get_new_htaccess_config() {
194 return $this->new_htaccess_config;
195 }
196 }
197