T09 · Insecure Skill Coding Practices
- Location
scripts/black_fortress.py:263- Finding
Missing Kernel Trace Is Treated as a Successful Security Check
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This is a local sandboxing skill with a coherent security purpose, but its implementation materially undercuts several protections it claims users can rely on.
Install only for review or experimentation, not as a final approval gate for untrusted skills. Run it on a disposable, isolated machine; do not grant optional root/Firecracker access unless you have reviewed and fixed the sandbox gaps; pin and verify container images; and treat any approval report as advisory rather than proof of safety.
scripts/black_fortress.py:263Missing Kernel Trace Is Treated as a Successful Security Check
scripts/black_fortress.py:171Sandbox Executes Original Source Instead of the Neutralized Copy
scripts/microvm_orchestrator.py:55Sandbox Outputs Are Destroyed Before Entropy and Format Validation
scripts/microvm_orchestrator.py:89Raw Untrusted Standard Output Bypasses Postmortem Sanitization
scripts/babel_output_filter.py:101Output Filter Copies Unknown and Potentially Active File Types
scripts/seccomp-profile.json:1Sandbox Policy Omits Documented Process, Timing, and Storage Restrictions
The README explicitly documents that earlier versions used os.environ.copy() when spawning sub-processes, which would forward the entire host environment into sandbox tooling. In a system designed to inspect untrusted code, that is dangerous because secrets such as cloud keys, API tokens, and credentials can be exposed to child processes and then stolen via logs, files, or other side channels if containment is imperfect.
### Host Environment Isolation (v1.1.6)
**The Problem:** Before v1.1.5, `black_fortress.py` used `os.environ.copy()` to build the subprocess environment. This leaked **all** host environment variables — including `AWS_SECRET_ACCESS_KEY`, `OPENAI_API_KEY`, `GITHUB_TOKEN`, and any other secrets — to every sub-script the orchestrator spawned.
**The Fix:** `_build_safe_env()` now constructs a minimal whitelist-only environment:
A static analysis/reporting CLI is not equivalent to a five-layer pre-installation sandbox. Conflating the two can cause operators to rely on source inspection where actual isolation, kernel verification, and controlled rendering are required.
A static analysis/reporting CLI is not equivalent to a five-layer pre-installation sandbox. Conflating the two can cause operators to rely on source inspection where actual isolation, kernel verification, and controlled rendering are required.
A static analysis/reporting CLI is not equivalent to a five-layer pre-installation sandbox. Conflating the two can cause operators to rely on source inspection where actual isolation, kernel verification, and controlled rendering are required.
A static analysis/reporting CLI is not equivalent to a five-layer pre-installation sandbox. Conflating the two can cause operators to rely on source inspection where actual isolation, kernel verification, and controlled rendering are required.
A static analysis/reporting CLI is not equivalent to a five-layer pre-installation sandbox. Conflating the two can cause operators to rely on source inspection where actual isolation, kernel verification, and controlled rendering are required.
A static analysis/reporting CLI is not equivalent to a five-layer pre-installation sandbox. Conflating the two can cause operators to rely on source inspection where actual isolation, kernel verification, and controlled rendering are required.
A static analysis/reporting CLI is not equivalent to a five-layer pre-installation sandbox. Conflating the two can cause operators to rely on source inspection where actual isolation, kernel verification, and controlled rendering are required.
A static analysis/reporting CLI is not equivalent to a five-layer pre-installation sandbox. Conflating the two can cause operators to rely on source inspection where actual isolation, kernel verification, and controlled rendering are required.
Code enumerates, copies, or searches environment variables for secrets. Bulk environment access can collect credentials unrelated to the skill's stated purpose.
### Host Environment Isolation (v1.1.6)
**The Problem:** Before v1.1.5, `black_fortress.py` used `os.environ.copy()` to build the subprocess environment. This leaked **all** host environment variables — including `AWS_SECRET_ACCESS_KEY`, `OPENAI_API_KEY`, `GITHUB_TOKEN`, and any other secrets — to every sub-script the orchestrator spawned.
**The Fix:** `_build_safe_env()` now constructs a minimal whitelist-only environment:
Referenced artifact was not completely inspected
**Fix:** `behavioral_audit.py` now explicitly checks for missing/empty traces and emits:
Referenced artifact was not completely inspected
**Fix:** `behavioral_audit.py` now explicitly checks for missing/empty traces and emits:
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
After fresh install, the credential helper may not be in PATH. Fix:
mkdir -p ~/.docker
echo '{"credsStore":"osxkeychain"}' > ~/.docker/config.json
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
After fresh install, the credential helper may not be in PATH. Fix:
mkdir -p ~/.docker
echo '{"credsStore":"osxkeychain"}' > ~/.docker/config.json
The differential test is security-significant because it claims to detect sandbox evasion by comparing Docker and Firecracker behavior, but the Firecracker path never runs the supplied source_dir at all. That creates a false assurance mechanism: evasive or malicious code could pass or fail based on incomparable executions, undermining a core defense in a sandboxing skill.
The seccomp profile is effectively permissive because it sets defaultAction to SCMP_ACT_ALLOW and only blocks a small set of network-related syscalls. That falls far short of a meaningful sandbox: many dangerous syscalls remain available, including process execution, filesystem manipulation, privilege-related operations, namespace abuse, and other kernel attack surface, so the claimed multi-layer confinement is not actually enforced by this profile.
The skill advertises and demonstrates capabilities to read/write files, inspect environment variables, invoke shell commands, and use Docker/network-related functionality, yet declares no explicit tool scope or permission boundaries. In an agent skill, this creates an authorization ambiguity where reviewers and runtimes cannot easily constrain dangerous operations, increasing the chance of overbroad execution.
Docker image references without a specific tag (:latest is implicit) or digest (@sha256:...) can be silently replaced by a malicious image.
Docker image references without a specific tag (:latest is implicit) or digest (@sha256:...) can be silently replaced by a malicious image.
Docker image references without a specific tag (:latest is implicit) or digest (@sha256:...) can be silently replaced by a malicious image.
The documentation claims timing instructions like rdtsc/rdtscp are blocked via seccomp, but the shown profile only blocks network-related syscalls. This discrepancy can lead users to overestimate side-channel resistance and rely on protections that are not actually enforced.
The skill describes automatic deletion of sandbox filesystems and artifacts without clearly scoping what paths are affected or warning users about data-loss boundaries. In operational use, destructive cleanup logic can remove unintended data if path handling is wrong or misunderstood.
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.
After fresh install, the credential helper may not be in PATH. Fix:
mkdir -p ~/.docker
echo '{"credsStore":"osxkeychain"}' > ~/.docker/config.json
The docstring promises JSON schema validation and metadata stripping for all files, but the implementation simply copies most non-raster files unchanged. In a security boundary component, this mismatch is dangerous because operators may rely on protections that do not actually exist, allowing malicious content or sensitive metadata to pass through the 'trusted output' layer.
The pass-through path uses shutil.copy2, which preserves file metadata, directly contradicting the claim that metadata is stripped for all files. In this sandboxing context, preserved metadata can carry hidden data or leak information, undermining the skill's stated purpose of producing sanitized, trusted outputs.
No suspicious patterns detected.