PluginProbe
AcyMailing – An Ultimate Newsletter Plugin and Marketing Automation Solution for WordPress / 11.1.0
AcyMailing – An Ultimate Newsletter Plugin and Marketing Automation Solution for WordPress v11.1.0
11.1.1 11.1.0 11.0.5 11.0.4 11.0.3 11.0.2 11.0.1 11.0.0 10.11.1 10.11.0 10.10.2 10.10.1 10.10.0 10.9.1 trunk 10.0.0 10.0.1 10.1.0 10.1.1 10.1.2 10.1.3 10.1.4 10.2.0 10.2.1 10.2.2 All 62 releases
← All changes | back/Core/wordpress/security.php +86 -57 10.10.2 → 11.1.0 View file →
@@ -1,33 +1,39 @@
1 1 <?php
2 2
3 +defined('ABSPATH') || die('Restricted Access');
4 +
3 5 use AcyMailing\Helpers\UpdatemeHelper;
4 6
7 +/**
8 + * @param mixed $default
9 + *
10 + * @return mixed
11 + */
5 12 function acym_getVar(string $type, string $name, $default = null, string $source = 'REQUEST', int $mask = 0)
6 13 {
7 14 $source = strtoupper($source);
8 15
9 16 switch ($source) {
10 - case 'GET':
11 - $input = &$_GET;
12 - break;
13 - case 'POST':
14 - $input = &$_POST;
15 - break;
16 17 case 'FILES':
18 + // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Nonce verification is the caller's responsibility for this generic helper.
17 19 $input = &$_FILES;
18 20 break;
19 21 case 'COOKIE':
22 + // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Nonce verification is the caller's responsibility for this generic helper.
20 23 $input = &$_COOKIE;
21 24 break;
22 - case 'ENV':
23 - $input = &$_ENV;
24 - break;
25 25 case 'SERVER':
26 + // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Nonce verification is the caller's responsibility for this generic helper.
26 27 $input = &$_SERVER;
27 28 break;
29 + case 'SESSION':
30 + acym_session();
31 + $input = &$_SESSION;
32 + break;
28 33 default:
29 34 $source = 'REQUEST';
35 + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Nonce verification is the caller's responsibility for this generic helper.
30 36 $input = &$_REQUEST;
31 37 break;
32 38 }
33 39
@@ -40,8 +46,9 @@
40 46 if ($type === 'array') {
41 47 $result = (array)$result;
42 48 }
43 49
50 + // WP alters every variable in $_REQUEST... Seriously...
44 51 if (in_array($source, ['POST', 'REQUEST', 'GET', 'COOKIE'])) {
45 52 $result = acym_stripslashes($result);
46 53 }
47 54
@@ -106,8 +113,9 @@
106 113 return $var;
107 114 }
108 115
109 116 if (!preg_match('//u', $var)) {
117 + // String contains invalid byte sequence, remove it
110 118 $var = htmlspecialchars_decode(htmlspecialchars($var, ENT_IGNORE, 'UTF-8'));
111 119 }
112 120
113 121 if (!($mask & ACYM_ALLOWHTML)) {
@@ -116,50 +124,26 @@
116 124
117 125 return $var;
118 126 }
119 127
120 -function acym_setVar(string $name, $value = null, string $hash = 'REQUEST', bool $overwrite = true): void
128 +function acym_setVar(string $name, $value): void
121 129 {
122 - $hash = strtoupper($hash);
123 -
124 - switch ($hash) {
125 - case 'GET':
126 - $input = &$_GET;
127 - break;
128 - case 'POST':
129 - $input = &$_POST;
130 - break;
131 - case 'FILES':
132 - $input = &$_FILES;
133 - break;
134 - case 'COOKIE':
135 - $input = &$_COOKIE;
136 - break;
137 - case 'ENV':
138 - $input = &$_ENV;
139 - break;
140 - case 'SERVER':
141 - $input = &$_SERVER;
142 - break;
143 - default:
144 - $input = &$_REQUEST;
145 - break;
146 - }
147 -
148 - if (!isset($input[$name]) || $overwrite) {
149 - $input[$name] = $value;
150 - }
130 + $_REQUEST[$name] = $value;
151 131 }
152 132
133 +/**
134 + * Function detecting the context of a request, not related to security checks
135 + */
153 136 function acym_isAdmin(): bool
154 137 {
138 + // Outside of /wp-admin we are on the front-end, whatever the request parameters say
139 + if (!is_admin()) {
140 + return false;
141 + }
142 +
155 143 $page = acym_getVar('string', 'page', '');
156 144
157 - if (!empty($page)) {
158 - return !in_array($page, [ACYM_COMPONENT.'_front', 'front']);
159 - } else {
160 - return is_admin();
161 - }
145 + return !in_array($page, [ACYM_COMPONENT.'_front', 'front'], true);
162 146 }
163 147
164 148 function acym_cmsLoaded(): void
165 149 {
@@ -172,8 +156,9 @@
172 156 }
173 157
174 158 function acym_askLog(bool $current = true, string $message = 'ACYM_NOTALLOWED', string $type = 'error'): void
175 159 {
160 + //If the user is not logged in, we just redirect him to the login page....
176 161 $url = acym_rootURI().'wp-login.php';
177 162 if ($current) {
178 163 $url .= '&redirect_to='.base64_encode(acym_currentURL());
179 164 }
@@ -200,40 +185,69 @@
200 185
201 186 return $allPref;
202 187 }
203 188
204 -function acym_cmsPermission(): string
189 +function acym_hasAdminPermissions(): bool
205 190 {
206 - if (!current_user_can('manage_options')) return '';
191 + return current_user_can('manage_options');
192 +}
207 193
194 +/**
195 + * May the user reach the AcyMailing back-end at all? Same rule as the menu visibility (Menu::addMenus).
196 + */
197 +function acym_hasBackofficeAccess(): bool
198 +{
208 199 $config = acym_config();
200 + $allowedGroups = explode(',', $config->get('wp_access', 'administrator'));
201 +
202 + $userGroups = acym_getGroupsByUser();
203 + foreach ($userGroups as $oneGroup) {
204 + if ($oneGroup == 'administrator' || in_array($oneGroup, $allowedGroups)) {
205 + return true;
206 + }
207 + }
208 +
209 + return false;
210 +}
211 +
212 +function acym_cmsPermission(): void
213 +{
214 + if (!acym_hasAdminPermissions()) {
215 + return;
216 + }
217 +
218 + $config = acym_config();
209 219 $roles = acym_getGroups();
210 220 $options = [];
211 221 $selected = explode(',', $config->get('wp_access', 'administrator'));
212 222
213 223 foreach ($roles as $name => $oneRole) {
214 - if ($name === 'administrator') continue;
224 + if ($name === 'administrator') {
225 + continue;
226 + }
215 227 $options[$name] = $oneRole->text;
216 228 }
217 229
218 230 asort($options);
219 231
220 - $option = '
221 - <div class="cell grid-x">
222 - <label class="cell large-3 medium-5 small-9">'.acym_translation('ACYM_ACCESS').' '.acym_info(['textShownInTooltip' => 'ACYM_ACCESS_DESC']).'</label>
232 + echo '<div class="cell grid-x">
233 + <label class="cell large-3 medium-5 small-9">'.esc_html(acym_translation('ACYM_ACCESS')).' ';
234 + acym_info(['textShownInTooltip' => 'ACYM_ACCESS_DESC']);
235 + echo '</label>
223 236 <div class="cell auto">';
224 237
225 - $option .= acym_selectMultiple(
238 + acym_selectMultiple(
226 239 $options,
227 240 'config[wp_access]',
228 241 $selected,
229 - ['class' => 'acym__select']
242 + ['class' => 'acym__select'],
243 + 'value',
244 + 'text',
245 + true,
230 246 );
231 247
232 - $option .= '</div>
248 + echo '</div>
233 249 </div>';
234 -
235 - return $option;
236 250 }
237 251
238 252 function acym_triggerCmsHook(string $action, array $args = [], bool $isAction = true)
239 253 {
@@ -246,11 +260,10 @@
246 260 {
247 261 return [];
248 262 }
249 263
250 -function acym_loadCaptcha(string $captchaPluginName, string $id): string
264 +function acym_loadCaptcha(string $captchaPluginName, string $id): void
251 265 {
252 - return '';
253 266 }
254 267
255 268 function acym_checkCaptcha(string $captchaPluginName, ?string $response = null): bool
256 269 {
@@ -259,5 +272,21 @@
259 272
260 273 function acym_getSiteSalt(): string
261 274 {
262 275 return wp_salt('auth');
276 +}
277 +
278 +function acym_stripTags(string $text): string
279 +{
280 + return wp_strip_all_tags($text);
281 +}
282 +
283 +function acym_setSession(string $name, $value, bool $remove = false): void
284 +{
285 + acym_session();
286 +
287 + if ($remove) {
288 + unset($_SESSION[$name]);
289 + } else {
290 + $_SESSION[$name] = $value;
291 + }
263 292 }