PluginProbe
Defender Security – Malware Scanner, Login Security & Firewall / 6.3.0
Defender Security – Malware Scanner, Login Security & Firewall v6.3.0
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-headers / class-sh-feature-policy.php

class-sh-feature-policy.php in Defender Security – Malware Scanner, Login Security & Firewall 6.3.0, at src/component/security-headers/class-sh-feature-policy.php

187 lines 4.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Handles the implementation of the Permissions-Policy header for security purposes.
4 *
5 * @package WP_Defender\Component\Security_Headers
6 */
7
8 namespace WP_Defender\Component\Security_Headers;
9
10 use WP_Defender\Component\Security_Header;
11
12 /**
13 * Manages the Permissions-Policy header which controls browser features.
14 */
15 class Sh_Feature_Policy extends Security_Header {
16
17 /**
18 * Unique identifier for this security header rule.
19 *
20 * @var string
21 */
22 public static $rule_slug = 'sh_feature_policy';
23
24 /**
25 * Checks if the Policy should be applied based on the current settings and site configuration.
26 *
27 * @return bool True if the header should be applied, false otherwise.
28 */
29 public function check() {
30 $model = $this->get_model();
31
32 if ( ! $model->sh_feature_policy ) {
33 return false;
34 }
35 if ( isset( $model->sh_feature_policy_mode ) && '' !== $model->sh_feature_policy_mode ) {
36 return true;
37 }
38 $headers = $this->head_request( network_site_url(), self::$rule_slug );
39 if ( is_wp_error( $headers ) ) {
40 $this->log( sprintf( 'Self ping error: %s', $headers->get_error_message() ), wd_internal_log() );
41
42 return false;
43 }
44 if ( isset( $headers['feature-policy'] ) ) {
45 return true;
46 }
47
48 return false;
49 }
50
51 /**
52 * Retrieves miscellaneous data related to the Policy.
53 *
54 * @return array Contains introductory text, mode, and values for the Policy.
55 */
56 public function get_misc_data() {
57 $model = $this->get_model();
58
59 return array(
60 'intro_text' => esc_html__(
61 'The Permissions-Policy response header provides control over what browser features can be used when web pages are embedded in iframes.',
62 'defender-security'
63 ),
64 'mode' => $model->sh_feature_policy_mode ?? 'self',
65 'values' => $model->sh_feature_policy_urls ?? '',
66 );
67 }
68
69 /**
70 * Registers hooks related to sending headers.
71 */
72 public function add_hooks() {
73 add_action( 'send_headers', array( $this, 'append_header' ) );
74 }
75
76 /**
77 * Appends the header to the response.
78 */
79 public function append_header() {
80 if ( headers_sent() ) {
81 return;
82 }
83 $model = $this->get_model();
84 if ( ! $this->maybe_submit_header( 'Permissions-Policy', false ) ) {
85
86 return;
87 }
88
89 if ( true === $model->sh_feature_policy
90 && isset( $model->sh_feature_policy_mode )
91 && in_array( $model->sh_feature_policy_mode, array( 'self', 'allow', 'origins', 'none' ), true )
92 ) {
93 $headers = '';
94 /**
95 * Filter the list of features for the Permissions-Policy header.
96 *
97 * @since 2.6.1
98 *
99 * @param array $features An array of features.
100 */
101 $features = apply_filters(
102 'wd_permissions_policy_directives',
103 // Default list of features.
104 array(
105 'accelerometer', // Enable access to the Accelerometer API.
106 'autoplay', // Allow media to be automatically played.
107 'camera', // Enable access to the Camera API.
108 'encrypted-media', // Require encrypted media to be played.
109 'fullscreen', // Allow the fullscreen mode.
110 'geolocation', // Enable access to the Geolocation API.
111 'gyroscope', // Enable access to the Gyroscope API.
112 'magnetometer', // Enable access to the Magnetometer API.
113 'microphone', // Enable access to the Microphone API.
114 'midi', // Allow access to MIDI devices.
115 'payment', // Allow websites to make payments.
116 'usb', // Allow websites to access USB devices.
117 )
118 );
119
120 switch ( $model->sh_feature_policy_mode ) {
121 case 'self':
122 array_walk(
123 $features,
124 function ( &$value ) {
125 $value .= '=(self)';
126 }
127 );
128 $headers = 'Permissions-Policy: ' . implode( ', ', $features );
129 break;
130 case 'allow':
131 array_walk(
132 $features,
133 function ( &$value ) {
134 $value .= '=*';
135 }
136 );
137 $headers = 'Permissions-Policy: ' . implode( ', ', $features );
138 break;
139 case 'origins':
140 if ( isset( $model->sh_feature_policy_urls ) && '' !== $model->sh_feature_policy_urls ) {
141 $urls = explode( PHP_EOL, $model->sh_feature_policy_urls );
142 $urls = array_map( 'trim', $urls );
143 // Wrap strings in quotes.
144 array_walk(
145 $urls,
146 function ( &$x ) {
147 $x = '"' . $x . '"';
148 }
149 );
150 $urls = implode( ' ', $urls );
151 array_walk(
152 $features,
153 function ( &$value ) use ( $urls ) {
154 $value .= '=(' . $urls . ')';
155 }
156 );
157 $headers = 'Permissions-Policy: ' . implode( ', ', $features );
158 }
159 break;
160 case 'none':
161 array_walk(
162 $features,
163 function ( &$value ) {
164 $value .= '=()';
165 }
166 );
167 $headers = 'Permissions-Policy: ' . implode( ', ', $features );
168 break;
169 default:
170 break;
171 }
172 if ( strlen( $headers ) > 0 ) {
173 header( trim( $headers ) );
174 }
175 }
176 }
177
178 /**
179 * Retrieves the title of the Permissions-Policy.
180 *
181 * @return string The title of the Permissions-Policy.
182 */
183 public function get_title() {
184 return esc_html__( 'Permissions-Policy', 'defender-security' );
185 }
186 }
187