PluginProbe
Defender Security – Malware Scanner, Login Security & Firewall / trunk
Defender Security – Malware Scanner, Login Security & Firewall vtrunk
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 3.1.1 All 140 releases
defender-security / src / controller / class-security-headers.php

class-security-headers.php in Defender Security – Malware Scanner, Login Security & Firewall trunk, at src/controller/class-security-headers.php

252 lines 6.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Handles security headers settings.
4 *
5 * @package WP_Defender\Controller
6 */
7
8 namespace WP_Defender\Controller;
9
10 use WP_Defender\Event;
11 use Calotes\Helper\HTTP;
12 use Calotes\Component\Request;
13 use Calotes\Component\Response;
14 use WP_Defender\Component\Config\Config_Hub_Helper;
15
16 /**
17 * Class Security_Headers
18 * Contains methods to handle security headers.
19 */
20 class Security_Headers extends Event {
21
22 /**
23 * The model for handling the data.
24 *
25 * @var \WP_Defender\Model\Setting\Security_Headers
26 */
27 public $model;
28
29 /**
30 * Initializes the model and service, registers routes, and sets up scheduled events if the model is active.
31 */
32 public function __construct() {
33 $this->model = wd_di()->get( \WP_Defender\Model\Setting\Security_Headers::class );
34 $this->init_headers();
35 $this->register_routes();
36 }
37
38 /**
39 * Safe way to get cached model.
40 *
41 * @return \WP_Defender\Model\Setting\Security_Headers
42 */
43 private function get_model() {
44 if ( is_object( $this->model ) ) {
45 return $this->model;
46 }
47
48 return new \WP_Defender\Model\Setting\Security_Headers();
49 }
50
51 /**
52 * Save settings.
53 *
54 * @param Request $request The request object containing new settings data.
55 *
56 * @return Response
57 * @defender_route
58 */
59 public function save_settings( Request $request ) {
60 $data = $request->get_data_by_model( $this->model );
61 $this->model->import( $data );
62 if ( $this->model->validate() ) {
63 $this->model->save();
64 Config_Hub_Helper::set_clear_active_flag();
65
66 if ( $this->maybe_track() ) {
67 // The current model data.
68 $is_active_curr_data = $this->get_model()->is_any_activated();
69 // The previous model data.
70 $prev_data = $this->get_model()->get_old_settings();
71
72 $is_active_prev_data = false;
73
74 if ( array() !== $prev_data ) {
75 $is_active_prev_data = true === $prev_data['sh_xframe'] || true === $prev_data['sh_xss_protection']
76 || true === $prev_data['sh_content_type_options'] || true === $prev_data['sh_feature_policy']
77 || true === $prev_data['sh_strict_transport'] || true === $prev_data['sh_referrer_policy'];
78 }
79
80 $need_track = false;
81
82 if ( $is_active_prev_data && ! $is_active_curr_data ) {
83 $need_track = true;
84 $event = 'def_feature_deactivated';
85 } elseif ( ! $is_active_prev_data && $is_active_curr_data ) {
86 $need_track = true;
87 $event = 'def_feature_activated';
88 }
89
90 // Other conditions without State's changes.
91 if ( $need_track ) {
92 $data = array(
93 'Feature' => 'Security Headers',
94 'Triggered From' => 'Feature page',
95 );
96 $this->track_feature( $event, $data );
97 }
98 }
99
100 return new Response(
101 true,
102 array_merge(
103 array(
104 'message' => esc_html__( 'Your settings have been updated.', 'defender-security' ),
105 'auto_close' => true,
106 ),
107 $this->data_frontend()
108 )
109 );
110 }
111
112 return new Response( false, array( 'message' => $this->model->get_formatted_errors() ) );
113 }
114
115 /**
116 * Init headers.
117 *
118 * @return void
119 */
120 public function init_headers(): void {
121 if ( ! defined( 'DOING_AJAX' ) ) {
122 // Refresh if on admin, on page with headers.
123 if ( ( is_admin() || is_network_admin() )
124 &&
125 (
126 ( 'wdf-advanced-tools' === HTTP::get( 'page' ) )
127 || ( 'wp-defender' === HTTP::get( 'page' ) )
128 )
129 ) {
130 // This meant we don't have any data or data is overdue need to refresh list of headers.
131 $this->model->refresh_headers();
132 } elseif ( defined( 'DOING_CRON' ) ) {
133 // If this is in cronjob, we refresh it too.
134 $this->model->refresh_headers();
135 }
136 }
137
138 foreach ( $this->model->get_headers() as $rule ) {
139 $rule->add_hooks();
140 }
141 }
142
143 /**
144 * Removes settings for all submodules.
145 */
146 public function remove_settings() {
147 }
148
149 /**
150 * Delete all the data & the cache.
151 */
152 public function remove_data() {
153 }
154
155 /**
156 * Converts the current object state to an array.
157 *
158 * @return array The array representation of the object.
159 */
160 public function to_array() {
161 $misc = $this->get_model()->refresh_headers();
162
163 return array_slice( $misc, 0, 3 );
164 }
165
166 /**
167 * Get data about headers.
168 *
169 * @return array
170 */
171 public function get_type_headers(): array {
172 return $this->get_model()->get_headers_by_type();
173 }
174
175 /**
176 * Provides data for the frontend.
177 *
178 * @return array An array of data for the frontend.
179 */
180 public function data_frontend(): array {
181 $model = $this->get_model();
182
183 return array_merge(
184 array(
185 'model' => $model->export(),
186 'misc' => $model->get_headers_as_array( true ),
187 'enabled' => $model->get_enabled_headers( 3 ),
188 ),
189 $this->dump_routes_and_nonces()
190 );
191 }
192
193 /**
194 * Provides data for the dashboard widget.
195 *
196 * @return array An array of dashboard widget data.
197 */
198 public function dashboard_widget(): array {
199 return array( 'enabled' => $this->get_model()->get_enabled_headers( 3 ) );
200 }
201
202 /**
203 * Imports data into the model.
204 *
205 * @param array $data Data to be imported into the model.
206 */
207 public function import_data( array $data ) {
208 $model = $this->get_model();
209
210 $model->import( $data );
211 if ( $model->validate() ) {
212 $model->save();
213 }
214 }
215
216 /**
217 * Exports strings.
218 *
219 * @return array An array of strings.
220 */
221 public function export_strings(): array {
222 return array(
223 \WP_Defender\Model\Setting\Security_Headers::get_module_name() . ' '
224 . ( $this->get_model()->is_any_activated() ? esc_html__( 'active', 'defender-security' ) : esc_html__(
225 'inactive',
226 'defender-security'
227 ) ),
228 );
229 }
230
231 /**
232 * Generates configuration strings based on the provided configuration.
233 *
234 * @param array $config Configuration data.
235 *
236 * @return array Returns an array of configuration strings.
237 */
238 public function config_strings( array $config ): array {
239 $active = ( isset( $config['sh_xframe'] ) && $config['sh_xframe'] )
240 || ( isset( $config['sh_xss_protection'] ) && $config['sh_xss_protection'] )
241 || ( isset( $config['sh_content_type_options'] ) && $config['sh_content_type_options'] )
242 || ( isset( $config['sh_feature_policy'] ) && $config['sh_feature_policy'] )
243 || ( isset( $config['sh_strict_transport'] ) && $config['sh_strict_transport'] )
244 || ( isset( $config['sh_referrer_policy'] ) && $config['sh_referrer_policy'] );
245
246 return array(
247 \WP_Defender\Model\Setting\Security_Headers::get_module_name() . ' '
248 . ( $active ? esc_html__( 'active', 'defender-security' ) : esc_html__( 'inactive', 'defender-security' ) ),
249 );
250 }
251 }
252