Back to skill

Security audit

Project Manager

Security checks for vulnerabilities and agentic risk

Overview

This appears to be a legitimate project-management skill, but it needs review because some mutating project-file operations can be redirected by project-controlled symlinks while the skill also uses broad local Git and remote-repository authority.

Install only for trusted project workspaces. Before running mutating commands, inspect managed directories such as 05-verification, 08-configuration, 00-project/management, 07-quality, 09-risks, and 01-requirements/intake for symlinks or unexpected redirects, and review any bootstrap plan before allowing repository creation or pushes through gh, glab, or SSH.

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/verification_evidence.py:39
Finding
Project-controlled symlink allows evidence-management writes outside the project root## Vulnerability Details **File Location**: `scripts/verification_evidence.py`, lines 39–57 and 601–620 **Vulnerability Type**: Filesystem boundary violation through unchecked symlink traversal **Risk Level**: Medium ### Vulnerable Code ```python def locations(project): root = Path(project) / "05-verification" return { "root": root, "marker": root / "EVIDENCE-MANAGEMENT.json", "registry": root / "EVIDENCE.json", "index": root / "EVIDENCE.md", "records": root / "evidence", "lock": root / ".evidence.lock", } @contextmanager def evidence_lock(project): loc = locations(project) loc["root"].mkdir(parents=True, exist_ok=True) with loc["lock"].open("a+", encoding="utf-8") as stream: fcntl.flock(stream, fcntl.LOCK_EX) try: yield finally: fcntl.flock(stream, fcntl.LOCK_UN) ``` The initialization path subsequently writes through these unchecked paths: ```python def main(argv=None): args = build_parser().parse_args(argv) project = Path(args.project).resolve() try: if args.command == "init": with evidence_lock(project): registry = load_registry(project, required=False) loc = locations(project) loc["records"].mkdir(parents=True, exist_ok=True) write_json_atomic(loc["marker"], { "model": "PROJECT_MANAGER_VERIFICATION_EVIDENCE_MANAGEMENT", "model_version": MODEL_VERSION, "enabled": True, "enabled_at": utc_timestamp(), "enabled_by": args.actor, }) if not loc["registry"].exists(): write_json_atomic(loc["registry"], registry) render_all(project, registry) print("Verification evidence management initialized") return 0 ``` ### Technical Analysis The script resolves the sup ...[truncated 2765 chars]
Remediation
## Remediation Suggestions 1. Resolve and validate the evidence root before every lock or write: ```python project_root = Path(project).resolve() evidence_root = project_root / "05-verification" resolved_root = evidence_root.resolve() if not resolved_root.is_relative_to(project_root): raise EvidenceError("Evidence-management path escapes the project") ``` 2. Reject symlinks and junctions in every existing component from the project root through: - `05-verification`; - `.evidence.lock`; - `EVIDENCE.json`; - `EVIDENCE.md`; - `EVIDENCE-MANAGEMENT.json`; and - `evidence/`. 3. Reuse or adapt the `control_path()` approach from `scripts/management_common.py` so all management subsystems enforce a consistent containment policy. 4. Revalidate containment immediately before opening a lock file and immediately before each atomic replacement. This reduces the opportunity for a path to be changed between initial validation and use. 5. Where supported, use descriptor-relative operations and no-follow semantics, such as `O_NOFOLLOW`, for security-sensitive lock and registry files. 6. Add regression tests covering: - `05-verification` as an external-directory symlink; - symlinked registry, marker, index, lock, and records paths; - symlink replacement between validation and write; - normal evidence initialization within a real project directory. 7. Fail without creating or modifying any file when a symlink, junction, or resolved path outside the project is detected.
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Memory PoisoningPersistent Context Injection, Context Window Stuffing, Memory Manipulation
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
Findings (47)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
The declared description presents a comprehensive engineering project management capability spanning planning, coordination, execution control, requirements traceability, change control, quality, and release readiness. The supplied code instead implements a specific compliance-management utility. It reads and validates compliance records tied to reviewed source obligations, ensures immutable source linkage, maps obligations to active requirements and verification evidence, produces coverage reports, renders a compliance matrix, and performs audits that flag missing/stale evidence links. While there is some overlap with requirements traceability, auditing, and limited release-gate checks, the code does not perform most of the broad PM functions claimed in the description. Its primary purpose is materially narrower and different: compliance evidence coverage assessment rather than end-to-end project management.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The description presents a broad project/program management skill covering planning, execution, coordination, traceability, change control, quality audit, and release gating across substantial engineering projects. The supplied code instead is a specialized intake manager for external sources. It validates a SOURCES registry, tracks source metadata and confidentiality, stages artifacts, records obligations, seals reviewed snapshots with hashes, supports supersession of reviewed source versions, renders markdown views, and performs limited audits around draft/reviewed/superseded status. While there is some overlap with governance concepts like requirements intake, change control, and release audit, the implemented behavior is much narrower and materially different in primary purpose. Therefore the declared description does not accurately represent the actual code behavior.

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding
The declared description presents a broad end-to-end project-management capability covering planning, execution, coordination, traceability, change control, and release gating. The supplied code, however, is narrowly focused on auditing optional project-management registries in read-only fashion. It checks for marker files, validates registry files, imports per-registry audit modules, summarizes counts/statuses, and reports errors/warnings. This aligns only with a subset of the declared functionality—quality/release-readiness auditing—and not with the much broader management, planning, coordination, or change-control capabilities claimed. Therefore the description materially overstates what this code chunk actually does.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The description promises a general-purpose project-management/orchestration capability spanning planning, execution, change control, quality audit, and release readiness. The supplied code instead implements a specific static assessment script for migration to a newer project format/version. It reads local project files, parses requirement document patterns, validates marker JSON files, checks task schema and traceability references, imports a management audit summary, and outputs a textual or JSON assessment. While there is some thematic overlap with requirements, traceability, configuration management, and audit, the primary purpose is materially different and much narrower than declared. The code neither performs end-to-end management actions nor coordinates work; it only reports status and suggested initialization commands. Therefore the declared description does not accurately represent the actual behavior.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The description presents a comprehensive end-to-end project/program management skill. The supplied code only manages a problem register in the quality area (`PROBLEMS.json` / `PROBLEMS.md`). It validates defect records, supports status transitions (NEW through CLOSED), captures triage/resolution/verification/closure events, requires sealed evidence for some transitions, and audits release-blocking issues. While there is some overlap with quality auditing, change links, traceability, and release readiness checks, these are limited to defect/problem tracking. The primary purpose is materially narrower than declared, so the description does not accurately represent the code chunk.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
The declared description promises a broad, active project-management capability covering planning, execution, change control, quality auditing, and release-gate enforcement. The supplied code is much narrower: it is explicitly a read-only status script that reads existing files, validates/summarizes them, captures git state, aggregates findings, and optionally shells out to another script for a release check. It does perform some auditing/reporting related to management, configuration, verification, and release readiness, which partially overlaps with the description. However, its primary purpose is operational status reporting from authoritative records, not managing projects end to end or coordinating work. This is therefore a material description-behavior mismatch due to substantial overstatement of capabilities.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
The declared description promises a broad project orchestration and governance capability spanning planning through execution, change control, quality audit, and release readiness. The supplied code is much narrower: it is a setup-plan intake/validation tool. Its core behavior is schema validation, questionnaire prompting, normalization of paths and infrastructure settings, secret-pattern rejection, deterministic hashing, and generation of a review summary. It references possible future effects after approval and can persist setup metadata, but those actions are not performed here. The code even states 'without provisioning infrastructure,' 'never access the network,' and 'validation does not establish authentication, reachability, runner or agent availability.' So the actual primary purpose is planning/configuration collection, not end-to-end project management. This is a material description-behavior mismatch, though the code is partially related to the planning/bootstrap portion of the declared scope.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The code is narrowly focused on static validation of requirement records in a project directory. It does not perform end-to-end project management, coordinate agents, manage baselines, control releases, or execute planning/status workflows. While it tangentially supports requirements quality and governance by auditing requirement metadata and traceability fields, that is only a small subset of the broad declared description. The declared purpose materially overstates the skill's functionality and primary purpose.

Memory Manipulation

High
Category
Memory Poisoning
Content
of an authoritative state. Concurrent writers must use the managers, not editors.

If JSON is corrupted, preserve the faulty file for private diagnosis and restore
a known valid version through normal Git recovery. Do not delete history or
renumber IDs to make validation pass. Reapply the intended operation with its
original context and evidence after review. A hash chain is not a backup.
Confidence
80% confidence
Finding
Skill manipulates agent memory, state, or stored context. Memory corruption can alter personality, override safety rules, or cause unpredictable behavior.

Memory Manipulation

High
Category
Memory Poisoning
Content
- document the cause;
- specify what must be corrected;
- keep the previous evidence;
- do not erase history.

## WIP
Confidence
80% confidence
Finding
Skill manipulates agent memory, state, or stored context. Memory corruption can alter personality, override safety rules, or cause unpredictable behavior.

Memory Manipulation

High
Category
Memory Poisoning
Content
- document the cause;
- specify what must be corrected;
- keep the previous evidence;
- do not erase history.

## WIP
Confidence
80% confidence
Finding
Skill manipulates agent memory, state, or stored context. Memory corruption can alter personality, override safety rules, or cause unpredictable behavior.

Credential Access

High
Category
Privilege Escalation
Content
.bootstrap-state.json

# Secrets
.env
.env.*
*.key
*.pem
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
raise SetupError(f"{location} must be a single line without control characters")
    # These checks reject common accidental disclosures, not arbitrary secrets.
    if re.search(r"(?:gh[pousr]_|github_pat_|glpat-|sk-proj-)[A-Za-z0-9_-]{8,}|-----BEGIN .*PRIVATE KEY", value):
        raise SetupError(f"{location} appears to contain a credential; use an env: or keychain: reference")
    return value.strip()
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
raise SetupError(f"{location} must be a single line without control characters")
    # These checks reject common accidental disclosures, not arbitrary secrets.
    if re.search(r"(?:gh[pousr]_|github_pat_|glpat-|sk-proj-)[A-Za-z0-9_-]{8,}|-----BEGIN .*PRIVATE KEY", value):
        raise SetupError(f"{location} appears to contain a credential; use an env: or keychain: reference")
    return value.strip()
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
raise SetupError(f"{location} must be a single line without control characters")
    # These checks reject common accidental disclosures, not arbitrary secrets.
    if re.search(r"(?:gh[pousr]_|github_pat_|glpat-|sk-proj-)[A-Za-z0-9_-]{8,}|-----BEGIN .*PRIVATE KEY", value):
        raise SetupError(f"{location} appears to contain a credential; use an env: or keychain: reference")
    return value.strip()
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
raise SetupError(f"{location} must be a single line without control characters")
    # These checks reject common accidental disclosures, not arbitrary secrets.
    if re.search(r"(?:gh[pousr]_|github_pat_|glpat-|sk-proj-)[A-Za-z0-9_-]{8,}|-----BEGIN .*PRIVATE KEY", value):
        raise SetupError(f"{location} appears to contain a credential; use an env: or keychain: reference")
    return value.strip()
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Lp3

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding
The skill advertises broad operational behavior and explicitly instructs the agent to run local scripts, Git operations, and potentially remote-bootstrap workflows, but it does not declare any tool restrictions such as allowed-tools or permissions. That creates an avoidable least-privilege failure: a caller or hosting framework may grant filesystem, shell, environment, and network access implicitly, increasing the blast radius if the skill is misused or if referenced scripts behave unsafely.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
| `REJECTED` | A documented decision that the reported item requires no correction |

Self-duplicates, missing targets and duplicate-reference cycles are rejected.
Duplicate or rejected dispositions do not bypass verification: every closure
requires `VERIFIED`, an explicit verification actor/rationale and sealed
verification evidence. The tool validates records and artifact integrity; the
reviewer must evaluate whether the evidence genuinely supports the disposition.
Confidence
85% confidence
Finding
Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
labels, writable paths, maximum simultaneous tasks (1–3), retry bound, and
   review policy. Labels are configurable and do not prove runtime availability.

Keep personal contact information out of shared configuration. Never ask the user
to paste a token, password or private key. Use `env:VARIABLE` or `keychain:item`
references. Authentication stays in the provider CLI or secret store. Setup
preserves reference labels but never reads or exports their secret values.
Confidence
80% confidence
Finding
Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
The digest detects changes to a reviewed plan; it is not an authentication or
signature mechanism. Any changed configuration must be reviewed again. Never
auto-approve a digest merely because the script printed it.

Dry run performs schema validation only. Preflight checks templates, configured
global Git identity, provider authentication/API access and SSH transport when selected;
Confidence
85% confidence
Finding
Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Session Persistence

Medium
Category
Rogue Agent
Content
Before creating a new project:
1. search whether it already exists;
2. reuse the matching project;
3. do not silently create a duplicate.

Each project has:
- project_title;
Confidence
60% confidence
Finding
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.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
## No blind execution

Do not automatically execute a task if:
- its acceptance criteria are absent;
- it involves an unapproved irreversible decision;
- it requires an unavailable secret or access;
Confidence
80% confidence
Finding
Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
- validate Git transport;
- persist bootstrap state;
- resume safely after interruption;
- never automatically delete a remote repository;
- separate remote creation from initial push;
- verify local HEAD against the configured remote branch;
- configure the canonical default branch only after it exists;
Confidence
80% confidence
Finding
Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Missing User Warnings

Medium
Confidence
88% confidence
Finding
This code file performs a persistent write to 00-project/STATUS.md as part of baseline operations, changing project status state on disk. Although the behavior is implied by the function name, there is no confirmation prompt or explicit user-facing disclosure at the point of modification that a status document will be rewritten.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
def run_release_gate(project, baseline_id):
    release_check = Path(__file__).resolve().parent / "release_check.py"
    result = subprocess.run(
        [sys.executable, str(release_check), str(project), "--baseline", baseline_id],
        text=True,
        stdout=subprocess.PIPE,
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Static analysis

No suspicious patterns detected.