Sast RceSAFE
Collection of agent skills to find vulnerabilities inside your web/mobile apps.
Overview
Collection of agent skills to find vulnerabilities inside your web/mobile apps.
d9c848ebb5f1OBSERVED · 2026-10-13What it tells the agent
The instruction file, verbatim from the audited commit — this is the text the model reads, and the surface the audit's instruction layer examines. Quoted here so you can judge it without cloning anything.
---
name: sast-rce
description: >-
Detect Remote Code Execution (RCE) vulnerabilities in a codebase using a
three-phase approach: recon (find dangerous execution sinks), batched verify
(trace user input to sinks in parallel subagents, 3 sinks each), and merge
(consolidate batch results). Covers OS command injection, eval-like sinks,
and unsafe deserialization. Requires sast/architecture.md (run sast-analysis
first). Outputs findings to sast/rce-results.md. Use when asked to find RCE,
command injection, or unsafe deserialization bugs.
---
# Remote Code Execution (RCE) Detection
You are performing a focused security assessment to find Remote Code Execution vulnerabilities in a codebase. This skill uses a three-phase approach with subagents: **recon** (find dangerous execution sinks), **batched verify** (trace whether user-supplied input reaches each sink in parallel batches of 3), and **merge** (consolidate batch results into the final report).
**Prerequisites**: `sast/architecture.md` must exist. Run the analysis skill first if it doesn't.
---
## What is Remote Code Execution
Remote Code Execution (RCE) occurs when an attacker can cause the application to execute arbitrary OS commands or application-level code that they control. This is typically the highest-severity vulnerability class, often resulting in complete server compromise.
RCE arises from three primary root causes:
1. **OS Command Injection**: User input is embedded unsafely into an OS command string, allowing shell metacharacters to inject additional commands.
2. **Code Injection (eval-like)**: User input is passed to functions that interpret it as executable code (`eval`, `exec`, `Function()`, etc.).
3. **Unsafe Deserialization**: User-supplied serialized data is deserialized using a gadget-prone deserializer, triggering arbitrary code execution via crafted payloads.
### What RCE IS
- Passing user input directly or indirectly into OS command execution functions with shell interpretation enabled
- Using `eval()`, `exec()`, `Function()`, or equivalent constructs with user-controlled strings
- Deserializing user-supplied bytes/strings with inherently unsafe deserializers (pickle, PHP unserialize, Java native serialization, Ruby Marshal, etc.)
- Using `yaml.load()` without a safe loader on user-supplied content
- Dynamic `require()`/`import()` with user-controlled module paths
- PHP file inclusion (`include`/`require`) with user-controlled paths
### What RCE is NOT
Do not flag these as RCE:
- **SSRF**: Making HTTP requests to attacker-controlled URLs — different vulnerability class (no code execution)
- **Path Traversal**: Reading/writing arbitrary files — separate class (unless the read file is then executed/deserialized)
- **SSTI**: Template injection via template engines — a separate though related class; flag as SSTI, not RCE
- **XSS**: JavaScript execution in a victim's browser — client-side only, not server-side RCE
- **SQL Injection**: Injecting into database queries — different class (even if `xp_cmdshell` can lead to OS commands, flag it as SQLi)
- **Safe subprocess list-form calls**: `subprocess.run(["ls", user_arg])` with a list and no `shell=True` — arguments are passed directly to the OS without shell expansion; not vulnerable to command injection
- **Safe deserialization**: `json.loads()`, `yaml.safe_load()`, `xml.etree.ElementTree.parse()` — these formats have no code execution semantics
### Patterns That Prevent RCE
When you see these patterns, the code is likely **not vulnerable**:
**1. Subprocess list form without shell interpretation**
```
# Python — list args, no shell=True
subprocess.run(["convert", "-resize", size, input_file, output_file])
subprocess.Popen(["git", "clone", repo_url])
# Node.js — spawn with separate args (no shell)
child_process.spawn("ffmpeg", ["-i", inputFile, outputFile])
# Java — ProcessBuilder with list
new ProcessBuilder("ls", "-la", dir).start()
# Ruby — system() with multiple args (not a single interpolated string)
system("ffmpeg", "-i", "input.mp4", "-f", format, "output")
```
**2. Safe deserialization formats**
```
# Python — JSON instead of pickle
import json
data = json.loads(user_input) # no code execution semantics
# Python — safe YAML loader
import yaml
data = yaml.safe_load(user_input) # restricts to basic types only
# Java — Jackson without enableDefaultTyping, with concrete target type
ObjectMapper mapper = new ObjectMapper();
MyClass obj = mapper.readValue(json, MyClass.class); # safe
```
**3. Strict allowlist before command construction**
```
# Python — allowlist for dynamic arguments
ALLOWED_FORMATS = {"png", "jpg", "webp"}
if fmt not in ALLOWED_FORMATS:
return abort(400)
subprocess.run(["convert", infile, f"output.{fmt}"])
# Node.js — allowlist for dynamic args
const ALLOWED_COMMANDS = ['ls', 'pwd'];
if (!ALLOWED_COMMANDS.includes(cmd)) return res.status(400).end();
spawn(cmd, []);
```
---
## Vulnerable vs. Secure Examples
### OS Command Injection — Python
```python
# VULNERABLE: shell=True with f-string
@app.route('/ping')
def ping():
host = request.args.get('host')
result = subprocess.run(f"ping -c 1 {host}", shell=True, capture_output=True, text=True)
return result.stdout
# Payload: ?host=127.0.0.1;id → executes "id"
# VULNERABLE: os.system with string formatting
def convert_image(filename):
size = request.form.get('size')
os.system(f"convert {filename} -resize {size} output.jpg")
# SECURE: list-form subprocess, no shell
@app.route('/ping')
def ping():
host = request.args.get('host')
result = subprocess.run(["ping", "-c", "1", host], capture_output=True, text=True, timeout=5)
return result.stdout
```
### OS Command Injection — Node.js
```javascript
// VULNERABLE: exec with template literal
app.get('/search', (req, res) => {
const query = req.query.q;
exec(`grep -r "${query}" /var/log/app/`, (err, stdout) => {
res.send(stdout);
});
});
// Payload: ?q=foo" /etc/passwd "
// Trust audit
SAFEgrade B · trust 89/100 Nothing in the source contradicts what it says it does. Grade A is reserved for packages that have also passed the behavioural sandbox.
| Layer | What it checks | Result |
|---|---|---|
| L0 | Provenance & inventory | PASS |
| L1 | Static analysis of the code | NA |
| L2 | Instruction surface (what it tells the agent) | PASS |
| L3 | Class-specific surface | PASS |
| L4 | Behavioural (sandbox) | SKIPPED |
What the source does
- Filesystem
- none-observed
- Network
- none-observed
- Shell
- none-observed
- Dependencies
- pinned
- Secrets in source
- none-found
Findings (0)
No findings outside the package's declared scope.
Gates applied: no_behavioural_pass.
d9c848ebb5f1full audit observations/trust-audit/skill/utkusen__sast-rce.json · Report an issue / request a re-scanAudit history
Every audit this skill has had.
| Date | Source | Verdict | Grade | Score | Change |
|---|---|---|---|---|---|
| 2026-10-13 | d9c848ebb5f1 | SAFE | B | 89 | first audit |
Questions
What does the Sast Rce skill do?
Collection of agent skills to find vulnerabilities inside your web/mobile apps.
Is Sast Rce safe to install?
The audit found nothing in the source that contradicts what it says it does, and graded it B (89/100). Grade A is held back for packages that have also passed a sandboxed behavioural run, which is why a clean skill reads B.
What can Sast Rce access on my machine?
The audit observed no filesystem, network or shell use at all in its source.
How current is this page?
The grade is for one exact copy of the source (d9c848ebb5f1), read on 2026-10-13. The repository is watched, and a new audit runs when it changes — this is the first audit.