Our Research Story: Unauthenticated RCE in Ametys CMS 4.7.x
Our Research Story: Unauthenticated RCE in Ametys CMS 4.7.x


Introduction
Our R&D team recently uncovered a previously unknown unauthenticated Remote Code Execution (RCE) vulnerability affecting Ametys CMS versions 4.7.x up to 4.7.16. Ametys is a widely adopted open-source content management system, powering both educational institutions and enterprise portals.
The issue was discovered during a private penetration test, where we encountered an instance running Ametys CMS 4.7.x. Despite the absence of any public CVEs, we were curious: could we still find a way in?
The short answer: yes. By chaining together three subtle flaws, we achieved full system compromise without authentication.
The authentication mechanism for the Callable method
Ametys CMS comes with several built-in plugins, one of which is core-ui. Within org/ametys/runtime/plugins/core-ui/sitemap.xmap, we can see that any request made to /plugins/core-ui/servercomm/messages.xml is handled by the dispatcher.
Digging deeper into the request flow, we noticed that the client-call action was a promising entry point. This is handled by the class org.ametys.core.ui.ExecuteClientCallsAction
In org.ametys.core.ui.ExecuteClientCallsAction, when a method is invoked, it checks whether the method is annotated with @Callable. If so, it passes through the _checkAccess function. If a non-empty "callable right" is defined, the system verifies whether the current user has the necessary permissions to execute the method.
In short, for example, we can call the method org.ametys.plugins.core.right.profile.ProfileDAO#getProfile without permission, but we need Runtime_Rights_Rights_Profile_Handle to call org.ametys.plugins.core.right.profile.ProfileDAO#addProfile.
All the methods are invoked by reflection
In short: methods marked as @Callable could be invoked remotely, and only some of them enforced proper permission checks. That was the first weak spotS
From Scheduler to RCE
Ametys groups users into User Populations (e.g., System admins and regular users).
When an admin signs in, they can schedule tasks including system commands via the Scheduler.
Inside the admin UI, the Scheduler exposes a task creation flow that ultimately triggers the client-call action we examined earlier.
And exactly, it calls the client-call action we mentioned.
Following the request chain, the Scheduler lands on org.ametys.plugins.core.schedule.Scheduler#add. There are two overloaded add methods.
The second method requires the CORE_Rights_TaskScheduler permission, whereas the first one does not. The second method, which requires authentication, is the one we normally invoke using an administration account. However, since it internally calls the first method - which does not require authentication and accepts fewer parameters - we can craft a request to directly call the first method and create a new scheduler task without needing to authenticate.
But unfortunately, inside the first method, it still has a check
Takeaway: The Scheduler path exposes an unprotected add overload. If we can impersonate a user, it turns into unauthenticated RCE.
Authentication Bypass: Turning a Datasource into Access
One more @Callable stood out org.ametys.core.datasource.DataSourceClientInteraction#addDataSource.
This function let us create a new datasource without requiring any permissions.
By adding valid credentials into a new datasource, we could in theory log in as another user.
The default datasource relies on a local Derby DB. With addDataSource + getDataSource (also unrestricted), we could create and list datasources freely.
(For clarity, we created a new local datasource by copying the internal DB — avoiding disruption to the instance.)
We can see a new datasource is added (id SQL-mdpgdvm3), and it appears in the list of datasources
At first glance, this looked like enough to log in with accounts from the new datasource.
But the User Populations list only showed the default entries. The new datasource wasn’t actually integrated.
Even we had the datasource
Digging further, we realized datasources are activated only when declared in
webapps/site/WEB-INF/data/config/user-populations.xml.
By editing this file, we could bind our new datasource to a fresh user population.
The syntax is quite clear: define a userPopulation id, assign a label, and config the datasource.
Initially disappointing — until we found another loose @Callable:
org.ametys.core.file.FileHelper#saveFile.
This method can overwrite existing files under <installation_folder>/webapps/site.
Just enough to update user-populations.xml.
It retrieves the filename and checks whether the source exists. It can only modify existing files within <installation_folder>/webapps/site, but that’s sufficient for our current needs.
And that file is changed
By saving our changes, a new “RCE population” appeared on the login screen.
Logging in with any valid account from this datasource showed a 403 but crucially, that session was sufficient to trigger the unprotected Scheduler method and achieve RCE.
After beautify
This config works only for the normal population. We cannot add or change the System population.
And “RCE population” will appear in the list to log in
After logging in with any account, we will see the 403 page
But it is enough for us to create a new scheduler as we talked before.
Impact
- Unauthenticated RCE across all Ametys CMS versions ≤ 4.7.16.
- Exploitation required no prior knowledge of valid users.
- Attack chain combined three separate weaknesses:
- Unrestricted @Callable methods
- Insecure Scheduler overload
- File overwrite via saveFile
Remediation
The Ametys team responded quickly and responsibly after our disclosure.
- Starting from Ametys CMS 4.8.0, sensitive @Callable methods now enforce proper access rights.
- The vulnerable chain is no longer exploitable.
Recommendation:
Upgrade immediately to version 4.8.0 or later. Any version below 4.8.0 should be considered vulnerable and unsafe for production environments.
Need help securing your organization?
Vulnerabilities like this Ametys CMS RCE highlight why proactive security assessments are essential. At Cenobe, we specialize in finding these security gaps before attackers do.
Our Services:
- Penetration Testing - Comprehensive testing of web apps, networks, cloud, and mobile applications
- Red Team Operations - Real-world attack simulations to test your defenses
- External Attack Surface Management - Our Morpheus platform continuously monitors your external perimeter for vulnerabilities
- Source code audit - In-depth review of your application’s source code to identify security vulnerabilities, coding flaws, and compliance issues before they become exploitable
- Continuous Threat Exposure Management - Ongoing risk assessment and prioritization
Why Choose Cenobe?
✓ Proven expertise across 50+ organizations in 7 countries
✓ Manual analysis that goes beyond automated tools
✓ Active R&D team discovering new vulnerabilities
✓ Enterprise-ready platform with custom solutions
Contact us for a consultation and learn how we can strengthen your security posture.