Back to skill

Security audit

portfolio-case-study-forge

Security checks for vulnerabilities and agentic risk

Overview

This is a straightforward portfolio case-study drafting skill with a small local scaffold script, though users should choose output paths carefully because the script can overwrite files.

Install only if you are comfortable with a drafting helper that may process project notes, metrics, screenshots, or links you provide. If using the bundled script, write to a new file in the current project folder and avoid absolute paths, traversal paths, symlinks, or important existing files because the script does not protect against overwrites.

Vulnerability Patterns
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (1)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/case_study_scaffold.py:16
Finding
Unchecked User-Controlled Output Path Allows Arbitrary File Overwrite## Vulnerability Details **File Location**: `scripts/case_study_scaffold.py`, lines 16–18 **Vulnerability Type**: Unrestricted file overwrite through a user-controlled output path **Risk Level**: Medium ### Vulnerable Code ```python ap.add_argument("--out", default="case_study_scaffold.json") args = ap.parse_args() json.dump(TEMPLATE, open(args.out, "w", encoding="utf-8"), ensure_ascii=False, indent=2) ``` ### Technical Analysis The `--out` argument is passed directly to `open()` in truncating write mode (`"w"`). The implementation does not verify that the destination is inside an approved workspace, does not reject symbolic links, and does not check whether the target already exists. Consequently, invoking the script with an absolute path or traversal-based relative path can replace any file writable by the script's operating-system account. If the output path is a symbolic link, the write follows that link and truncates its target. This behavior also conflicts with the skill's preview-first operating rule in `SKILL.md`. The generated content is a fixed JSON object, so the flaw does not provide arbitrary content control or code execution by itself. Exploitation also requires the attacker to influence the command-line argument used when the helper is invoked. ### Attack Path 1. An attacker influences the value supplied to the helper's `--out` option, potentially through malicious project notes or prompt content that persuades an agent to use a particular path. 2. The agent or user invokes the script, for example: ```bash python3 scripts/case_study_scaffold.py --out /path/to/writable/important-file ``` Alternatively, the attacker selects a path that is a symbolic link to another writable file. 3. The script passes the path directly to `open(..., "w")`. 4. Python creates the file if it does not exist or truncates it if it does. 5. The script replaces the target's contents with the fixed case-study JSON scaffold. ### Impact Assessment The a ...[truncated 635 chars]
Remediation
## Remediation Suggestions 1. Use exclusive creation mode (`"x"`) by default so existing files cannot be silently overwritten: ```python with open(output_path, "x", encoding="utf-8") as output_file: json.dump(TEMPLATE, output_file, ensure_ascii=False, indent=2) ``` 2. Resolve the requested path and require it to remain inside an explicitly approved output directory: ```python from pathlib import Path output_root = Path.cwd().resolve() output_path = (output_root / args.out).resolve() if output_path.parent != output_root: raise ValueError("Output must be created in the approved output directory") ``` If nested output directories are permitted, use a robust containment check such as `output_path.is_relative_to(output_root)` on supported Python versions. 3. Reject symbolic-link destinations and ensure that every existing parent component is trusted. Where race resistance is required, use operating-system facilities such as `os.open()` with `O_CREAT | O_EXCL` and, where supported, `O_NOFOLLOW`. 4. If overwrite functionality is necessary, place it behind an explicit `--force` option and clearly display the resolved destination before writing. 5. Use a context manager to ensure that the file descriptor is closed reliably. 6. Add automated tests covering existing targets, absolute paths, `..` traversal, symbolic links, invalid parent directories, and explicit overwrite behavior. 7. Run the helper with least privilege and avoid invoking it as an administrative or root account.
Vulnerability Patterns
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (9)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The skill description promises polished case-study generation, metrics handling, visuals checklists, and interview talking points, but the observed behavior reportedly only emits a generic JSON scaffold. This mismatch is dangerous because users and orchestrators may trust the skill with sensitive project notes or automate downstream actions based on capabilities the skill does not actually provide, creating opportunities for misuse, data mishandling, or deceptive workflow composition.

Vague Triggers

Medium
Confidence
92% confidence
Finding
The trigger list contains generic phrases such as "portfolio story" and "面试讲项目" that can overlap with ordinary conversation and may cause unintended invocation. The README provides examples but does not add exclusion conditions or negative examples to clarify when the skill should not activate.

Lp3

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding
The skill advertises use of a local script and static analysis detected file-write capability, but the manifest does not declare any explicit tool scope such as permissions or allowed-tools. That makes the skill's operational boundaries opaque to the host and reviewer, increasing the chance of unintended file modification or overbroad execution when invoked.

Vague Triggers

Medium
Confidence
91% confidence
Finding
This markdown file lists activation examples such as "做作品集案例", "portfolio story", and "面试讲项目" without clarifying boundaries or exclusions. These phrases are generic enough that they could match normal discussion about portfolios or interviews, increasing the risk of unintended invocation.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The smoke test instructions are written entirely in Chinese, including core headings and validation steps, with no indication that language selection is optional or that the skill is intentionally limited to a Chinese-speaking context. Under the stated policy, forcing a specific language without user opt-in is a natural-language policy violation.

Natural-Language Policy Violations

Low
Confidence
78% confidence
Finding
The document presents core instructions and labels in both Chinese and English, but it does not state whether the skill supports user language preference or how language is selected. If interpreted as a default language policy, this can create ambiguity about locale handling without explicit user opt-in.

Natural-Language Policy Violations

Low
Confidence
82% confidence
Finding
Natural-language policy issues include forcing a specific language or locale without opt-in. The file presents bilingual trigger phrases but does not state whether other languages are unsupported by design or offer any user language preference, which can be interpreted as an undocumented language constraint.

Vague Triggers

Low
Confidence
94% confidence
Finding
For a markdown skill file, trigger phrases should be specific enough to avoid accidental activation. "portfolio story" is broad and lacks constraints or negative examples, so it could match ordinary discussion about portfolios rather than an intentional request to run this skill.

Natural-Language Policy Violations

Low
Confidence
73% confidence
Finding
The file presents core instructions and examples in both Chinese and English, but does not indicate whether the skill will adapt to the user's preferred language or requires opt-in to a specific language behavior. This can create an implicit language-policy issue if the skill defaults to a language the user did not choose.

Static analysis

No suspicious patterns detected.