T09 · Insecure Skill Coding Practices
- Location
scripts/build_rust.py:112- Finding
FastEdge application updates can erase existing configuration
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This FastEdge skill mostly matches its stated purpose, but its bundled update helper can unintentionally wipe existing app configuration on a live Gcore deployment.
Review this before installing if you plan to deploy to real FastEdge apps. Use a least-privileged Gcore API token, run builds in a minimal environment, pin dependencies where possible, and avoid the bundled helper for updating existing production apps until it preserves the full app configuration or shows a complete diff for confirmation.
scripts/build_rust.py:112FastEdge application updates can erase existing configuration
SKILL.md:4Automatically installed dependencies are not reproducibly pinned
Code enumerates, copies, or searches environment variables for secrets. Bulk environment access can collect credentials unrelated to the skill's stated purpose.
subprocess.run(["rustup", "target", "add", "wasm32-wasip1"],
capture_output=True, text=True)
env = dict(os.environ)
if rustc:
env["RUSTC"] = rustc
result = subprocess.run([cargo, "build", "--release"],
The README presents the skill as handling build and deployment tasks but does not warn that these operations may execute scripts, compile code, modify project artifacts, or publish binaries to an external edge platform. In a deployment-oriented skill, lack of such warnings reduces user awareness and increases the chance of unintended system changes or remote releases when the skill is invoked.
The auto-trigger criteria are broad enough to match generic requests about edge computing or Wasm deployment, which can cause this skill to activate outside narrowly intended FastEdge-specific contexts. Because the skill is about building and deploying software, unintended invocation can steer the agent into system-affecting actions such as compilation, packaging, or deployment without sufficient user specificity or safety gating.
The skill declares capabilities that imply shell, network, environment-variable access, and file interaction via metadata and documented workflows, but it does not constrain tool usage with an explicit permission or allowed-tools scope. In an agent setting, this increases the chance of over-broad execution, including unintended use of secrets like GCORE_API_KEY or unintended outbound deployment actions.
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.
Copy assets/rust-template/ for a ready starter, or create the three files manually:
.cargo/config.toml
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
Upload the binary (save the id from the response):
curl -X POST 'https://api.gcore.com/fastedge/v1/binaries/raw' \
-H 'accept: application/json' \
-H "Authorization: APIKey $GCORE_API_KEY" \
-H 'Content-Type: application/octet-stream' \
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
import subprocess
import sys
API_BASE = "https://api.gcore.com/fastedge/v1"
def _toolchain():
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
import subprocess
import sys
API_BASE = "https://api.gcore.com/fastedge/v1"
def _toolchain():
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
import subprocess
import sys
API_BASE = "https://api.gcore.com/fastedge/v1"
def _toolchain():
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
import subprocess
import sys
API_BASE = "https://api.gcore.com/fastedge/v1"
def _toolchain():
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
import subprocess
import sys
API_BASE = "https://api.gcore.com/fastedge/v1"
def _toolchain():
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.
import subprocess
import sys
API_BASE = "https://api.gcore.com/fastedge/v1"
def _toolchain():
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
if (not os.environ.get("CARGO") or not rustc) and shutil.which("rustup"):
try:
if not os.environ.get("CARGO"):
cargo = subprocess.check_output(
["rustup", "which", "cargo"], text=True).strip() or cargo
if not rustc:
rustc = subprocess.check_output(
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
cargo = subprocess.check_output(
["rustup", "which", "cargo"], text=True).strip() or cargo
if not rustc:
rustc = subprocess.check_output(
["rustup", "which", "rustc"], text=True).strip() or None
except subprocess.CalledProcessError:
pass
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
def build():
"""Build the release Wasm binary and return its path."""
cargo, rustc = _toolchain()
subprocess.run(["rustup", "target", "add", "wasm32-wasip1"],
capture_output=True, text=True)
env = dict(os.environ)
This subprocess executes the cargo binary selected from the CARGO environment variable, or from PATH/rustup resolution, so an attacker who can influence the environment could cause execution of an arbitrary program during build. In an agent or automation context, build steps often run with sensitive environment variables and filesystem access, which increases the risk of local code execution and secret exposure.
env = dict(os.environ)
if rustc:
env["RUSTC"] = rustc
result = subprocess.run([cargo, "build", "--release"],
capture_output=True, text=True, env=env)
if result.returncode != 0:
sys.exit(f"Build failed:\n{result.stderr}")
The cargo executable can come directly from os.environ.get("CARGO"), and is then passed to subprocess.run, creating a true tainted flow from environment-controlled input to code execution. In CI/agent environments, if an attacker can set or poison this variable, they can replace the compiler invocation with an arbitrary executable and potentially access build secrets, source code, or deployment credentials.
env = dict(os.environ)
if rustc:
env["RUSTC"] = rustc
result = subprocess.run([cargo, "build", "--release"],
capture_output=True, text=True, env=env)
if result.returncode != 0:
sys.exit(f"Build failed:\n{result.stderr}")
No suspicious patterns detected.