Security
Headlines
HeadlinesLatestCVEs

Headline

CVE-2022-0218: Changeset 2656984 for wp-html-mail/trunk/includes/class-template-designer.php – WordPress Plugin Repository

The WP HTML Mail WordPress plugin is vulnerable to unauthorized access which allows unauthenticated attackers to retrieve and modify theme settings due to a missing capability check on the /themesettings REST-API endpoint found in the ~/includes/class-template-designer.php file, in versions up to and including 3.0.9. This makes it possible for attackers with no privileges to execute the endpoint and add malicious JavaScript to a vulnerable WordPress site.

CVE
#web#js#java
  • wp-html-mail/trunk/includes/class-template-designer.php

    r2466288

    r2656984

1

 

<?php if ( ! defined( 'ABSPATH' ) ) exit;

 

1

<?php if (!defined('ABSPATH')) exit;

2

2

3

 

class Haet\_TemplateDesigner {

 

3

class Haet\_TemplateDesigner

 

4

{

4

5

    private $api\_base = 'whm/v3';

5

6

6

 

    function \_\_construct(){

7

 

        add\_action( 'admin\_enqueue\_scripts', \[ $this, 'admin\_page\_scripts\_and\_styles' \] );

8

 

        add\_action( 'rest\_api\_init', \[ $this, 'rest\_api\_init' \] );

 

7

    function \_\_construct()

 

8

    {

 

9

        add\_action('admin\_enqueue\_scripts', \[$this, 'admin\_page\_scripts\_and\_styles'\]);

 

10

        add\_action('rest\_api\_init', \[$this, 'rest\_api\_init'\]);

9

11

10

 

        add\_action( 'admin\_notices', \[ $this, 'showTemplateDesignerUpdateNotice' \] );

 

12

        add\_action('admin\_notices', \[$this, 'showTemplateDesignerUpdateNotice'\]);

11

13

    }

12

 

   

13

 

   

14

 

   

15

 

    public function admin\_page\_scripts\_and\_styles($page){

16

 

        if(strpos($page, 'wp-html-mail') && ( !array\_key\_exists( 'tab', $\_GET ) || $\_GET\['tab'\] =="template" ) ){

17

 

           

 

14

 

15

 

16

 

17

    public function admin\_page\_scripts\_and\_styles($page)

 

18

    {

 

19

        if (strpos($page, 'wp-html-mail') && (!array\_key\_exists('tab', $\_GET) || $\_GET\['tab'\] == "template")) {

 

20

18

21

            // style our options panel like the block editor

19

 

            wp\_enqueue\_style( 'wp-editor' );

20

 

            wp\_enqueue\_style( 'wp-components' );

21

 

            wp\_enqueue\_style( 'forms' );

 

22

            wp\_enqueue\_style('wp-editor');

 

23

            wp\_enqueue\_style('wp-components');

 

24

            wp\_enqueue\_style('forms');

22

25

23

26

            // https://developer.wordpress.org/block-editor/packages/packages-dependency-extraction-webpack-plugin/

24

 

            $script\_path = HAET\_MAIL\_PATH . 'js/template-designer/' . ( $this->isScriptDebug() ? 'dev' : 'dist' ) . '/main.js';

25

 

            $script\_asset\_path = HAET\_MAIL\_PATH . 'js/template-designer/' . ( $this->isScriptDebug() ? 'dev' : 'dist' ) . '/main.asset.php';

26

 

            $script\_asset      = file\_exists( $script\_asset\_path )

27

 

                ? require( $script\_asset\_path )

28

 

                : array( 'dependencies' => array(), 'version' => filemtime( $script\_path ) );

29

 

            $script\_url = HAET\_MAIL\_URL . 'js/template-designer/' . ( $this->isScriptDebug() ? 'dev' : 'dist' ) . '/main.js';

 

27

            $script\_path = HAET\_MAIL\_PATH . 'js/template-designer/' . ($this->isScriptDebug() ? 'dev' : 'dist') . '/main.js';

 

28

            $script\_asset\_path = HAET\_MAIL\_PATH . 'js/template-designer/' . ($this->isScriptDebug() ? 'dev' : 'dist') . '/main.asset.php';

 

29

            $script\_asset      = file\_exists($script\_asset\_path)

 

30

                ? require($script\_asset\_path)

 

31

                : array('dependencies' => array(), 'version' => filemtime($script\_path));

 

32

            $script\_url = HAET\_MAIL\_URL . 'js/template-designer/' . ($this->isScriptDebug() ? 'dev' : 'dist') . '/main.js';

30

33

31

34

            wp\_enqueue\_script('wp-html-mail-template-designer', $script\_url, $script\_asset\['dependencies'\], $script\_asset\['version'\]);

32

35

            wp\_localize\_script('wp-html-mail-template-designer', 'mailTemplateDesigner', \[

33

36

                'restUrl'               => $this->getRestUrl(),

34

 

                'nonce'                 => wp\_create\_nonce( 'wp\_rest' ),

 

37

                'nonce'                 => wp\_create\_nonce('wp\_rest'),

35

38

                'fonts'                 => $this->getAvailableFonts(),

36

39

                'templateLibraryUrl'    => Haet\_Mail()->get\_tab\_url('template-library'),

37

40

                'isMultiLanguageSite'   => Haet\_Mail()->multilanguage->is\_multilanguage\_site(),

38

 

                'currentLanguage'       => Haet\_Mail()->multilanguage->get\_current\_language()

 

41

                'currentLanguage'       => Haet\_Mail()->multilanguage->get\_current\_language(),

 

42

                'nonce'                 => wp\_create\_nonce('wp\_rest')

39

43

            \]);

40

44

            wp\_enqueue\_media();

41

45

            wp\_enqueue\_editor();

42

 

        } 

 

46

        }

43

47

    }

44

48

45

49

46

50

47

 

    public function rest\_api\_init() {

48

 

        register\_rest\_route( $this->api\_base, '/themesettings', array(

49

 

            'methods' => 'GET',

50

 

            'callback' => \[ $this, 'getThemeSettings' \],

51

 

            'permission\_callback' => '\_\_return\_true'

 

51

    public function rest\_api\_init()

 

52

    {

 

53

        register\_rest\_route($this->api\_base, '/themesettings', array(

 

54

            'methods' => 'GET',

 

55

            'callback' => \[$this, 'getThemeSettings'\],

 

56

            'permission\_callback' => function () {

 

57

                return current\_user\_can('manage\_options');

 

58

            }

52

59

        ));

53

 

       

54

 

        register\_rest\_route( $this->api\_base, '/themesettings', array(

55

 

            'methods' => 'POST',

56

 

            'callback' => \[ $this, 'saveThemeSettings' \],

57

 

            'permission\_callback' => '\_\_return\_true'

 

60

 

61

        register\_rest\_route($this->api\_base, '/themesettings', array(

 

62

            'methods' => 'POST',

 

63

            'callback' => \[$this, 'saveThemeSettings'\],

 

64

            'permission\_callback' => function () {

 

65

                return current\_user\_can('manage\_options');

 

66

            }

58

67

        ));

59

68

    }

60

69

61

70

62

 

    public function getThemeSettings(){

 

71

    public function getThemeSettings()

 

72

    {

63

73

        $theme\_options = Haet\_Mail()->get\_theme\_options('default');

64

74

65

 

        return new \\WP\_REST\_Response( $theme\_options );

 

75

        return new \\WP\_REST\_Response($theme\_options);

66

76

    }

67

 

   

68

 

    public function saveThemeSettings( $request ){

69

 

        if( $request->get\_params() ){

 

77

 

78

    public function saveThemeSettings($request)

 

79

    {

 

80

        if ($request->get\_params()) {

70

81

            $theme\_options = $request->get\_params();

71

82

            update\_option('haet\_mail\_theme\_options', $theme\_options);

72

83

        }

73

 

       

 

84

74

85

        $options = Haet\_Mail()->get\_options();

75

86

        $plugin\_options = Haet\_Sender\_Plugin::get\_plugin\_options();

76

87

77

 

        $preview = Haet\_Mail()->get\_preview( Haet\_Sender\_Plugin::get\_active\_plugins(), 'template', $options, $plugin\_options, $theme\_options );

78

 

        return new \\WP\_REST\_Response( \['preview' => $preview\] );

 

88

        $preview = Haet\_Mail()->get\_preview(Haet\_Sender\_Plugin::get\_active\_plugins(), 'template', $options, $plugin\_options, $theme\_options);

 

89

        return new \\WP\_REST\_Response(\['preview' => $preview\]);

79

90

    }

80

91

81

 

    private function getAvailableFonts(){

 

92

    private function getAvailableFonts()

 

93

    {

82

94

        $fonts = Haet\_Mail()->get\_fonts();

83

95

        $fonts\_select\_options = \[\];

84

 

        foreach( $fonts as $value => $label ){

 

96

        foreach ($fonts as $value => $label) {

85

97

            $fonts\_select\_options\[\] = \[

86

98

                'value' => $value,

…

…

 

88

100

            \];

89

101

        }

90

 

        return $fonts\_select\_options;

 

102

        return $fonts\_select\_options;

91

103

    }

92

104

93

105

94

106

95

 

    private function getRestUrl( $endpoint = '' ) {

96

 

        return get\_rest\_url( null, $this->api\_base . '/' . $endpoint );

 

107

    private function getRestUrl($endpoint = '')

 

108

    {

 

109

        return get\_rest\_url(null, $this->api\_base . '/' . $endpoint);

97

110

    }

98

 

   

99

111

100

 

    public function isScriptDebug() {

101

 

        return defined('SCRIPT\_DEBUG') && SCRIPT\_DEBUG === true;

 

112

 

113

    public function isScriptDebug()

 

114

    {

 

115

        return defined('SCRIPT\_DEBUG') && SCRIPT\_DEBUG === true;

102

116

    }

103

 

   

104

 

    public function isWPVersionCompatible(){

 

117

 

118

    public function isWPVersionCompatible()

 

119

    {

105

120

        // our new JavaScript based editor relies on some WordPress React components available in 5.4

106

 

        return version\_compare( get\_bloginfo( 'version' ), '5.4', '>=' );

 

121

        return version\_compare(get\_bloginfo('version'), '5.4', '>=');

107

122

    }

108

123

…

…

 

112

127

     \* either to tell the users to check their settings in the new editor or to tell them to better update WP to see the new editor

113

128

     \*/

114

 

    public function showTemplateDesignerUpdateNotice(){

115

 

        if( $this->isWPVersionCompatible() ){

 

129

    public function showTemplateDesignerUpdateNotice()

 

130

    {

 

131

        if ($this->isWPVersionCompatible()) {

116

132

            $options = Haet\_Mail()->get\_options();

117

 

            if( !array\_key\_exists( 'user\_checked\_settings\_in\_v3', $options ) || !$options\['user\_checked\_settings\_in\_v3'\] ){

118

 

                ?>

 

133

            if (!array\_key\_exists('user\_checked\_settings\_in\_v3', $options) || !$options\['user\_checked\_settings\_in\_v3'\]) {

 

134

?>

119

135

                <div class="notice notice-success">

120

 

                    <p><?php echo sprintf( \_\_( 'You successfully upgraded to our <strong>new email editor</strong>! Please <a href="%1$s">review your settings</a> to make sure everything still looks as expected.', 'wp-html-mail' ), get\_admin\_url(null,'options-general.php?page=wp-html-mail') ); ?></p>

 

136

                    <p><?php echo sprintf(\_\_('You successfully upgraded to our <strong>new email editor</strong>! Please <a href="%1$s">review your settings</a> to make sure everything still looks as expected.', 'wp-html-mail'), get\_admin\_url(null, 'options-general.php?page=wp-html-mail')); ?></p>

121

137

                </div>

122

 

                <?php

 

138

            <?php

123

139

            }

124

 

        }elseif( array\_key\_exists( 'page', $\_GET ) && $\_GET\['page'\] == "wp-html-mail" ){

 

140

        } elseif (array\_key\_exists('page', $\_GET) && $\_GET\['page'\] == "wp-html-mail") {

125

141

            ?>

126

142

            <div class="notice notice-warning">

127

 

                <p><?php \_e( 'In order to use our <strong>new email editor</strong> you need to upgrade to WordPress 5.4 or higher. In the meanwhile you can still use our classic settings pages.', 'wp-html-mail' ); ?></p>

 

143

                <p><?php \_e('In order to use our <strong>new email editor</strong> you need to upgrade to WordPress 5.4 or higher. In the meanwhile you can still use our classic settings pages.', 'wp-html-mail'); ?></p>

128

144

            </div>

129

 

            <?php

 

145

<?php

130

146

        }

131

147

    }

CVE: Latest News

CVE-2023-50976: Transactions API Authorization by oleiman · Pull Request #14969 · redpanda-data/redpanda
CVE-2023-6905
CVE-2023-6903
CVE-2023-6904
CVE-2023-3907