Versa Concerto is a widely used network security and SD-WAN orchestration platform, designed to provide seamless policy management, analytics, and automation for enterprises. With a growing customer base that includes large enterprises, service providers, and government entities, the security of this platform is critical. Given its extensive adoption and potential exposure to external threats, we initiated research to assess its security posture and uncover possible vulnerabilities.
Our research led to the discovery of multiple critical security flaws in Versa Concerto’s deployment. In this blog, we explore multiple vulnerabilities discovered in Versa Concerto, a Spring Boot-based application deployed via Docker containers and routed through Traefik.
These vulnerabilities, when chained together, could allow an attacker to fully compromise both the application and the underlying host system. This research highlights how small misconfigurations in modern cloud-based deployments can escalate into severe security risks, particularly for platforms handling sensitive network configurations and enterprise data.
Versa Concerto is deployed using multiple Docker containers, with the key ones being:
To understand the appliance’s routing, we start by analyzing the Traefik container. The Traefik container listens on ports 80/443, serving as the entry point for client requests. Based on location configurations, incoming requests are routed to either core-service or web-service. Both of these containers deploys Spring Boot embedded applications. We decompiled their code to audit their authentication mechanisms.
Our primary focus was the AuthenticationFilter class, which is typically responsible for handling authentication in Spring applications. Upon reviewing the decompiled code, we observed that certain paths were explicitly excluded from authentication:
However, we noticed an inconsistency between the authentication check and the actual URL being processed.
Bypassing authentication is possible using a request URL like - /portalapi/v1/users/username/admin;%2fv1%2fping
After discovering the authentication bypass, we analyzed the authorization mechanisms across the services. Most endpoints enforced strict authorization checks by validating the user’s assigned role. As a result, we were unable to access the majority of critical endpoints within the core-service. Only a handful of endpoints were exposed without authorization checks, but they did not provide a viable path for privilege escalation.
Shifting our focus to the web-service, we identified an endpoint related to package uploads /portalapi/v1/package/spack/upload
that appeared to be vulnerable to arbitrary file writes. The logic within this endpoint suggested that we could write files to an arbitrary location on the system, making it a promising vector for further exploitation.
Despite the apparent vulnerability, there was a significant obstacle. While the file was successfully written to disk at [1] and [2], it was immediately deleted inside a try/catch block at [4] an [5]. If any exception occurred during execution, the application would trigger a cleanup process that removed the uploaded file. Specifically, right after writing the file at [1] and [2], the code tried to retrieve the access token from current user context at [3]. This check resulted in a null pointer exception, which in turn caused the deletion of our written file at [4] and [5].
Even though the file was being deleted almost instantly, there's a brief window of time in which an arbitrary file write was possible. This introduced the possibility of a race condition, which could potentially be exploited to use the written file to cause remote code execution.
Initially, we considered exploiting the vulnerability by writing a web shell to the web root. However, since this was a Spring Boot embedded application, it did not follow the traditional file-serving structure, meaning we couldn’t simply drop a shell and execute it as we would in a typical web application.
After ruling out this approach, we explored the possibility of leveraging cron jobs for execution. However, upon further investigation, we discovered that the web-service container did not have cron set up, eliminating this option as well. This forced us to rethink our strategy and look for alternative execution methods.
We then utilized an LD_PRELOAD trick to achieve remote code execution. Our approach involved overwriting ../../../../../../etc/ld.so.preload with a path pointing to /tmp/hook.so. Simultaneously, we uploaded /tmp/hook.so, which contained a compiled C binary for a reverse shell. Since our request triggered two file write operations, we leveraged this to ensure that both files were written within the same request.
Once these files were successfully written, any command execution on the system while both persisted would result in the execution of /tmp/hook.so, thereby giving us a reverse shell. While looking for a suitable trigger, we observed that a curl command was being executed every 10 seconds within the web-service container to check the container’s health status.
Knowing this, we continuously sent requests to write both ../../../../../../etc/ld.so.preload and /tmp/hook.so in a way that created a race condition. Our goal was to ensure that at the exact moment the health check executed, both files would be present on the system. Once all three conditions aligned—the presence of ld.so.preload, the malicious shared object, and a triggered system command—we successfully achieved remote code execution (RCE).
While analyzing the authentication filter, we noticed that access control for certain endpoints, including the Spring Boot Actuator endpoints, relied on the presence of the X-Real-Ip
header. Specifically, if this header was set, the application performed an additional check to determine whether access should be granted.
This logic ensures that if an external request contains X-Real-Ip
, and the request URI contains /actuator, access is explicitly denied.
As previously mentioned, client requests are initially sent to the Traefik reverse proxy, which then forwards them to the Spring Boot applications running on Tomcat. Traefik automatically sets the X-Real-Ip
header when forwarding requests, meaning that external requests are always flagged as originating from an external source.
However, we identified a hop-by-hop header handling vulnerability in the version of Traefik in use. This issue, documented in Traefik Security Advisory GHSA-62c8-mh53-4cqv, allows an attacker to drop specific headers that would otherwise be added by Traefik.
By leveraging this issue, we can drop the X-Real-Ip header from the forwarded request. Without this header, the access control logic is never triggered, and we can access restricted actuator endpoints.
By setting Connection: X-Real-IP
, we instruct Traefik to drop the X-Real-Ip header before forwarding the request to the backend. Since the authentication logic depends on this header’s presence, the request bypasses the security check, granting us direct access to the /actuator endpoints.
This allows to get plain text credentials via downloading heap-dump or/else directly access logs via /portalapi/actuator/traces
that would directly disclose logged user session tokens and login into appliance as admin. Once you become an admin, there are various routes available to get Remote Code Execution such as by uploading a security package.
We also observed a critical misconfiguration that allowed us to escape from web-service docker container and gain execution on the host machine.
On Ubuntu systems, a default cron job exists under /etc/cron.d/popularity-contest
, designed to gather usage statistics on installed Debian packages. This cron job executes every hour on the host machine, running a shell script that makes use of commands such as test, touch, and cd.
Ordinarily, this wouldn’t pose a security risk. However, in this case, we discovered that the core-service docker container had /usr/bin/
and /bin/
directories directly mapped to the host’s filesystem. This meant that any changes made to binaries within the container would also apply to the host system.
With root access inside the container, we leveraged this misconfiguration to overwrite one of the frequently used binaries (test) with a malicious shell script. This ensured that when the popularity-contest cron job executed on the host, our payload would be triggered.
With full control over the mapped system binaries, we replaced /usr/bin/test with a script that initiated a reverse shell:
Make the script executable and wait for the hourly cron job to execute. As expected, when the cron job ran, it called our malicious test binary, granting us a reverse shell on the Concerto host system.
Versa Concerto API Auth Bypass:
Versa Concerto Actuator Auth Bypass:
While we await official patches from the Versa Concerto team, organizations can implement temporary remediation measures at the reverse proxy or Web Application Firewall (WAF) levels to mitigate the risk posed by the identified authentication bypass vulnerabilities. Here are two recommended actions:
;
) in the URL path. This measure will help prevent exploitation of the URL decoding inconsistency that allows authentication bypass.Connection
header contains the value X-Real-Ip
(case insensitive). This will mitigate the vulnerability that allows unauthorized access to Spring Boot Actuator endpoints by manipulating the X-Real-Ip
header.By applying these temporary measures, organizations can reduce the risk of exploitation until official patches are released. It is crucial to monitor network traffic and logs for any suspicious activity and to keep security teams informed of these interim protections.
Despite our efforts to responsibly disclose these issues to the Versa team, including multiple follow-ups over the past 90 days, we have not received any response or indication of a forthcoming patch. As a result, we are compelled to publish our findings to raise awareness and prompt the necessary actions to secure affected systems.
Here's a timeline table of the vulnerability disclosure process:
Date | Event |
---|---|
Feb 13, 2025 | Vulnerabilities reported to the Versa Concerto team with a 90-day disclosure timeline. |
Feb 15, 2025 | Acknowledgement received; team requested additional info and mentioned eagerness to patch. |
Feb 17, 2025 | Additional details provided; team stated they would patch all affected releases soon. |
Mar 28, 2025 | Team replied, indicating hot fixes and patches would be pushed on April 7th. |
Apr 23, 2025 | Follow-up email sent regarding hot fixes and patches; no response received. |
May 12, 2025 | Another follow-up email sent; still no response. |
May 13, 2025 | 90-day disclosure timeline ended. |
May 21, 2025 | Published this blog post. |
In conclusion, our research into the Versa Concerto platform has uncovered several critical vulnerabilities that pose significant security risks to enterprises relying on this technology. These vulnerabilities, ranging from authentication bypasses to remote code execution and container escapes, highlight the potential for severe exploitation if left unaddressed.
We urge organizations using Versa Concerto to implement additional security measures and remain vigilant until official patches are released. Our hope is that this disclosure will expedite the resolution process and enhance the overall security posture of the platform.
Nuclei template to detect this vulnerability is now part of the ProjectDiscovery Cloud platform, so you can automatically detect this vulnerability across your infrastructure. We also offer free monthly scans to help you detect emerging threats, covering all major vulnerabilities on an ongoing basis, plus a complete 30-day trial available to business email addresses.
For any questions, reach us at [email protected]