Security
Headlines
HeadlinesLatestCVEs

Headline

CVE-2021-4074: Changeset 2653041 for whmcs-bridge – WordPress Plugin Repository

The WHMCS Bridge WordPress plugin is vulnerable to Stored Cross-Site Scripting via the cc_whmcs_bridge_url parameter found in the ~/whmcs-bridge/bridge_cp.php file which allows attackers to inject arbitrary web scripts, in versions up to and including 6.1. Due to missing authorization checks on the cc_whmcs_bridge_add_admin function, low-level authenticated users such as subscribers can exploit this vulnerability.

CVE
#vulnerability#web#js

whmcs-bridge/trunk/bridge.init.php

r2535021

r2653041

4

4

if (!defined(‘WHMCS_BRIDGE_PAGE’)) define(‘WHMCS_BRIDGE_PAGE’,’WHMCS’);

5

5

6

define(“CC_WHMCS_BRIDGE_VERSION","6.1”);

6

define(“CC_WHMCS_BRIDGE_VERSION","6.3”);

7

7

8

8

if (!defined(‘PHP_VERSION_ID’)) {

180

180

181

181

function cc_whmcs_bridge_checks() {

182

if (!wp\_verify\_nonce($\_POST\['nonce'\], 'whmcs\_bridge\_check\_bridge') ){

183

    die('Permission Denied.');

184

}

185

182

186

$whmcs\_url = get\_option('cc\_whmcs\_bridge\_url');

183

187

494

498

cc\_whmcs\_log(0, '\[URL '.$ref.'\] '.$http);

495

499

500

if (stristr($http, 'viewinvoice.php') !== false && stristr($http, 'ccce=viewinvoice') !== false) {

501

    $http = str\_replace("&ccce=viewinvoice", "", $http);

502

    cc\_whmcs\_log(0, '\[URL '.$ref.'\] '.$http);

503

}

504

496

505

if (strstr($http, '?a=checkout') !== false && isset($\_REQUEST\['action'\]) && $\_REQUEST\['action'\] == 'doPayment') {

497

506

    $http = str\_replace('?a=checkout', '?a=complete', $http);

544

553

                stristr($\_REQUEST\['js'\], '.png') !== false ||

545

554

                stristr($\_REQUEST\['js'\], '.jpeg') !== false ||

546

                stristr($\_REQUEST\['js'\], '.gif') !== false

555

                stristr($\_REQUEST\['js'\], '.gif') !== false ||

556

                stristr($\_REQUEST\['js'\], '.svg') !== false

547

557

            ))

548

558

    ) {

580

590

            case "jpeg":

581

591

            case "jpg": $ctype="image/jpeg"; break;

592

            case "svg": $ctype="image/svg+xml"; break;

582

593

            default: $ctype="image"; break;

583

594

        }

whmcs-bridge/trunk/bridge.php

r2535021

r2653041

5

5

Description: WHMCS Bridge is a plugin that integrates the powerful WHMCS support and billing software with WordPress.

6

6

Author: globalprogramming

7

Version: 6.1

7

Version: 6.3

8

8

Author URI: http://i-plugins.com/

9

9

*/

whmcs-bridge/trunk/bridge_cp.php

r2216981

r2653041

101

101

function cc_whmcs_bridge_add_admin() {

102

102

103

global $cc\_whmcs\_bridge\_shortname;

104

105

$cc\_whmcs\_bridge\_options = cc\_whmcs\_bridge\_options();

106

107

if (isset($\_GET\['page'\]) && ($\_GET\['page'\] == "cc-ce-bridge-cp")) {

108

    if (isset($\_REQUEST\['action'\]) && 'install' == $\_REQUEST\['action'\]) {

109

        delete\_option('cc\_whmcs\_bridge\_log');

110

        delete\_option('cc\_whmcs\_bridge\_sso\_local\_key');

111

112

        foreach ($cc\_whmcs\_bridge\_options as $value) {

113

            if (isset($value\['id'\]) && !empty($\_REQUEST\[$value\['id'\]\])) {

114

                $post\_value = $\_REQUEST\[$value\['id'\]\];

115

                if ($value\['type'\] == 'password' && function\_exists('whmcs\_bridge\_sso\_password\_scrambler')) {

116

                    $post\_value = whmcs\_bridge\_sso\_password\_scrambler($post\_value, false);

103

global $cc\_whmcs\_bridge\_shortname,$current\_user;

104

105

if (in\_array('administrator', $current\_user->roles)) {

106

    $cc\_whmcs\_bridge\_options = cc\_whmcs\_bridge\_options();

107

108

    if (isset($\_GET\['page'\]) && ($\_GET\['page'\] == "cc-ce-bridge-cp")) {

109

        if (isset($\_REQUEST\['action'\]) && 'install' == $\_REQUEST\['action'\]) {

110

            check\_admin\_referer('cc\_bridge\_update\_settings\_submit');

111

112

            delete\_option('cc\_whmcs\_bridge\_log');

113

            delete\_option('cc\_whmcs\_bridge\_sso\_local\_key');

114

115

            foreach ($cc\_whmcs\_bridge\_options as $value) {

116

                if (isset($value\['id'\]) && !empty($\_REQUEST\[$value\['id'\]\])) {

117

                    $post\_value = $\_REQUEST\[$value\['id'\]\];

118

                    if ($value\['type'\] == 'password' && function\_exists('whmcs\_bridge\_sso\_password\_scrambler')) {

119

                        $post\_value = whmcs\_bridge\_sso\_password\_scrambler($post\_value, false);

120

                    }

121

                    update\_option($value\['id'\], $post\_value);

122

                } else if (isset($value\['id'\]) && empty($\_REQUEST\[$value\['id'\]\])) {

123

                    delete\_option($value\['id'\]);

117

124

                }

118

                update\_option($value\['id'\], $post\_value);

119

            } else if (isset($value\['id'\]) && empty($\_REQUEST\[$value\['id'\]\])) {

120

                delete\_option($value\['id'\]);

121

125

            }

126

127

            if (isset($\_REQUEST\['cc\_whmcs\_bridge\_sso\_cache'\])) {

128

                foreach (glob(dirname(\_\_FILE\_\_) . '/cache/\*') as $file) {

129

                    @unlink($file);

130

                }

131

                $xtrarg = '&whmcs\_clear=true';

132

            } else {

133

                $xtrarg = '';

134

            }

135

136

            cc\_whmcs\_bridge\_install();

137

            if (function\_exists('cc\_whmcs\_bridge\_sso\_update'))

138

                cc\_whmcs\_bridge\_sso\_update();

139

140

            header("Location: " . get\_admin\_url() . "options-general.php?page=cc-ce-bridge-cp&installed=true" . $xtrarg);

141

            die;

122

142

        }

123

124

        if (isset($\_REQUEST\['cc\_whmcs\_bridge\_sso\_cache'\])) {

125

            foreach (glob(dirname(\_\_FILE\_\_).'/cache/\*') as $file) {

126

                @unlink($file);

127

            }

128

            $xtrarg = '&whmcs\_clear=true';

129

        } else {

130

            $xtrarg = '';

143

    }

144

145

    add\_options\_page(WHMCS\_BRIDGE, WHMCS\_BRIDGE, 'administrator', 'cc-ce-bridge-cp', 'cc\_whmcs\_bridge\_admin');

146

}

147

}

148

149

function cc_whmcs_bridge_admin() {

150

151

global $cc\_whmcs\_bridge\_shortname, $current\_user;

152

153

if (in\_array('administrator', $current\_user->roles)) {

154

    $controlpanelOptions = cc\_whmcs\_bridge\_options();

155

156

    if (isset($\_REQUEST\['installed'\]))

157

        echo '<div id="message" class="updated fade"><p><strong>' . WHMCS\_BRIDGE . ' installed.</strong></p></div>';

158

    if (isset($\_REQUEST\['error'\])) {

159

        echo '<div id="message" class="updated fade"><p>The following error occured: <strong>' . $\_REQUEST\['error'\] . '</strong></p></div>';

160

        if (strstr($\_REQUEST\['error'\], 'parsing')) {

161

            echo '<div id="message" class="updated fade"><p>Parse errors occur when the bridge is unable to connect to your WHMCS API, for more information please <a href="http://i-plugins.com/whmcs/knowledgebase/1082/I-am-getting-intermittent-DOMDocument-or-loadXML-errors-showing-up-on-the-bridge.html" target="\_blank"><strong>click here</strong></a></p></div>';

162

131

163

        }

132

133

        cc\_whmcs\_bridge\_install();

134

        if (function\_exists('cc\_whmcs\_bridge\_sso\_update'))

135

            cc\_whmcs\_bridge\_sso\_update();

136

137

        header("Location: ".get\_admin\_url()."options-general.php?page=cc-ce-bridge-cp&installed=true".$xtrarg);

138

        die;

139

164

    }

140

}

141

142

add\_options\_page(WHMCS\_BRIDGE, WHMCS\_BRIDGE, 'administrator', 'cc-ce-bridge-cp','cc\_whmcs\_bridge\_admin');

165

166

    ?>

167

    <script>

168

        jQuery(function () {

169

            jQuery("#bridgetabs").tabs();

170

        });

171

    </script>

172

173

    <div class="wrap">

174

        <h2><b><?php echo WHMCS\_BRIDGE; ?></b></h2>

175

        <div id="bridgetabs" style="width:68%;float:left;">

176

177

            <ul>

178

                <li><a href="#bridgetabs-1"><i class="fa fa-cog"></i> Settings</a></li>

179

                <li><a href="#bridgetabs-2"><i class="fa fa-bug"></i> Log</a></li>

180

                <li><a href="#bridgetabs-3"><i class="fa fa-refresh"></i> Sync</a></li>

181

                <li><a href="#bridgetabs-4"><i class="fa fa-info"></i> Help</a></li>

182

            </ul>

183

184

            <div id="bridgetabs-1">

185

                <?php require(dirname(\_\_FILE\_\_) . '/pages/settings.php'); ?>

186

            </div>

187

            <div id="bridgetabs-2">

188

                <?php require(dirname(\_\_FILE\_\_) . '/pages/log.php'); ?>

189

            </div>

190

            <div id="bridgetabs-3">

191

                <?php require(dirname(\_\_FILE\_\_) . '/pages/sync.php'); ?>

192

            </div>

193

            <div id="bridgetabs-4">

194

                <?php require(dirname(\_\_FILE\_\_) . '/pages/help.php'); ?>

195

            </div>

196

197

        </div> <!-- end bridgetabs -->

198

        <div style="width:30%;float:right;">

199

            <?php

200

            require(dirname(\_\_FILE\_\_) . '/support-us.inc.php');

201

            zing\_support\_us('whmcs-bridge', 'whmcs-bridge', 'cc-ce-bridge-cp', CC\_WHMCS\_BRIDGE\_VERSION);

202

            ?>

203

        </div>

204

    </div> <!-- end wrap -->

205

    <?php

206

}

143

207

}

144

208

145

function cc_whmcs_bridge_admin() {

146

147

global $cc\_whmcs\_bridge\_shortname;

148

149

$controlpanelOptions=cc\_whmcs\_bridge\_options();

150

151

if (isset($\_REQUEST\['installed'\])) echo '<div id="message" class="updated fade"><p><strong>'.WHMCS\_BRIDGE.' installed.</strong></p></div>';

152

if (isset($\_REQUEST\['error'\])) {

153

    echo '<div id="message" class="updated fade"><p>The following error occured: <strong>'.$\_REQUEST\['error'\].'</strong></p></div>';

154

    if (strstr($\_REQUEST\['error'\], 'parsing')) {

155

        echo '<div id="message" class="updated fade"><p>Parse errors occur when the bridge is unable to connect to your WHMCS API, for more information please <a href="http://i-plugins.com/whmcs/knowledgebase/1082/I-am-getting-intermittent-DOMDocument-or-loadXML-errors-showing-up-on-the-bridge.html" target="\_blank"><strong>click here</strong></a></p></div>';

156

157

    }

158

}

159

160

?>

161

<script>

162

    jQuery(function() {

163

        jQuery("#bridgetabs").tabs();

164

    });

165

</script>

166

167

<div class="wrap">

168

    <h2><b><?php echo WHMCS\_BRIDGE; ?></b></h2>

169

    <div id="bridgetabs" style="width:68%;float:left;">

170

171

        <ul>

172

            <li><a href="#bridgetabs-1"><i class="fa fa-cog"></i> Settings</a></li>

173

            <li><a href="#bridgetabs-2"><i class="fa fa-bug"></i> Log</a></li>

174

            <li><a href="#bridgetabs-3"><i class="fa fa-refresh"></i> Sync</a></li>

175

            <li><a href="#bridgetabs-4"><i class="fa fa-info"></i> Help</a></li>

176

        </ul>

177

178

        <div id="bridgetabs-1">

179

            <?php require(dirname(\_\_FILE\_\_).'/pages/settings.php');?>

180

        </div>

181

        <div id="bridgetabs-2">

182

            <?php require(dirname(\_\_FILE\_\_).'/pages/log.php');?>

183

        </div>

184

        <div id="bridgetabs-3">

185

            <?php require(dirname(\_\_FILE\_\_).'/pages/sync.php');?>

186

        </div>

187

        <div id="bridgetabs-4">

188

            <?php require(dirname(\_\_FILE\_\_).'/pages/help.php');?>

189

        </div>

190

191

    </div> <!-- end bridgetabs -->

192

    <div style="width:30%;float:right;">

193

        <?php

194

        require(dirname(\_\_FILE\_\_).'/support-us.inc.php');

195

        zing\_support\_us('whmcs-bridge','whmcs-bridge','cc-ce-bridge-cp',CC\_WHMCS\_BRIDGE\_VERSION);

196

        ?>

197

    </div>

198

</div> <!-- end wrap -->

199

<?php

200

}

201

202

209

add_action('admin_menu’, ‘cc_whmcs_bridge_add_admin’); ?>

whmcs-bridge/trunk/includes/cpedit.inc.php

r2083858

r2653041

11

11

            if (function\_exists('whmcs\_bridge\_sso\_password\_scrambler') && $value\['type'\] == 'password') {

12

12

                $text\_value = whmcs\_bridge\_sso\_password\_scrambler($text\_value, true);

13

            } else if ($value\['type'\] != 'password') {

14

                $text\_value = htmlentities(stripslashes($text\_value));

13

15

            }

14

16

            ?>

whmcs-bridge/trunk/includes/http.class.php

r2535021

r2653041

417

417

418

418

    if (count($this->post) > 0) {

419

        cc\_whmcs\_log(0, "HTTP Method POST 2");

419

420

        curl\_setopt($ch, CURLOPT\_POST, 1); // set POST method

420

421

        $post = "";

445

446

    } else if (stristr($url, 'two-factor') !== false && stristr($url, 'totp') === false) {

446

447

        curl\_setopt($ch, CURLOPT\_CUSTOMREQUEST, "POST"); // set POST method

448

        cc\_whmcs\_log(0, "HTTP customrequest Method POST 1");

447

449

    }

448

450

461

463

            cc\_whmcs\_log(0, 'Posting as \[1\]:  '.json\_encode($pfields));

462

464

        }

465

463

466

    } else if (!empty($rawPost)) {

464

467

        if (in\_array(substr($rawPost, 0, 1),  \['\[', '{', '"'\])) {

470

473

471

474

        cc\_whmcs\_log(0, "Posting RAW: ".$rawPost);

472

    } else if (strtolower($\_SERVER\['REQUEST\_METHOD'\]) == "post") {

475

        cc\_whmcs\_log(0, "HTTP customrequest Method POST 2");

476

    } else if (strtolower($\_SERVER\['REQUEST\_METHOD'\]) == "post" && strstr($url, 'viewinvoice.php') === false) {

473

477

        curl\_setopt($ch, CURLOPT\_POST, 1); // set POST method

478

        cc\_whmcs\_log(0, "HTTP Method POST 1");

474

479

    }

475

480

629

634

                if (empty($rawPost))

630

635

                    $bounce = true;

631

                $redir = $this->\_protocol . '://' .$this->\_host .$this->\_path. $redir;

636

                if (stristr($this->\_path, '/user/accounts') !== false)

637

                    $redir = $this->\_protocol . '://' .$this->\_host .'/'. $redir;

638

                else

639

                    $redir = $this->\_protocol . '://' .$this->\_host .$this->\_path. $redir;

632

640

                $this->debug(0, 'S4.1: '.$redir);

633

641

            } else {

whmcs-bridge/trunk/includes/parser.inc.php

r2535021

r2653041

278

278

$buffer = str\_replace('url: \\'modules/', 'url: \\''.$bridge\_url.'/modules/', $buffer);

279

279

280

280

281

// Twitter feed

281

282

$buffer = str\_replace('?ccce=index&ajax=1?rp=', '?ccce=index&ajax=1&rp=', $buffer);

314

315

// whmcsBaseUrl

315

316

$buffer = str\_replace("whmcsBaseUrl+\\"/index.php?rp=\\"", "whmcsBaseUrl+\\"{$home}?ccce=index&rp=\\"", $buffer);

317

//whmcsBaseUrl+"/cart"

316

318

317

319

// Payment Gateways

328

330

\], $buffer);

329

331

332

$buffer = str\_replace('whmcsBaseUrl+"/cart"', 'whmcsBaseUrl+"'.$home.'?ccce=cart"', $buffer);

330

333

331

334

if (is\_numeric($cache\_setting) && $cache\_setting > 0 && (

999

1002

1000

1003

// whmcsBaseUrl

1001

$buffer = str\_replace("whmcsBaseUrl = ", "whmcsBaseUrl = \\"\\"; //", $buffer);

1004

$buffer = str\_replace("whmcsBaseUrl = ", "whmcsBaseUrl = \\"{$home}\\"; //", $buffer);

1002

1005

1003

1006

// SolusVM

whmcs-bridge/trunk/pages/help.php

r1890489

r2653041

22

22

<h2>Check my installation</h2>

23

23

<p>

24

<button class="button-positive" onclick="jQuery('#whmcs-check-results').html(''); jQuery('#whmcs-check').show(); jQuery.post(ajaxurl, { action: 'check\_bridge' }, function(data) { jQuery('#whmcs-check-results').html(data); jQuery('#whmcs-check').hide(); }); return false;">

24

<button class="button-positive" onclick="jQuery('#whmcs-check-results').html('');

25

                                jQuery('#whmcs-check').show();

26

                                jQuery.post(ajaxurl, { action: 'check\_bridge', nonce: '<?= wp\_create\_nonce('whmcs\_bridge\_check\_bridge') ?>' }, function(data) { jQuery('#whmcs-check-results').html(data); jQuery('#whmcs-check').hide(); }); return false;">

25

27

    Check for problems with my setup

26

28

</button>

whmcs-bridge/trunk/pages/settings.php

r1440324

r2653041

4

4

?>

5

5

<form method="post">

6

<?php wp\_nonce\_field( 'cc\_bridge\_update\_settings\_submit' ); ?>

7

6

8

<div class="alert success">

7

9

  <span class="closebtn" onclick="this.parentElement.style.display='none';">&times;</span>

whmcs-bridge/trunk/readme.txt

r2535021

r2653041

4

4

Tags: WHMCS, hosting, support, billing, integration

5

5

Requires at least: 5.0

6

Tested up to: 5.7.2

7

Stable tag: 6.1

6

Tested up to: 5.8.2

7

Stable tag: 6.3

8

8

License: GPLv3

9

9

77

77

78

78

== Changelog ==

79

80

= 6.3 =

81

* Fixed checkout redirect issue

82

* Security upgrades for admin panel

83

84

= 6.2 =

85

* Fixed issue with svg images not rendering due to incorrect headers

86

* Fixed 400 Bad Request issue on Invoice view

79

87

80

88

= 6.1 =

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