Headline
CVE-2023-4772: Changeset 2955097 for newsletter – WordPress Plugin Repository
The Newsletter plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the ‘newsletter_form’ shortcode in versions up to, and including, 7.8.9 due to insufficient input sanitization and output escaping on user supplied attributes. This makes it possible for authenticated attackers with contributor-level and above permissions to inject arbitrary web scripts in pages that will execute whenever a user accesses an injected page.
newsletter/tags/7.9.0/emails/blocks/hero/block-full.php
r2929338
r2955097
13
13
padding: 0 0 20px 0;
14
14
15
line-height: 1.5em;
15
line-height: 1.5;
16
16
margin: 0;
17
17
}
newsletter/tags/7.9.0/emails/blocks/hero/block-left.php
r2929338
r2955097
17
17
<?php $text\_style->echo\_css()?>
18
18
padding: 0 0 15px;
19
line-height: 1.5em;
19
line-height: 1.5;
20
20
margin: 0;
21
21
}
newsletter/tags/7.9.0/emails/blocks/hero/block-right.php
r2929338
r2955097
16
16
<?php $text\_style->echo\_css()?>
17
17
padding: 0 0 15px;
18
line-height: 1.5em;
18
line-height: 1.5;
19
19
margin: 0;
20
20
}
newsletter/tags/7.9.0/emails/blocks/posts/layout-big-image.php
r2864600
r2955097
18
18
.excerpt {
19
19
<?php echo $text\_style->echo\_css() ?>
20
line-height: 1.5em!important;
20
line-height: 1.5 !important;
21
21
text-decoration: none;
22
22
}
newsletter/tags/7.9.0/emails/blocks/posts/layout-full-post.php
r2869252
r2955097
20
20
.p {
21
21
<?php $text\_style->echo\_css() ?>
22
line-height: 1.5em!important;
22
line-height: 1.5 !important;
23
23
}
24
24
newsletter/tags/7.9.0/emails/blocks/posts/layout-one-2.php
r2864600
r2955097
20
20
.excerpt {
21
21
<?php $text\_style->echo\_css() ?>
22
line-height: 1.5em;
22
line-height: 1.5;
23
23
text-decoration: none;
24
24
}
newsletter/tags/7.9.0/emails/blocks/posts/layout-one.php
r2878889
r2955097
18
18
.excerpt {
19
19
<?php $text\_style->echo\_css() ?>
20
line-height: 1.5em !important;
20
line-height: 1.5 !important;
21
21
text-decoration: none;
22
22
}
newsletter/tags/7.9.0/emails/blocks/posts/layout-two.php
r2855901
r2955097
12
12
.title {
13
13
<?php $title\_style->echo\_css()?>
14
line-height: 1.3em;
14
line-height: 1.3;
15
15
padding: 15px 0 0 0;
16
16
}
newsletter/tags/7.9.0/emails/emails.php
r2922963
r2955097
185
185
header('X-Robots-Tag: noindex,nofollow,noarchive');
186
186
header('Cache-Control: no-cache,no-store,private');
187
188
echo apply\_filters('newsletter\_view\_message', $this->replace($email->message, $user, $email));
187
188
$message = $this->replace($email->message, $user, $email);
189
if (Newsletter::instance()->get\_option('do\_shortcodes')) {
190
$message = do\_shortcode($message);
191
}
192
echo apply\_filters('newsletter\_view\_message', $message);
189
193
190
194
die();
newsletter/tags/7.9.0/emails/index.php
r2922655
r2955097
62
62
<thead>
63
63
<tr>
64
<th\><input type="checkbox" onchange="jQuery('input.tnp-selector').prop('checked', this.checked)"></th>
64
<th style="text-align: center"\><input type="checkbox" onchange="jQuery('input.tnp-selector').prop('checked', this.checked)"></th>
65
65
<th>Id</th>
66
66
<th><?php \_e('Subject', 'newsletter') ?></th>
…
…
68
68
<th><?php \_e('Progress', 'newsletter') ?> (\*)</th>
69
69
<th><?php \_e('Date', 'newsletter') ?></th>
70
<th> </th>
71
<th> </th>
72
70
<th> </th>
73
71
<th> </th>
…
…
79
77
<?php foreach ($emails as $email) { ?>
80
78
<tr>
81
<td\>
79
<td style="text-align: center"\>
82
80
<input type="checkbox" class="tnp-selector" name="ids\[\]" value="<?php echo $email->id; ?>">
83
81
</td>
newsletter/tags/7.9.0/includes/helper.php
r2924171
r2955097
302
302
return \_tnp\_get\_default\_media($media\_id, $size);
303
303
}
304
305
$relative\_thumb = $pathinfo\['dirname'\] . '/' . $pathinfo\['filename'\] . '-' . $width . 'x' . $height . ($crop ? '-c' : '') . '.' . $pathinfo\['extension'\];
304
305
$file\_ext = strtolower($pathinfo\['extension'\]);
306
$out\_mimetype = null;
307
308
if ($file\_ext === 'webp') {
309
$file\_ext = 'jpg';
310
$out\_mimetype = 'image/jpeg';
311
}
312
313
$relative\_thumb = $pathinfo\['dirname'\] . '/' . $pathinfo\['filename'\] . '-' . $width . 'x' . $height . ($crop ? '-c' : '') . '.' . $file\_ext;
306
314
$absolute\_thumb = $uploads\['basedir'\] . '/newsletter/thumbnails/' . $relative\_thumb;
307
315
…
…
341
349
return \_tnp\_get\_default\_media($media\_id, $size);
342
350
}
343
344
$saved = $editor->save($absolute\_thumb);
351
352
$saved = $editor->save($absolute\_thumb, $out\_mimetype);
345
353
if (is\_wp\_error($saved)) {
346
354
Newsletter::instance()->logger->error($saved);
newsletter/tags/7.9.0/includes/module-admin.php
r2925806
r2955097
749
749
} else if (function\_exists('pll\_languages\_list')) {
750
750
$languages = pll\_languages\_list(\['fields' => ''\]);
751
//var\_dump($languages);
752
751
foreach ($languages as $data) {
753
752
$language\_options\[$data->slug\] = $data->name;
newsletter/tags/7.9.0/plugin.php
r2943508
r2955097
5
5
Plugin URI: https://www.thenewsletterplugin.com/plugins/newsletter
6
6
Description: Newsletter is a cool plugin to create your own subscriber list, to send newsletters, to build your business. <strong>Before update give a look to <a href="https://www.thenewsletterplugin.com/category/release">this page</a> to know what's changed.</strong>
7
Version: 7.8.9
7
Version: 7.9.0
8
8
Author: Stefano Lissa & The Newsletter Team
9
9
Author URI: https://www.thenewsletterplugin.com
…
…
12
12
License: GPLv2 or later
13
13
Requires at least: 4.6
14
Requires PHP: 5.6
14
Requires PHP: 7.0
15
15
16
16
Copyright 2009-2023 The Newsletter Team (email: [email protected], web: https://www.thenewsletterplugin.com)
…
…
38
38
}
39
39
40
define('NEWSLETTER\_VERSION', '7.8.9');
40
define('NEWSLETTER\_VERSION', '7.9.0');
41
41
42
42
global $newsletter, $wpdb;
newsletter/tags/7.9.0/readme.txt
r2943508
r2955097
1
1
\=== Newsletter - Send awesome emails from WordPress ===
2
2
Tags: newsletter, email marketing, welcome email, signup forms, lead generation, marketing automation
3
Tested up to: 6.2.2
4
Stable tag: 7.8.9
3
Tested up to: 6.3
4
Stable tag: 7.9.0
5
5
Contributors: satollo,webagile,michael-travan
6
6
License: GPLv2 or later
…
…
127
127
\== Changelog ==
128
128
129
\= 7.9.0 =
130
131
\* Fixed some line heights
132
\* Added registration of shortcodes under the AJAX context
133
\* Added shortcode management on newsletter online view
134
\* Fixed line-height for Outlook on some blocks
135
\* Fixed the template message test
136
\* Added webp images check since Outlook does not support that format
137
\* Fixed error text field on subscription panel not displaying when customized
138
\* Security fix on minimal form shortcode
139
\* Removed the "before" and "after" attributes of the main shortcode
140
129
141
\= 7.8.9 =
130
142
newsletter/tags/7.9.0/subscription/options.php
r2924171
r2955097
80
80
//$this->dump($controls->data);
81
81
82
foreach (\['confirmed\_text', 'confirmed\_message', 'confirmation\_text', 'confirmation\_message', 'subscription\_text'\] as $key) {
82
foreach (\['confirmed\_text', 'confirmed\_message', 'confirmation\_text', 'confirmation\_message', 'subscription\_text', 'error\_text'\] as $key) {
83
83
if (!empty($controls->data\[$key\])) {
84
84
$controls->data\[$key . '\_custom'\] = '1';
newsletter/tags/7.9.0/subscription/subscription.php
r2943508
r2955097
32
32
function hook\_init() {
33
33
add\_action('newsletter\_action', array($this, 'hook\_newsletter\_action'), 10, 3);
34
if (!is\_admin()) {
34
if (!is\_admin() || defined('DOING\_AJAX') && DOING\_AJAX) {
35
35
// Shortcode for the Newsletter page
36
36
add\_shortcode('newsletter', array($this, 'shortcode\_newsletter'));
…
…
38
38
add\_shortcode('newsletter\_field', array($this, 'shortcode\_newsletter\_field'));
39
39
}
40
}
41
42
function get\_options($set = '', $language = null) {
43
// This is a patch for addon using the "profile" set which originally contained the
44
// form options. This patch can create a problem if someone calls this method to get the actual
45
// "profile" set which is the configuration of the profile page.
46
// The correct call would be NewsletterProfile::instance()->get\_options().
47
if ($set === 'profile') {
48
$set = 'form';
49
}
50
return parent::get\_options($set, $language);
51
40
}
52
41
…
…
194
183
}
195
184
}
185
186
function get\_options($set = '', $language = null) {
187
// This is a patch for addon using the "profile" set which originally contained the
188
// form options. This patch can create a problem if someone calls this method to get the actual
189
// "profile" set which is the configuration of the profile page.
190
// The correct call would be NewsletterProfile::instance()->get\_options().
191
if ($set === 'profile') {
192
$set = 'form';
193
}
194
return parent::get\_options($set, $language);
195
}
196
196
197
197
function get\_form\_options() {
…
…
1505
1505
}
1506
1506
1507
if (isset($attrs\['before'\])) {
1508
$buffer .= $attrs\['before'\];
1509
} else {
1510
if (isset($attrs\['class'\])) {
1511
$buffer .= '<div class="tnp tnp-subscription ' . $attrs\['class'\] . '">' . "\\n";
1512
} else {
1513
$buffer .= '<div class="tnp tnp-subscription">' . "\\n";
1514
}
1507
1508
if (isset($attrs\['class'\])) {
1509
$buffer .= '<div class="tnp tnp-subscription ' . esc\_attr($attrs\['class'\]) . '">' . "\\n";
1510
} else {
1511
$buffer .= '<div class="tnp tnp-subscription">' . "\\n";
1515
1512
}
1516
1513
…
…
1568
1565
}
1569
1566
1570
1571
1567
$buffer .= '<input class="tnp-submit" type="submit" value="' . esc\_attr($this->get\_form\_text('subscribe')) . '" ' . $button\_style . '>' . "\\n";
1572
1568
1573
1569
$buffer .= "</div>\\n</form>\\n";
1574
1570
1575
if (isset($attrs\['after'\])) {
1576
$buffer .= $attrs\['after'\];
1577
} else {
1578
$buffer .= "</div>\\n";
1579
}
1571
$buffer .= "</div>\\n";
1580
1572
1581
1573
return $buffer;
…
…
1592
1584
1593
1585
if (stripos($form, '<form') === false) {
1594
$form = '<form method="post" action="' . $action . '">' . $form . '</form>';
1586
$form = '<form method="post" action="' . esc\_attr($action) . '">' . $form . '</form>';
1595
1587
}
1596
1588
…
…
1613
1605
$lists = $this->get\_lists\_for\_subscription();
1614
1606
foreach ($lists as $list) {
1615
$checkboxes .= '<input type="checkbox" name="nl\[\]" value="' . $list->id . '"> ' . $list->name . '<br />';
1607
$checkboxes .= '<input type="checkbox" name="nl\[\]" value="' . esc\_attr($list->id) . '"> ' . esc\_attr($list->name) . '<br />';
1616
1608
}
1617
1609
$buffer = str\_replace('{lists}', $checkboxes, $buffer);
1618
$buffer = str\_replace('{preferences}', $checkboxes, $buffer);
1610
$buffer = str\_replace('{preferences}', $checkboxes, $buffer); // For compatibility
1619
1611
return $buffer;
1620
1612
}
…
…
1651
1643
$form = '';
1652
1644
1653
$form .= '<div class="tnp tnp-subscription-minimal ' . $attrs\['class'\] . '">';
1645
$form .= '<div class="tnp tnp-subscription-minimal ' . esc\_attr($attrs\['class'\]) . '">';
1654
1646
$form .= '<form action="' . esc\_attr($this->build\_action\_url('s')) . '" method="post"';
1655
1647
if (!empty($attrs\['id'\])) {
newsletter/tags/7.9.0/subscription/template.php
r2922655
r2955097
22
22
if ($controls->is\_action('test')) {
23
23
24
$users = $module\->get\_test\_users();
24
$users = $this\->get\_test\_users();
25
25
if (count($users) == 0) {
26
26
$controls->errors = \_\_('No test subscribers found.', 'newsletter') . ' <a href="https://www.thenewsletterplugin.com/plugins/newsletter/subscribers-module#test" target="\_blank"><i class="fas fa-info-circle"></i></a>';
…
…
40
40
foreach ($users as $user) {
41
41
$addresses\[\] = $user->email;
42
Newsletter::instance()->mail($user->email, 'Newsletter Messages Template Test', $module\->replace($message, $user));
42
Newsletter::instance()->mail($user->email, 'Newsletter Messages Template Test', $this\->replace($message, $user));
43
43
}
44
44
$controls->messages .= 'Test emails sent to ' . count($users) . ' test subscribers: ' .
newsletter/trunk/emails/blocks/hero/block-full.php
r2929338
r2955097
13
13
padding: 0 0 20px 0;
14
14
15
line-height: 1.5em;
15
line-height: 1.5;
16
16
margin: 0;
17
17
}
newsletter/trunk/emails/blocks/hero/block-left.php
r2929338
r2955097
17
17
<?php $text\_style->echo\_css()?>
18
18
padding: 0 0 15px;
19
line-height: 1.5em;
19
line-height: 1.5;
20
20
margin: 0;
21
21
}
newsletter/trunk/emails/blocks/hero/block-right.php
r2929338
r2955097
16
16
<?php $text\_style->echo\_css()?>
17
17
padding: 0 0 15px;
18
line-height: 1.5em;
18
line-height: 1.5;
19
19
margin: 0;
20
20
}
newsletter/trunk/emails/blocks/posts/layout-big-image.php
r2864600
r2955097
18
18
.excerpt {
19
19
<?php echo $text\_style->echo\_css() ?>
20
line-height: 1.5em!important;
20
line-height: 1.5 !important;
21
21
text-decoration: none;
22
22
}
newsletter/trunk/emails/blocks/posts/layout-full-post.php
r2869252
r2955097
20
20
.p {
21
21
<?php $text\_style->echo\_css() ?>
22
line-height: 1.5em!important;
22
line-height: 1.5 !important;
23
23
}
24
24
newsletter/trunk/emails/blocks/posts/layout-one-2.php
r2864600
r2955097
20
20
.excerpt {
21
21
<?php $text\_style->echo\_css() ?>
22
line-height: 1.5em;
22
line-height: 1.5;
23
23
text-decoration: none;
24
24
}
newsletter/trunk/emails/blocks/posts/layout-one.php
r2878889
r2955097
18
18
.excerpt {
19
19
<?php $text\_style->echo\_css() ?>
20
line-height: 1.5em !important;
20
line-height: 1.5 !important;
21
21
text-decoration: none;
22
22
}
newsletter/trunk/emails/blocks/posts/layout-two.php
r2855901
r2955097
12
12
.title {
13
13
<?php $title\_style->echo\_css()?>
14
line-height: 1.3em;
14
line-height: 1.3;
15
15
padding: 15px 0 0 0;
16
16
}
newsletter/trunk/emails/emails.php
r2922963
r2955097
185
185
header('X-Robots-Tag: noindex,nofollow,noarchive');
186
186
header('Cache-Control: no-cache,no-store,private');
187
188
echo apply\_filters('newsletter\_view\_message', $this->replace($email->message, $user, $email));
187
188
$message = $this->replace($email->message, $user, $email);
189
if (Newsletter::instance()->get\_option('do\_shortcodes')) {
190
$message = do\_shortcode($message);
191
}
192
echo apply\_filters('newsletter\_view\_message', $message);
189
193
190
194
die();
newsletter/trunk/emails/index.php
r2922655
r2955097
62
62
<thead>
63
63
<tr>
64
<th\><input type="checkbox" onchange="jQuery('input.tnp-selector').prop('checked', this.checked)"></th>
64
<th style="text-align: center"\><input type="checkbox" onchange="jQuery('input.tnp-selector').prop('checked', this.checked)"></th>
65
65
<th>Id</th>
66
66
<th><?php \_e('Subject', 'newsletter') ?></th>
…
…
68
68
<th><?php \_e('Progress', 'newsletter') ?> (\*)</th>
69
69
<th><?php \_e('Date', 'newsletter') ?></th>
70
<th> </th>
71
<th> </th>
72
70
<th> </th>
73
71
<th> </th>
…
…
79
77
<?php foreach ($emails as $email) { ?>
80
78
<tr>
81
<td\>
79
<td style="text-align: center"\>
82
80
<input type="checkbox" class="tnp-selector" name="ids\[\]" value="<?php echo $email->id; ?>">
83
81
</td>
newsletter/trunk/includes/helper.php
r2924171
r2955097
302
302
return \_tnp\_get\_default\_media($media\_id, $size);
303
303
}
304
305
$relative\_thumb = $pathinfo\['dirname'\] . '/' . $pathinfo\['filename'\] . '-' . $width . 'x' . $height . ($crop ? '-c' : '') . '.' . $pathinfo\['extension'\];
304
305
$file\_ext = strtolower($pathinfo\['extension'\]);
306
$out\_mimetype = null;
307
308
if ($file\_ext === 'webp') {
309
$file\_ext = 'jpg';
310
$out\_mimetype = 'image/jpeg';
311
}
312
313
$relative\_thumb = $pathinfo\['dirname'\] . '/' . $pathinfo\['filename'\] . '-' . $width . 'x' . $height . ($crop ? '-c' : '') . '.' . $file\_ext;
306
314
$absolute\_thumb = $uploads\['basedir'\] . '/newsletter/thumbnails/' . $relative\_thumb;
307
315
…
…
341
349
return \_tnp\_get\_default\_media($media\_id, $size);
342
350
}
343
344
$saved = $editor->save($absolute\_thumb);
351
352
$saved = $editor->save($absolute\_thumb, $out\_mimetype);
345
353
if (is\_wp\_error($saved)) {
346
354
Newsletter::instance()->logger->error($saved);
newsletter/trunk/includes/module-admin.php
r2925806
r2955097
749
749
} else if (function\_exists('pll\_languages\_list')) {
750
750
$languages = pll\_languages\_list(\['fields' => ''\]);
751
//var\_dump($languages);
752
751
foreach ($languages as $data) {
753
752
$language\_options\[$data->slug\] = $data->name;
newsletter/trunk/plugin.php
r2943508
r2955097
5
5
Plugin URI: https://www.thenewsletterplugin.com/plugins/newsletter
6
6
Description: Newsletter is a cool plugin to create your own subscriber list, to send newsletters, to build your business. <strong>Before update give a look to <a href="https://www.thenewsletterplugin.com/category/release">this page</a> to know what's changed.</strong>
7
Version: 7.8.9
7
Version: 7.9.0
8
8
Author: Stefano Lissa & The Newsletter Team
9
9
Author URI: https://www.thenewsletterplugin.com
…
…
12
12
License: GPLv2 or later
13
13
Requires at least: 4.6
14
Requires PHP: 5.6
14
Requires PHP: 7.0
15
15
16
16
Copyright 2009-2023 The Newsletter Team (email: [email protected], web: https://www.thenewsletterplugin.com)
…
…
38
38
}
39
39
40
define('NEWSLETTER\_VERSION', '7.8.9');
40
define('NEWSLETTER\_VERSION', '7.9.0');
41
41
42
42
global $newsletter, $wpdb;
newsletter/trunk/readme.txt
r2943508
r2955097
1
1
\=== Newsletter - Send awesome emails from WordPress ===
2
2
Tags: newsletter, email marketing, welcome email, signup forms, lead generation, marketing automation
3
Tested up to: 6.2.2
4
Stable tag: 7.8.9
3
Tested up to: 6.3
4
Stable tag: 7.9.0
5
5
Contributors: satollo,webagile,michael-travan
6
6
License: GPLv2 or later
…
…
127
127
\== Changelog ==
128
128
129
\= 7.9.0 =
130
131
\* Fixed some line heights
132
\* Added registration of shortcodes under the AJAX context
133
\* Added shortcode management on newsletter online view
134
\* Fixed line-height for Outlook on some blocks
135
\* Fixed the template message test
136
\* Added webp images check since Outlook does not support that format
137
\* Fixed error text field on subscription panel not displaying when customized
138
\* Security fix on minimal form shortcode
139
\* Removed the "before" and "after" attributes of the main shortcode
140
129
141
\= 7.8.9 =
130
142
newsletter/trunk/subscription/options.php
r2924171
r2955097
80
80
//$this->dump($controls->data);
81
81
82
foreach (\['confirmed\_text', 'confirmed\_message', 'confirmation\_text', 'confirmation\_message', 'subscription\_text'\] as $key) {
82
foreach (\['confirmed\_text', 'confirmed\_message', 'confirmation\_text', 'confirmation\_message', 'subscription\_text', 'error\_text'\] as $key) {
83
83
if (!empty($controls->data\[$key\])) {
84
84
$controls->data\[$key . '\_custom'\] = '1';
newsletter/trunk/subscription/subscription.php
r2943508
r2955097
32
32
function hook\_init() {
33
33
add\_action('newsletter\_action', array($this, 'hook\_newsletter\_action'), 10, 3);
34
if (!is\_admin()) {
34
if (!is\_admin() || defined('DOING\_AJAX') && DOING\_AJAX) {
35
35
// Shortcode for the Newsletter page
36
36
add\_shortcode('newsletter', array($this, 'shortcode\_newsletter'));
…
…
38
38
add\_shortcode('newsletter\_field', array($this, 'shortcode\_newsletter\_field'));
39
39
}
40
}
41
42
function get\_options($set = '', $language = null) {
43
// This is a patch for addon using the "profile" set which originally contained the
44
// form options. This patch can create a problem if someone calls this method to get the actual
45
// "profile" set which is the configuration of the profile page.
46
// The correct call would be NewsletterProfile::instance()->get\_options().
47
if ($set === 'profile') {
48
$set = 'form';
49
}
50
return parent::get\_options($set, $language);
51
40
}
52
41
…
…
194
183
}
195
184
}
185
186
function get\_options($set = '', $language = null) {
187
// This is a patch for addon using the "profile" set which originally contained the
188
// form options. This patch can create a problem if someone calls this method to get the actual
189
// "profile" set which is the configuration of the profile page.
190
// The correct call would be NewsletterProfile::instance()->get\_options().
191
if ($set === 'profile') {
192
$set = 'form';
193
}
194
return parent::get\_options($set, $language);
195
}
196
196
197
197
function get\_form\_options() {
…
…
1505
1505
}
1506
1506
1507
if (isset($attrs\['before'\])) {
1508
$buffer .= $attrs\['before'\];
1509
} else {
1510
if (isset($attrs\['class'\])) {
1511
$buffer .= '<div class="tnp tnp-subscription ' . $attrs\['class'\] . '">' . "\\n";
1512
} else {
1513
$buffer .= '<div class="tnp tnp-subscription">' . "\\n";
1514
}
1507
1508
if (isset($attrs\['class'\])) {
1509
$buffer .= '<div class="tnp tnp-subscription ' . esc\_attr($attrs\['class'\]) . '">' . "\\n";
1510
} else {
1511
$buffer .= '<div class="tnp tnp-subscription">' . "\\n";
1515
1512
}
1516
1513
…
…
1568
1565
}
1569
1566
1570
1571
1567
$buffer .= '<input class="tnp-submit" type="submit" value="' . esc\_attr($this->get\_form\_text('subscribe')) . '" ' . $button\_style . '>' . "\\n";
1572
1568
1573
1569
$buffer .= "</div>\\n</form>\\n";
1574
1570
1575
if (isset($attrs\['after'\])) {
1576
$buffer .= $attrs\['after'\];
1577
} else {
1578
$buffer .= "</div>\\n";
1579
}
1571
$buffer .= "</div>\\n";
1580
1572
1581
1573
return $buffer;
…
…
1592
1584
1593
1585
if (stripos($form, '<form') === false) {
1594
$form = '<form method="post" action="' . $action . '">' . $form . '</form>';
1586
$form = '<form method="post" action="' . esc\_attr($action) . '">' . $form . '</form>';
1595
1587
}
1596
1588
…
…
1613
1605
$lists = $this->get\_lists\_for\_subscription();
1614
1606
foreach ($lists as $list) {
1615
$checkboxes .= '<input type="checkbox" name="nl\[\]" value="' . $list->id . '"> ' . $list->name . '<br />';
1607
$checkboxes .= '<input type="checkbox" name="nl\[\]" value="' . esc\_attr($list->id) . '"> ' . esc\_attr($list->name) . '<br />';
1616
1608
}
1617
1609
$buffer = str\_replace('{lists}', $checkboxes, $buffer);
1618
$buffer = str\_replace('{preferences}', $checkboxes, $buffer);
1610
$buffer = str\_replace('{preferences}', $checkboxes, $buffer); // For compatibility
1619
1611
return $buffer;
1620
1612
}
…
…
1651
1643
$form = '';
1652
1644
1653
$form .= '<div class="tnp tnp-subscription-minimal ' . $attrs\['class'\] . '">';
1645
$form .= '<div class="tnp tnp-subscription-minimal ' . esc\_attr($attrs\['class'\]) . '">';
1654
1646
$form .= '<form action="' . esc\_attr($this->build\_action\_url('s')) . '" method="post"';
1655
1647
if (!empty($attrs\['id'\])) {
newsletter/trunk/subscription/template.php
r2922655
r2955097
22
22
if ($controls->is\_action('test')) {
23
23
24
$users = $module\->get\_test\_users();
24
$users = $this\->get\_test\_users();
25
25
if (count($users) == 0) {
26
26
$controls->errors = \_\_('No test subscribers found.', 'newsletter') . ' <a href="https://www.thenewsletterplugin.com/plugins/newsletter/subscribers-module#test" target="\_blank"><i class="fas fa-info-circle"></i></a>';
…
…
40
40
foreach ($users as $user) {
41
41
$addresses\[\] = $user->email;
42
Newsletter::instance()->mail($user->email, 'Newsletter Messages Template Test', $module\->replace($message, $user));
42
Newsletter::instance()->mail($user->email, 'Newsletter Messages Template Test', $this\->replace($message, $user));
43
43
}
44
44
$controls->messages .= 'Test emails sent to ' . count($users) . ' test subscribers: ' .
Related news
WordPress Newsletter plugin versions 7.8.9 and below suffer from a persistent cross site scripting vulnerability.