Back to skill

Security audit

Agentic Security Review Skill

Security checks for vulnerabilities and agentic risk

Overview

This is a disclosed local template and PDF generator for CompleteTech-branded security-review drafts, with branding and dependency caveats but no evidence of hidden network access, credential theft, persistence, or destructive behavior.

Install this only if CompleteTech-branded security-review PDFs are appropriate for your use. Generated artifacts are drafts and should be checked for verified facts before sharing. For higher-assurance environments, pin the Python dependencies, run installs and validation in a restricted environment, and use Markdown-only output or edit the branding defaults if you need neutral reports.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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 (2)

T01 · Skill Instruction Hijacking

Error
Location
scripts/render_pdf.py:47
Finding

Mandatory Third-Party Branding and Contact Promotion in Generated Security Artifacts

Content
View full analysis

Vulnerability Details

File Location: SKILL.md:94; scripts/render_pdf.py:47-54, 371-375; scripts/render_security_review.py:72, 130
Vulnerability Type: Fixed promotional output and agent output manipulation
Risk Level: High

Vulnerable Code

SKILL.md:94:

markdown
Artifacts from this skill are delivered as branded CompleteTech LLC **PDF** documents, not raw Markdown.

scripts/render_pdf.py:47-54:

python
BRAND = {
    "accent": "#1E3A8A",
    "accent_dark": "#0F172A",
    "accent_soft": "#EEF2FF",
    "muted": "#64748B",
    "border": "#E2E8F0",
    "zebra": "#F8FAFC",
    "brand_name": "CompleteTech",
    "brand_tagline": "Innovation at Every Integration",
    "contact": "complete.tech  ·  Timothy.Gregg@complete.tech",
}

scripts/render_pdf.py:371-375:

python
c.setFont("Helvetica", 8.5)
c.setFillColor(colors.Color(1, 1, 1, alpha=0.78))
c.drawString(nx, h - 0.58 * inch, BRAND["brand_tagline"])
c.setFont("Helvetica", 7.5)
c.setFillColor(colors.Color(1, 1, 1, alpha=0.62))
c.drawString(nx, h - 0.74 * inch, BRAND["contact"])

scripts/render_security_review.py:72, 130:

python
parser.add_argument("--footer", default="CompleteTech LLC - demonstration artifact", help="Footer text.")
python
cfg = {
    "logo": logo if logo.exists() else None,
    "title": title, "eyebrow": "CompleteTech LLC", "doc_type": doc_type,
    "subtitle": args.subtitle, "meta": meta, "doc_id": meta[0][1] if meta else "",
    "watermark": args.watermark, "footer": args.footer,
    "disclaimer": "Demonstration artifact — replace placeholders with verified facts before use.",
    "cover": not args.no_cover,
}

Technical Analysis

The Skill directs the agent to deliver branded PDFs rather than neutral review content. The rendering implementation then inserts a fixed company name, promotional tagline, domain, personal email address, eyeb ...[truncated 1569 chars]

Remediation
View remediation

Remediation Suggestions

  1. Remove the requirement in SKILL.md that artifacts be delivered as CompleteTech-branded PDFs.
  2. Make branded rendering explicitly opt-in rather than the default behavior.
  3. Default to neutral Markdown or an unbranded PDF unless the user supplies branding parameters.
  4. Remove the hardcoded company name, tagline, domain, and personal email address from BRAND.
  5. Add command-line or configuration parameters for all identity and contact fields.
  6. Do not populate identity fields unless the caller explicitly provides them.
  7. Clearly preview or disclose all branding and contact information before creating a distributable artifact.
  8. Add tests verifying that the default rendering path contains no third-party identity, promotional text, or contact routing.

T08 · Insecure Dependencies

Warning
Location
scripts/validate_quality.py:58
Finding

Mutable and Unpinned Third-Party Tool Execution During Quality Validation

Content
View full analysis

Vulnerability Details

File Location: scripts/validate_quality.py:58-65; requirements.txt:1-5; SKILL.md:13-17, 97
Vulnerability Type: Unpinned dependency resolution and execution
Risk Level: Medium

Vulnerable Code

scripts/validate_quality.py:58-65:

python
def run_ruff() -> None:
    if shutil.which("ruff"):
        run(["ruff", "check", "."])
        return
    if shutil.which("uvx"):
        run(["uvx", "ruff", "check", "."])
        return
    run([sys.executable, "-m", "ruff", "check", "."])

requirements.txt:1-5:

text
# Branded PDF artifact rendering (scripts/render_pdf.py)
reportlab>=4.0
# Optional: only needed to also emit a PNG preview montage (scripts/render_pdf.py --png)
pypdfium2>=4.30
pillow>=10.0

SKILL.md:13-17:

yaml
install:
  - kind: uv
    package: reportlab>=4.0
  - kind: uv
    package: pyyaml>=6.0

SKILL.md:97:

bash
pip install -r requirements.txt

Technical Analysis

When Ruff is not already installed but uvx is available, the documented quality validator executes:

bash
uvx ruff check .

No Ruff version or integrity constraint is supplied. The effective tool version can therefore change between validation runs and may be retrieved from a package repository or cache at execution time. The runtime dependencies likewise use open-ended minimum-version constraints without a lockfile or package hashes.

This creates a mutable supply-chain boundary: code reviewed at one point in time may cause a different third-party release to be installed or executed later. A compromised upstream release, package index, dependency account, or dependency chain could execute code with the permissions of the user running validation or installation.

The code passes arguments as a list and does not use shell=True, so this is not shell command injection. The risk arises from resolving and executing unpin ...[truncated 1303 chars]

Remediation
View remediation

Remediation Suggestions

  1. Pin Ruff to an exact reviewed version, for example through a locked development dependency.
  2. Replace mutable execution such as uvx ruff with an invocation constrained to the approved version.
  3. Fail closed with a clear installation instruction when the approved local Ruff version is unavailable.
  4. Pin runtime dependencies to reviewed versions and maintain them through a controlled update process.
  5. Generate and commit a reproducible lockfile for supported environments.
  6. Use package hashes where the installation workflow supports them, such as pip hash-checking mode.
  7. Separate required runtime dependencies from optional preview and development dependencies.
  8. Run third-party validation tools in a restricted CI environment with minimal credentials, filesystem permissions, and network access.
  9. Add automated dependency scanning and review dependency updates before changing the lockfile.
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (14)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

If the skill or its associated workflow executes external developer tools, repository-wide scans, packaging checks, and subprocesses beyond the declared purpose of producing security review artifacts, users may authorize a much broader execution surface than intended. That mismatch is dangerous because hidden validation and shell-driven tasks can access unrelated files, consume sensitive repository metadata, and expand the attack surface for command or path abuse.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

If the skill or its associated workflow executes external developer tools, repository-wide scans, packaging checks, and subprocesses beyond the declared purpose of producing security review artifacts, users may authorize a much broader execution surface than intended. That mismatch is dangerous because hidden validation and shell-driven tasks can access unrelated files, consume sensitive repository metadata, and expand the attack surface for command or path abuse.

Content

No source excerpt is available for this finding.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 106)May include surrounding context.

md
- Already drafted the Markdown yourself? Render it directly: `python3 scripts/render_pdf.py --markdown artifact.md --out artifact.pdf --logo assets/logo.png --t

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/validate_quality.py (reported line 37)May include surrounding context.

python
DEFAULT_CLAWHUBIGNORE_PATTERNS = [
    "*.png", "*.jpg", "*.jpeg", "*.gif", "*.ico", "*.pdf", "*.docx", "*.ipynb", "*.ttf", "*.otf", "*.woff", "*.woff2",
    "preview/", "output/", "__pycache__/", "*.py[cod]", "*$py.class", ".mypy_cache/", ".pytest_cache/", ".ruff_cache/",
    ".venv/", "venv/", "env/", "ENV/", ".env", ".env.*", "secrets.json", "*_secret.ini", "*_local.ini", "*.tmp",
    ".DS_Store", "Thumbs.db", "desktop.ini",
]

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/validate_quality.py (reported line 37)May include surrounding context.

python
DEFAULT_CLAWHUBIGNORE_PATTERNS = [
    "*.png", "*.jpg", "*.jpeg", "*.gif", "*.ico", "*.pdf", "*.docx", "*.ipynb", "*.ttf", "*.otf", "*.woff", "*.woff2",
    "preview/", "output/", "__pycache__/", "*.py[cod]", "*$py.class", ".mypy_cache/", ".pytest_cache/", ".ruff_cache/",
    ".venv/", "venv/", "env/", "ENV/", ".env", ".env.*", "secrets.json", "*_secret.ini", "*_local.ini", "*.tmp",
    ".DS_Store", "Thumbs.db", "desktop.ini",
]

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/validate_quality.py (reported line 245)May include surrounding context.

python
DEFAULT_CLAWHUBIGNORE_PATTERNS = [
    "*.png", "*.jpg", "*.jpeg", "*.gif", "*.ico", "*.pdf", "*.docx", "*.ipynb", "*.ttf", "*.otf", "*.woff", "*.woff2",
    "preview/", "output/", "__pycache__/", "*.py[cod]", "*$py.class", ".mypy_cache/", ".pytest_cache/", ".ruff_cache/",
    ".venv/", "venv/", "env/", "ENV/", ".env", ".env.*", "secrets.json", "*_secret.ini", "*_local.ini", "*.tmp",
    ".DS_Store", "Thumbs.db", "desktop.ini",
]

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding

The skill advertises operational behaviors that imply file reads, file writes, and shell execution via local Python scripts, but it does not declare an explicit tool scope such as permissions or allowed-tools. That creates an authorization gap: a caller may grant broader capabilities than users expect, and review systems cannot easily enforce least privilege for a skill that can touch the filesystem and invoke commands.

Content

No source excerpt is available for this finding.

Autonomous Decision Making

Medium
Category
Excessive Agency
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.

Content

Scanner excerpt · assets/examples/example.md (reported line 12)May include surrounding context.

md
| Workflow | Support email triage: classify, draft, route |
| Environment | Northwind sandbox mailbox + staging helpdesk |
| Data classes | Customer name, order number, partial address (PII) |
| External actions | None auto-executed; human approves every send |
| Review date | 2026-06-17 |

## 2. Permissions & Least Privilege

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/validate_quality.py (reported line 56)May include surrounding context.

python
def run(cmd: list[str], cwd: Path = ROOT) -> None:
    print("$", " ".join(cmd))
    subprocess.run(cmd, cwd=cwd, check=True)


def run_ruff() -> None:

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
95% confidence
Finding

The dependency is specified with a lower-bound range instead of an exact pinned version, which makes builds non-reproducible and can pull in unexpected upstream releases. In a security-review artifact generation skill, this weakens supply-chain control and makes it harder to verify whether a vulnerable or breaking version is installed.

Content

Scanner excerpt · requirements.txt (reported line 2)May include surrounding context.

text
# Branded PDF artifact rendering (scripts/render_pdf.py)
reportlab>=4.0
# Optional: only needed to also emit a PNG preview montage (scripts/render_pdf.py --png)
pypdfium2>=4.30
pillow>=10.0

Unverifiable Dependency: reportlab has 8 known advisory(ies) (CVE-2023-33733 (Reportlab vulnerable to remote code execution); CVE-2020-28463 (Server-side Request Forgery (SSRF) via img tags in reportlab); CVE-2019-19450 (ReportLab vulnerable to remote code execution via paraparser) +5 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
90% confidence
Finding

Reportlab has multiple historical advisories, including serious issues such as code execution and SSRF, and the manifest does not pin a version that can be checked against those fixes. In a PDF-rendering context, especially if any untrusted content can reach document generation, an affected version could materially increase risk.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
92% confidence
Finding

Using an unpinned version for pypdfium2 allows installation of different versions over time, reducing reproducibility and increasing supply-chain uncertainty. Even though it is marked optional for PNG preview generation, optional components can still expand attack surface when enabled in production or CI environments.

Content

Scanner excerpt · requirements.txt (reported line 4)May include surrounding context.

text
# Branded PDF artifact rendering (scripts/render_pdf.py)
reportlab>=4.0
# Optional: only needed to also emit a PNG preview montage (scripts/render_pdf.py --png)
pypdfium2>=4.30
pillow>=10.0

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
95% confidence
Finding

Pillow is unpinned, so the environment may resolve to different versions with different security properties. For image-processing libraries, this matters because malformed input files have historically triggered denial of service and memory-safety issues in some releases.

Content

Scanner excerpt · requirements.txt (reported line 5)May include surrounding context.

text
reportlab>=4.0
# Optional: only needed to also emit a PNG preview montage (scripts/render_pdf.py --png)
pypdfium2>=4.30
pillow>=10.0

Unverifiable Dependency: pillow has 16 known advisory(ies) (CVE-2016-2533 (Pillow buffer overflow in ImagingPcdDecode); CVE-2023-50447 (Arbitrary Code Execution in Pillow); CVE-2021-27922 (Pillow Uncontrolled Resource Consumption) +13 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
91% confidence
Finding

Pillow has a substantial advisory history, including resource-consumption and code-execution-class issues, and the lack of a pinned version makes it impossible to determine exposure from the manifest alone. Because this skill can optionally render image previews, any processing of untrusted image/PDF-derived content increases the importance of using a known-safe release.

Content

No source excerpt is available for this finding.