Back to skill

Security audit

skill-portfolio-dashboard

Security checks for vulnerabilities and agentic risk

Overview

This local auditing skill needs review because optional checks can run repository-configured code, cleanup guidance lacks safeguards, and security grades can remain perfect despite detected secrets.

Keep scans limited to your skills directory. Leave --git disabled for repositories with untrusted configuration, and do not manually execute unfamiliar scripts as smoke tests. Review the credential fix queue directly: a perfect grade or successful JSON exit does not establish that credentials are absent. Require a reviewed backup and explicit approval before token revocation or history rewriting.

Vulnerability Patterns
  • 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
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
Vulnerability Patterns
  • Output HandlingUnvalidated Output Injection, Cross-Context Output, Unbounded Output
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • 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
Findings (9)

Description-Behavior Mismatch

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The implementation matches the general dashboard purpose and supports README, frontmatter, and basic structure checks. However, several explicitly advertised diagnostic capabilities are absent, materially narrowing its coverage. The credential scan and optional local Git checks are related health-audit functionality, not evidence of an unrelated or malicious purpose. No network requests, registry access, or script execution are implemented.

Content

No source excerpt is available for this finding.

Skill declares no tool scope ('permissions' or 'allowed-tools') but code capabilities were detected: file_read, shell.

Medium
Category
MCP Least Privilege
Confidence
70% confidence
Finding

Without declared permissions the skill's intent is opaque and cannot be validated.

Content

No source excerpt is available for this finding.

The recommended smoke test executes every portfolio script without warning about execution side effects.

Medium
Category
Output Handling
Confidence
94% confidence
Finding

The documentation recommends executing every portfolio script with --help, which does not prevent arbitrary top-level code from running with the auditor's credentials and filesystem access. The supplied implementation has no --smoke option, so this is unsafe workflow guidance rather than an existing execution path; implementing or manually following that guidance would expose the auditor to malicious portfolio scripts.

Content

No source excerpt is available for this finding.

The incident-response workflow instructs Git history rewriting without warning about its impact on repository history and collaborators.

Medium
Category
Output Handling
Confidence
93% confidence
Finding

The response protocol directs the agent to scrub history using git filter-repo, rather than merely listing the command. It does not warn that this rewrites commit identities and can disrupt shared branches, tags, and collaborators' clones.

Content

No source excerpt is available for this finding.

compile() call detected

Medium
Category
Dangerous Code Execution
Confidence
65% confidence
Finding

compile() creates code objects from strings. When combined with exec()/eval(), it enables obfuscated code execution.

Content

Scanner excerpt · scripts/portfolio_dashboard.py (reported line 159)May include surrounding context.

python
sp = os.path.join(scripts_dir, s)
        try:
            with open(sp, encoding="utf-8", errors="ignore") as f:
                compile(f.read(), sp, "exec")
        except SyntaxError as e:
            issues.append(("struct", f"script {s} does not compile: line {e.lineno}: {e.msg}"))
        except OSError as e:

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
90% confidence
Finding

Although the argument list prevents shell interpolation, git status can execute a filesystem-monitor helper configured through repository-local core.fsmonitor. With --git enabled, auditing an attacker-supplied repository containing malicious Git configuration can therefore execute code as the auditor; the timeout does not prevent those side effects.

Content

Scanner excerpt · scripts/portfolio_dashboard.py (reported line 168)May include surrounding context.

python
# git state (soft signal, opt-in: slow on big portfolios)
    if check_git and os.path.isdir(os.path.join(path, ".git")):
        try:
            r = subprocess.run(["git", "-C", path, "status", "--porcelain"],
                               capture_output=True, text=True, timeout=10)
            if r.stdout.strip():
                issues.append(("polish", f"{len(r.stdout.strip().splitlines())} uncommitted file(s)"))

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/portfolio_dashboard.py (reported line 172)May include surrounding context.

python
capture_output=True, text=True, timeout=10)
            if r.stdout.strip():
                issues.append(("polish", f"{len(r.stdout.strip().splitlines())} uncommitted file(s)"))
            r2 = subprocess.run(["git", "-C", path, "remote", "get-url", "origin"],
                                capture_output=True, text=True, timeout=10)
            if r2.returncode != 0:
                issues.append(("polish", "no origin remote"))

Credential findings do not affect grades or scores despite the documented security grading criterion.

Medium
Category
Excessive Agency
Confidence
99% confidence
Finding

Credential findings are collected after grades are finalized and never affect the score, allowing a portfolio containing detected secrets to receive an A grade and a perfect score. The separate fix queue and normal text-mode failure exit mitigate this, but downstream dashboards or release gates relying on grades can incorrectly approve publication of credentials.

Content

No source excerpt is available for this finding.

The dashboard does not implement advertised dead-link, stale-version, or clone-count anomaly checks.

Low
Category
Excessive Agency
Confidence
99% confidence
Finding

The manifest advertises these checks, but the audit only performs local structure/frontmatter checks, optional Git-state checks, and credential scanning. Versions are checked for presence rather than freshness, and there is no link validation or clone-count analysis, so the reported dashboard cannot establish several advertised health properties.

Content

No source excerpt is available for this finding.