# Security Audit Report — backtest360-mcp

- **Report ID:** `38a07ef3-3f80-4029-bc5e-9b90919dcd16`
- **Generated:** 2026-07-30T10:47:16.941581+00:00
- **Signature:** unsigned (cosign keyless signing runs in CI; Req 22.4)

## 1. Executive Summary

**Badge:** Unsafe (composite)  
**Security score:** 85.12

| Scanner | Badge |
| --- | --- |
| agent-audit-kit | Unsafe |
| cisco-skill-scanner | Verified |
| nerlo-behavioral | Verified |
| nerlo-install-instruction | Verified |
| nerlo-multi-source | unavailable |
| osv-scanner | unavailable |
| trivy | unavailable |
| trivy_image | unavailable |

| Severity | Findings |
| --- | --- |
| critical | 0 |
| high | 2 |
| medium | 5 |
| low | 1 |
| informational | 5 |

backtest360-mcp is NOT recommended for integration: the scan surfaced 0 critical and 2 high-severity findings. Treat the Per-Scanner Detail section as a remediation worklist and re-scan before reconsidering.

## 2. Source Provenance

- **Repository:** https://github.com/Backtest360/backtest360-mcp
- **Commit scanned:** `unknown`
- **License:** MIT
- **Maintainer:** Backtest360
- **Version:** unknown

## 3. Per-Scanner Detail

### cisco-skill-scanner (v2.0.11) — Verified / 90.5

- **[low] Hidden data file detected** — Hidden file found: .gitleaks.toml. Hidden files may contain concealed configuration or data that should be reviewed. (/repo/.gitleaks.toml:None)
- **[medium] Undeclared network usage** — Skill code uses network libraries but doesn't declare network requirement (/repo/repo/CHANGELOG.md:None)
- **[informational] Vague skill description** — [mcp_server policy: capability-matches-purpose class; severity low -> informational] Skill description is too short (16 chars). Provide detailed explanation. (/repo/SKILL.md:None)
- **[informational] Skill does not specify a license** — Skill manifest does not include a 'license' field. Specifying a license helps users understand usage terms. (/repo/SKILL.md:None)
- **[informational] Vague skill description** — [mcp_server policy: capability-matches-purpose class; severity low -> informational] Skill description is too short (16 chars). Provide detailed explanation. (/repo/.github/ISSUE_TEMPLATE/SKILL.md:None)
- **[informational] Skill name does not follow agent skills naming rules** — Skill name 'Bug report' is invalid. Agent skills require lowercase letters, numbers, and hyphens only, with a maximum length of 64 characters. (/repo/.github/ISSUE_TEMPLATE/SKILL.md:None)
- **[informational] Skill does not specify a license** — Skill manifest does not include a 'license' field. Specifying a license helps users understand usage terms. (/repo/.github/ISSUE_TEMPLATE/SKILL.md:None)

### agent-audit-kit (v0.3.26) — Unsafe / 50.0

- **[high] MCP server environment exposes secrets** — Hardcoded secrets found in mcpServers env block. Secrets in project-scoped MCP config are committed to git. (examples/mcp.json:6)
- **[medium] MCP server command uses relative path** — The command uses a relative path that can be hijacked via PATH manipulation. (examples/mcp.json:4)
- **[medium] Secret in MCP server environment block** — Hardcoded secret values found in mcpServers env blocks in non-.mcp.json files. (examples/mcp.json:6)
- **[high] Generic high-entropy secret** — A value assigned to a secret-like key has high Shannon entropy, indicating a likely credential or API key. (src/backtest360_mcp/settings.py:44)
- **[medium] No lockfile present** — A package manifest exists but no lockfile was found. Without lockfiles, dependency versions float and can be silently updated. (pyproject.toml:None)
- **[medium] Repo depends on a third-party agent-platform SDK** — The project depends on an agent-platform SDK (context-ai, langsmith, helicone, langfuse, humanloop, MCP SDK). Informational finding so reviewers audit the vendor's OAuth-scope footprint before merging. Raised to MEDIUM because the April 19 2026 Vercel × Context.ai incident showed a single vendor compromise can turn into a production breach via transitive OAuth grants. (pyproject.toml:6)

### nerlo-behavioral (v0.1.0) — Verified / 100.0

No findings.

### nerlo-install-instruction (v0.1.0) — Verified / 100.0

No findings.

### nerlo-multi-source (v0.1.0) — unavailable / n/a

No findings.

### trivy (v0.71.0) — unavailable / n/a

No findings.

### osv-scanner (v2.3.8) — unavailable / n/a

No findings.

### trivy_image (v0.71.0) — unavailable / n/a

No findings.

## 4. Threat Model

Threat model synthesis has not yet run for this scan. This section is generated by the registry's LLM pipeline (Req 22.3) and will appear in the next regeneration of this report.

## 5. Audit Chain

- **Scan job:** `feddeb26-3832-4cfc-8234-e5bd7a2aa781`
- **Completed:** 2026-07-30T01:03:45.841336+00:00
- **Scanner base image:** `us-central1-docker.pkg.dev/nerlo-vsk-prod/nerlo/scanner-base@sha256:18193e789f73339d5d3d9d784011bdb7c9af4b815925f756cc1dc842ecb3fe2d`
- **AI decision log entries:** 2
  - `ae3e2221-6124-4195-b731-2082be6036cf`
  - `12e3edf6-ec38-415b-b3fc-5b71780f3bd4`

## 6. Appendix — Raw Scanner Output

```json
[
  {
    "scanner_name": "cisco-skill-scanner",
    "scanner_version": "2.0.11",
    "score": 90.5,
    "scanner_badge": "Verified",
    "findings": [
      {
        "tool_name": "cisco-skill-scanner",
        "severity": "low",
        "category": "obfuscation",
        "file_path": "/repo/.gitleaks.toml",
        "line_number": null,
        "rule_identifier": "HIDDEN_DATA_FILE",
        "title": "Hidden data file detected",
        "description": "Hidden file found: .gitleaks.toml. Hidden files may contain concealed configuration or data that should be reviewed.",
        "remediation": "Move file to a visible location or document its purpose."
      },
      {
        "tool_name": "cisco-skill-scanner",
        "severity": "medium",
        "category": "unauthorized_tool_use",
        "file_path": "/repo/repo/CHANGELOG.md",
        "line_number": null,
        "rule_identifier": "TOOL_ABUSE_UNDECLARED_NETWORK",
        "title": "Undeclared network usage",
        "description": "Skill code uses network libraries but doesn't declare network requirement",
        "remediation": "Declare network usage in compatibility field or remove network calls"
      },
      {
        "tool_name": "cisco-skill-scanner",
        "severity": "informational",
        "category": "social_engineering",
        "file_path": "/repo/SKILL.md",
        "line_number": null,
        "rule_identifier": "SOCIAL_ENG_VAGUE_DESCRIPTION",
        "title": "Vague skill description",
        "description": "[mcp_server policy: capability-matches-purpose class; severity low -> informational] Skill description is too short (16 chars). Provide detailed explanation.",
        "remediation": "Provide a clear, detailed description of what the skill does and when to use it"
      },
      {
        "tool_name": "cisco-skill-scanner",
        "severity": "informational",
        "category": "policy_violation",
        "file_path": "/repo/SKILL.md",
        "line_number": null,
        "rule_identifier": "MANIFEST_MISSING_LICENSE",
        "title": "Skill does not specify a license",
        "description": "Skill manifest does not include a 'license' field. Specifying a license helps users understand usage terms.",
        "remediation": "Add 'license' field to SKILL.md frontmatter (e.g., MIT, Apache-2.0)"
      },
      {
        "tool_name": "cisco-skill-scanner",
        "severity": "informational",
        "category": "social_engineering",
        "file_path": "/repo/.github/ISSUE_TEMPLATE/SKILL.md",
        "line_number": null,
        "rule_identifier": "SOCIAL_ENG_VAGUE_DESCRIPTION",
        "title": "Vague skill description",
        "description": "[mcp_server policy: capability-matches-purpose class; severity low -> informational] Skill description is too short (16 chars). Provide detailed explanation.",
        "remediation": "Provide a clear, detailed description of what the skill does and when to use it"
      },
      {
        "tool_name": "cisco-skill-scanner",
        "severity": "informational",
        "category": "policy_violation",
        "file_path": "/repo/.github/ISSUE_TEMPLATE/SKILL.md",
        "line_number": null,
        "rule_identifier": "MANIFEST_INVALID_NAME",
        "title": "Skill name does not follow agent skills naming rules",
        "description": "Skill name 'Bug report' is invalid. Agent skills require lowercase letters, numbers, and hyphens only, with a maximum length of 64 characters.",
        "remediation": "Rename the skill to match `[a-z0-9-]{1,64}` (e.g., 'pdf-processing')"
      },
      {
        "tool_name": "cisco-skill-scanner",
        "severity": "informational",
        "category": "policy_violation",
        "file_path": "/repo/.github/ISSUE_TEMPLATE/SKILL.md",
        "line_number": null,
        "rule_identifier": "MANIFEST_MISSING_LICENSE",
        "title": "Skill does not specify a license",
        "description": "Skill manifest does not include a 'license' field. Specifying a license helps users understand usage terms.",
        "remediation": "Add 'license' field to SKILL.md frontmatter (e.g., MIT, Apache-2.0)"
      }
    ],
    "execution_duration_seconds": 16.397224115993595,
    "status": "complete",
    "examined": {
      "unit": "skills",
      "count": 2
    },
    "metadata": {
      "source": "pypi",
      "source_url": "https://pypi.org/project/cisco-ai-skill-scanner/2.0.11/",
      "report_type": "cisco-skill-sast",
      "analyzers_used": [
        "bytecode",
        "pipeline",
        "static_analyzer"
      ],
      "skills_scanned": [
        "repo",
        "Bug report"
      ],
      "install_command": "pip install --require-hashes -r docker/scanner-base/cisco-skill-scanner/requirements.txt",
      "severity_counts": {
        "low": 1,
        "high": 0,
        "medium": 1,
        "critical": 0,
        "informational": 5
      },
      "artifact_type_policy": "mcp_server",
      "downweighted_findings": 2
    },
    "display_score": 90.5,
    "display_badge": "Verified"
  },
  {
    "scanner_name": "agent-audit-kit",
    "scanner_version": "0.3.26",
    "score": 50.0,
    "scanner_badge": "Unsafe",
    "findings": [
      {
        "tool_name": "agent-audit-kit",
        "severity": "high",
        "category": "mcp-config",
        "file_path": "examples/mcp.json",
        "line_number": 6,
        "rule_identifier": "AAK-MCP-003",
        "title": "MCP server environment exposes secrets",
        "description": "Hardcoded secrets found in mcpServers env block. Secrets in project-scoped MCP config are committed to git.",
        "remediation": "Use environment variable references or a secrets manager."
      },
      {
        "tool_name": "agent-audit-kit",
        "severity": "medium",
        "category": "mcp-config",
        "file_path": "examples/mcp.json",
        "line_number": 4,
        "rule_identifier": "AAK-MCP-006",
        "title": "MCP server command uses relative path",
        "description": "The command uses a relative path that can be hijacked via PATH manipulation.",
        "remediation": "Use absolute paths for MCP server executables."
      },
      {
        "tool_name": "agent-audit-kit",
        "severity": "medium",
        "category": "secret-exposure",
        "file_path": "examples/mcp.json",
        "line_number": 6,
        "rule_identifier": "AAK-SECRET-007",
        "title": "Secret in MCP server environment block",
        "description": "Hardcoded secret values found in mcpServers env blocks in non-.mcp.json files.",
        "remediation": "Use environment variable references."
      },
      {
        "tool_name": "agent-audit-kit",
        "severity": "high",
        "category": "secret-exposure",
        "file_path": "src/backtest360_mcp/settings.py",
        "line_number": 44,
        "rule_identifier": "AAK-SECRET-004",
        "title": "Generic high-entropy secret",
        "description": "A value assigned to a secret-like key has high Shannon entropy, indicating a likely credential or API key.",
        "remediation": "Move to environment variables or secrets manager."
      },
      {
        "tool_name": "agent-audit-kit",
        "severity": "medium",
        "category": "supply-chain",
        "file_path": "pyproject.toml",
        "line_number": null,
        "rule_identifier": "AAK-SUPPLY-004",
        "title": "No lockfile present",
        "description": "A package manifest exists but no lockfile was found. Without lockfiles, dependency versions float and can be silently updated.",
        "remediation": "Generate and commit lockfile."
      },
      {
        "tool_name": "agent-audit-kit",
        "severity": "medium",
        "category": "supply-chain",
        "file_path": "pyproject.toml",
        "line_number": 6,
        "rule_identifier": "AAK-OAUTH-3P-001",
        "title": "Repo depends on a third-party agent-platform SDK",
        "description": "The project depends on an agent-platform SDK (context-ai, langsmith, helicone, langfuse, humanloop, MCP SDK). Informational finding so reviewers audit the vendor's OAuth-scope footprint before merging. Raised to MEDIUM because the April 19 2026 Vercel \u00d7 Context.ai incident showed a single vendor compromise can turn into a production breach via transitive OAuth grants.",
        "remediation": "Pin the SDK to an exact version, audit the OAuth scopes it requests, and keep any deployment-level grants (Vercel, GCP, Workspace) in a secrets vault \u2014 never in a committed env file. See Vercel's bulletin for sensitive-env-var guidance: https://vercel.com/kb/bulletin/vercel-april-2026-security-incident"
      }
    ],
    "execution_duration_seconds": 9.946947516000364,
    "status": "complete",
    "examined": {
      "unit": "files",
      "count": 34
    },
    "metadata": {
      "source": "pypi",
      "source_url": "https://pypi.org/project/agent-audit-kit/0.3.26/",
      "report_type": "agent-audit-kit-sast",
      "install_command": "pip install --require-hashes -r docker/scanner-base/agent-audit-kit/requirements.txt",
      "rules_evaluated": 211,
      "severity_counts": {
        "low": 0,
        "high": 2,
        "medium": 4,
        "critical": 0,
        "informational": 0
      }
    },
    "display_score": 50.0,
    "display_badge": "Unsafe"
  },
  {
    "scanner_name": "nerlo-behavioral",
    "scanner_version": "0.1.0",
    "score": 100.0,
    "scanner_badge": "Verified",
    "findings": [],
    "execution_duration_seconds": 35.69938182999613,
    "status": "complete",
    "examined": {
      "unit": "files",
      "count": 15
    },
    "metadata": {
      "source": "nerlo-original",
      "source_url": "https://github.com/nerlo-ai/nerlo",
      "report_type": "nerlo-behavioral",
      "ruleset_path": "/opt/nerlo-rules/exfiltration.yaml",
      "ruleset_paths": [
        "/opt/nerlo-rules/exfiltration.yaml",
        "/opt/nerlo-rules/clipboard_exfiltration.yaml",
        "/opt/nerlo-rules/rce_endpoint.yaml",
        "/opt/nerlo-rules/taint_egress.yaml"
      ],
      "install_command": "pip install 'semgrep==1.97.0'",
      "merged_invocation": true
    },
    "display_score": 100.0,
    "display_badge": "Verified"
  },
  {
    "scanner_name": "nerlo-install-instruction",
    "scanner_version": "0.1.0",
    "score": 100.0,
    "scanner_badge": "Verified",
    "findings": [],
    "execution_duration_seconds": 35.703219408984296,
    "status": "complete",
    "examined": {
      "unit": "files",
      "count": 6
    },
    "metadata": {
      "source": "nerlo-original",
      "source_url": "https://github.com/nerlo-ai/nerlo",
      "report_type": "nerlo-install-instruction",
      "ruleset_path": "/opt/nerlo-rules/install_instructions.yaml",
      "ruleset_paths": [
        "/opt/nerlo-rules/install_instructions.yaml",
        "/opt/nerlo-rules/cursor_rules.yaml"
      ],
      "install_command": "pip install 'semgrep==1.97.0'",
      "merged_invocation": true
    },
    "display_score": 100.0,
    "display_badge": "Verified"
  },
  {
    "scanner_name": "nerlo-multi-source",
    "scanner_version": "0.1.0",
    "score": 100.0,
    "scanner_badge": "Verified",
    "findings": [],
    "execution_duration_seconds": 11.052004336990649,
    "status": "not_applicable",
    "examined": null,
    "metadata": {
      "source": "nerlo-original",
      "per_source": [],
      "report_type": "nerlo-multi-source",
      "diverged_sources": [],
      "published_surfaces_scanned": 0
    },
    "display_score": null,
    "display_badge": "unavailable"
  },
  {
    "scanner_name": "trivy",
    "scanner_version": "0.71.0",
    "score": 100.0,
    "scanner_badge": "Verified",
    "findings": [],
    "execution_duration_seconds": 0.2535640529822558,
    "status": "not_applicable",
    "examined": {
      "unit": "manifests",
      "count": 0
    },
    "metadata": {
      "source": "github-releases",
      "source_url": "https://github.com/aquasecurity/trivy/releases/tag/v0.71.0",
      "report_type": "filesystem-vulnerability",
      "install_command": "curl -sfL -o /tmp/trivy.deb https://github.com/aquasecurity/trivy/releases/download/v0.71.0/trivy_0.71.0_Linux-64bit.deb && echo '<sha256>  /tmp/trivy.deb' | sha256sum -c - && dpkg -i /tmp/trivy.deb",
      "manifests_scanned": []
    },
    "display_score": null,
    "display_badge": "unavailable"
  },
  {
    "scanner_name": "osv-scanner",
    "scanner_version": "2.3.8",
    "score": 100.0,
    "scanner_badge": "Verified",
    "findings": [],
    "execution_duration_seconds": 0.2006455379887484,
    "status": "not_applicable",
    "examined": {
      "unit": "manifests",
      "count": 0
    },
    "metadata": {
      "source": "github-releases",
      "source_url": "https://github.com/google/osv-scanner/releases/tag/v2.3.8",
      "report_type": "osv-vulnerability",
      "ecosystems_seen": [],
      "install_command": "curl -sfL -o /usr/local/bin/osv-scanner https://github.com/google/osv-scanner/releases/download/v2.3.8/osv-scanner_linux_amd64 && echo '<sha256>  /usr/local/bin/osv-scanner' | sha256sum -c - && chmod +x /usr/local/bin/osv-scanner",
      "manifests_scanned": [],
      "finding_id_aliases": {},
      "cross_scanner_correlation": {
        "only_osv": [],
        "only_trivy": [],
        "intersection_ids": []
      }
    },
    "display_score": null,
    "display_badge": "unavailable"
  },
  {
    "scanner_name": "trivy_image",
    "scanner_version": "0.71.0",
    "score": 100.0,
    "scanner_badge": "Verified",
    "findings": [],
    "execution_duration_seconds": 5.145999602973461e-05,
    "status": "not_applicable",
    "examined": {
      "unit": "image_targets",
      "count": 0
    },
    "metadata": {
      "reason": "no OCI image acquired for this artifact"
    },
    "display_score": null,
    "display_badge": "unavailable"
  }
]
```
