Summary
Savon's Model.all_operations method interpolates attacker-controlled WSDL operation names into Ruby source that is then evaluated with module_eval, enabling arbitrary Ruby code execution.
When an application consumes untrusted or tampered WSDL definitions, an attacker can craft operation names that cause the application to execute injected Ruby code within its own process.
Affected context
This vulnerability arises in Ruby applications that use the Savon SOAP client's Savon::Model feature to introspect available operations from a WSDL.
It is most relevant when:
- The WSDL is fetched dynamically from external or semi-trusted endpoints
- WSDL operation names are not strictly controlled or validated
- Application code relies on
all_operationsor related dynamic method generation
In these contexts, attacker-influenced operation names can be turned into Ruby source code and evaluated at runtime.
Exploit preconditions
- Attack surface: SOAP/WSDL interface consumed by the Ruby application
- Required access: Ability to supply or modify the WSDL, or to intercept and alter WSDL responses (e.g., via compromised endpoint, man-in-the-middle, or malicious service)
- Trigger point: Invocation of
Savon::Model.all_operations(or APIs that implicitly call it) which processes operation names and passes constructed Ruby code intomodule_eval - Why exploitation is possible: Operation names from the WSDL are interpolated directly into Ruby code strings without adequate sanitization or escaping, and then executed via
module_eval, allowing crafted names to break out of the intended context and inject arbitrary Ruby code.
Why this happens
The root cause maps to CWE-94: Improper Control of Generation of Code ('Code Injection').
Savon dynamically generates Ruby methods or structures by building Ruby source strings using SOAP operation names derived from the WSDL, then executing those strings with module_eval.
Because the operation names are treated as trusted input, an attacker who controls or influences the WSDL can embed Ruby syntax into those names.
When module_eval executes the resulting string, the injected syntax is interpreted as code, enabling arbitrary instructions to run in the application's context.
The fundamental pattern is mixing untrusted data with dynamic code generation and execution, without a strict separation between data and code.
Potential impact
- Execution of arbitrary Ruby code within the application process
- Complete compromise of application integrity and confidentiality
- Access to in-process secrets, such as API keys, database credentials, and session data
- Modification or destruction of application data via injected logic
- Use of the compromised application as a pivot point for further network attacks
General mitigation guidance
Effective mitigation focuses on reducing or eliminating dynamic code generation based on untrusted input.
General defensive patterns include:
- Avoiding use of
module_eval,class_eval, and similar metaprogramming constructs for building methods from external data - Treating WSDL definitions and operation names as untrusted and restricting them to a safe, validated character set
- Introducing explicit whitelists of allowed operations, mapping them to methods without generating Ruby source strings
- Encapsulating SOAP operations in fixed, pre-defined interfaces instead of introspecting them at runtime
- Applying least-privilege principles so that, if code execution occurs, its ability to access sensitive resources is minimized
These measures help ensure that even if WSDL data is malicious, it cannot be transformed into executable Ruby code.
How teams detect issues like this
Detection generally involves identifying dynamic code execution patterns and their data sources.
Common strategies include:
- Static analysis rules that flag use of
module_eval,class_eval,eval, ordefine_methodwhere arguments can be influenced by network or file inputs - Code review checklists that highlight any metaprogramming based on external configuration or service descriptions such as WSDLs
- Instrumentation or runtime monitoring to log and alert on suspicious use of eval-like APIs, especially when linked to remote responses
- Policy-based enforcement in CI/CD pipelines that prevents merging code with unsafe dynamic code generation patterns unless properly justified and sandboxed
Automated security scanners and linters integrated into development workflows can help surface these patterns early.

