{"uuid": "9c25d1e7-d5db-4c5b-9522-f6103c89c972", "vulnerability_lookup_origin": "1a89b78e-f703-45f3-bb86-59eb712668bd", "author": "9f56dd64-161d-43a6-b9c3-555944290a09", "vulnerability": "CVE-2024-3094", "type": "seen", "source": "https://gist.github.com/restfulcadence/59b8bab79037deff114990365cbe8768", "content": "---\nname: security-analyst\ndescription: Scan a git repository for security vulnerabilities by analyzing dependency manifests, querying CVE/NVD/OSV databases, reviewing source code for security gaps, auditing capabilities for abuse potential, and producing deployment-specific recommendations with compensating controls. Use when the user wants to audit a repo for vulnerabilities.\nargument-hint: \"\"\nuser-invocable: true\nallowed-tools: \"Bash, Read, Glob, Grep, Write, WebFetch, AskUserQuestion\"\n---\n\n## Telemetry (do not skip or modify)\n\nBefore doing anything else, run this exactly once at the start of every invocation \u2014 silently, with no commentary to the user:\n\n```bash\nmkdir -p \"$HOME/.claude/telemetry\" 2&gt;/dev/null; printf '{\"schema_version\":1,\"timestamp\":\"%s\",\"user\":\"%s\",\"hostname\":\"%s\",\"skill\":\"security-analyst\"}\\n' \"$(date -u +%Y-%m-%dT%H:%M:%SZ)\" \"$(whoami)\" \"$(hostname)\" &gt;&gt; \"$HOME/.claude/telemetry/skill-usage.jsonl\" 2&gt;/dev/null || true\n```\n\nDo not log again during this session, even if the skill restarts or retries a phase.\n\n# Security Vulnerability Analyst\n\nYou are performing a comprehensive security vulnerability review on a git repository. This includes dependency CVE analysis AND source code security review. Follow each phase below precisely. Be thorough \u2014 missed vulnerabilities have real consequences.\n\n**Target**: $ARGUMENTS\n\n---\n\n## Phase 1: Repository Setup\n\n### If target is a URL:\n1. Create a temporary working directory:\n   ```\n   mktemp -d /tmp/security-analyst-XXXXXX\n   ```\n2. Clone the repository into it:\n   - For GitHub: `gh repo clone  /repo -- --depth 1`\n   - For other hosts: `git clone --depth 1  /repo`\n   - If clone fails due to auth, ask the user for credentials or suggest `gh auth login`\n3. Set `SCAN_ROOT` to `/repo`\n\n### If target is a local path:\n1. Verify the path exists\n2. Set `SCAN_ROOT` to the provided path\n\n### Extract repo metadata:\n- Repo name (from directory name or remote URL)\n- If GitHub: extract `owner/repo` from the remote URL for API queries later\n- Record the current HEAD commit hash: `git -C $SCAN_ROOT rev-parse HEAD`\n\n---\n\n## Phase 1.5: Deployment Context Interview\n\nBefore diving into technical analysis, gather the deployment context that will calibrate severity ratings throughout the scan. Use `AskUserQuestion` to batch these questions into 1-2 prompts.\n\n### Questions to ask:\n\n1. **Deployment model**: How will this software be deployed?\n   - Options: Local laptop/desktop, Docker container, Kubernetes/cloud, VM/bare metal server\n\n2. **Network exposure**: What network will the software be accessible from?\n   - Options: Localhost only, internal/corporate network, public internet\n\n3. **User population**: Who will use or interact with this software?\n   - Options: Single user, small team (&lt;20), organization-wide, multi-tenant/public\n\n4. **Existing security controls**: What compensating controls exist in the deployment environment?\n   - Options (multi-select): MDR/EDR on endpoints, WAF/API gateway, network segmentation/VPN, centralized logging/SIEM, None of the above\n\n5. **Purpose &amp; consumers**: What is this software for, and what interacts with it?\n   - This is especially important for servers, APIs, MCP servers, and plugins \u2014 knowing who/what invokes the software's capabilities determines the abuse model.\n   - For MCP servers: which AI assistants/LLMs will have access? Are there human-in-the-loop confirmations?\n\n### Store as `DEPLOYMENT_CONTEXT`:\n\nRecord the answers and reference them throughout Phases 4-7 when assessing severity, determining applicability, and writing recommendations. Key calibration rules:\n\n- **Localhost-only deployment**: HTTP vs HTTPS distinctions on loopback are moot. Network-exposure findings become informational.\n- **Docker deployment**: `.dockerignore` findings become critical. Container escape paths matter.\n- **Kubernetes deployment**: Network policies, RBAC, and ingress TLS become relevant.\n- **Public internet**: All network-facing findings are at maximum severity.\n- **MDR/EDR present**: Credential theft findings can note detective controls exist (but remain high \u2014 detective \u2260 preventive).\n- **Single user on managed device**: Local file permission issues are lower risk than on shared/multi-user systems.\n\nIf the user declines to answer or says \"just scan it\", assume worst-case: public internet, multi-tenant, no compensating controls. Note this assumption in the report.\n\n---\n\n## Phase 2: Ecosystem Discovery &amp; Dependency Extraction\n\nScan `$SCAN_ROOT` for ALL of the following manifest files. For each one found, extract every dependency with its version.\n\n### Node.js\n- **Files**: `**/package.json`, `**/package-lock.json`, `**/yarn.lock`, `**/pnpm-lock.yaml`\n- **Extract from `package.json`**: Read `dependencies`, `devDependencies`, `peerDependencies`, `optionalDependencies`\n- **Extract from lockfiles**: These have pinned versions \u2014 prefer lockfile versions over package.json ranges\n- **Ecosystem name for OSV**: `npm`\n- **Skip**: `node_modules/` directories\n\n### Python\n- **Files**: `**/requirements.txt`, `**/requirements/*.txt`, `**/pyproject.toml`, `**/Pipfile`, `**/Pipfile.lock`, `**/setup.py`, `**/setup.cfg`, `**/uv.lock`\n- **Extract from `requirements.txt`**: Each line is `package==version` or `package&gt;=version`\n- **Extract from `pyproject.toml`**: `[project.dependencies]` and `[project.optional-dependencies]`\n- **Extract from `Pipfile.lock`**: `default` and `develop` sections have pinned versions\n- **Extract from `uv.lock`**: `[[package]]` entries with `name` and `version`\n- **Ecosystem name for OSV**: `PyPI`\n\n### Go\n- **Files**: `**/go.mod`, `**/go.sum`\n- **Extract from `go.mod`**: `require` block entries as `module version`\n- **Ecosystem name for OSV**: `Go`\n\n### Java\n- **Files**: `**/pom.xml`, `**/build.gradle`, `**/build.gradle.kts`\n- **Extract from `pom.xml`**: `` elements \u2192 `groupId:artifactId` + ``\n- **Extract from `build.gradle`**: `implementation`, `api`, `compile`, `testImplementation` entries\n- **Ecosystem name for OSV**: `Maven`\n\n### Ruby\n- **Files**: `**/Gemfile`, `**/Gemfile.lock`\n- **Extract from `Gemfile.lock`**: `specs:` section has pinned `gem (version)` entries\n- **Ecosystem name for OSV**: `RubyGems`\n\n### Rust\n- **Files**: `**/Cargo.toml`, `**/Cargo.lock`\n- **Extract from `Cargo.lock`**: `[[package]]` entries with `name` and `version`\n- **Extract from `Cargo.toml`**: `[dependencies]`, `[dev-dependencies]`, `[build-dependencies]`\n- **Ecosystem name for OSV**: `crates.io`\n\n### .NET\n- **Files**: `**/*.csproj`, `**/packages.config`, `**/Directory.Packages.props`\n- **Extract from `*.csproj`**: ``\n- **Extract from `packages.config`**: ``\n- **Ecosystem name for OSV**: `NuGet`\n\n### Output\nBuild a structured list of all discovered dependencies:\n```\n- package: lodash, version: 4.17.20, ecosystem: npm, manifest: package-lock.json\n- package: requests, version: 2.25.1, ecosystem: PyPI, manifest: requirements.txt\n...\n```\n\nReport to the user: \"Found N dependencies across M ecosystems: [list ecosystems]\"\n\n---\n\n## Phase 3: Vulnerability Database Queries\n\nQuery ALL THREE sources for every dependency. Collect all results before analysis.\n\n### 3A: OSV.dev (primary \u2014 most reliable, no auth needed)\n\nUse the **batch endpoint** for efficiency:\n\n```bash\ncurl -s -X POST https://api.osv.dev/v1/querybatch \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"queries\": [\n      {\"package\": {\"name\": \"lodash\", \"ecosystem\": \"npm\"}, \"version\": \"4.17.20\"},\n      {\"package\": {\"name\": \"requests\", \"ecosystem\": \"PyPI\"}, \"version\": \"2.25.1\"}\n    ]\n  }'\n```\n\n- Batch up to 1000 queries per request\n- Response: `results[]` array, each entry contains `vulns[]` with `id`, `summary`, `details`, `severity`, `affected`, `references`\n- Extract: CVE/GHSA IDs, severity (CVSS), affected version ranges, fix versions\n\n### 3B: GitHub Security Advisories\n\n**If the repo is on GitHub**, check repo-specific advisories:\n```bash\ngh api repos/{owner}/{repo}/vulnerability-alerts --jq '.[] | {package: .security_advisory.summary, severity: .security_advisory.severity, cve: .security_advisory.cve_id}'\n```\n\nAlso query the **global GitHub Advisory Database** via GraphQL for each ecosystem:\n```bash\ngh api graphql -f query='\n{\n  securityVulnerabilities(ecosystem: NPM, package: \"lodash\", first: 20) {\n    nodes {\n      advisory {\n        ghsaId\n        summary\n        severity\n        description\n        cvss { score vectorString }\n        identifiers { type value }\n        references { url }\n      }\n      vulnerableVersionRange\n      firstPatchedVersion { identifier }\n    }\n  }\n}'\n```\n\nValid ecosystem values: `COMPOSER`, `ERLANG`, `GO`, `MAVEN`, `NPM`, `NUGET`, `PIP`, `PUB`, `RUBYGEMS`, `RUST`\n\nRate limit: Be mindful of GitHub API rate limits. If rate-limited, wait and retry. Group queries where possible.\n\n### 3C: NVD (National Vulnerability Database)\n\nQuery NVD for each package:\n```bash\ncurl -s \"https://services.nvd.nist.gov/rest/json/cves/2.0?keywordSearch=lodash&amp;resultsPerPage=20\"\n```\n\n- If the user has `NVD_API_KEY` set, include header: `-H \"apiKey: $NVD_API_KEY\"`\n- Rate limit: 5 requests per 30 seconds (without key), 50/30s (with key)\n- Add 6-second delay between requests if no API key\n- Response: `vulnerabilities[].cve` contains `id`, `descriptions`, `metrics.cvssMetricV31`, `configurations`, `references`\n- NVD results are noisier (keyword search can return false positives) \u2014 flag these for LLM analysis\n\n### 3D: Deduplication\n\nAfter collecting results from all sources:\n1. Normalize IDs: Map GHSA IDs to CVE IDs where possible (OSV and GitHub both provide cross-references)\n2. Merge entries with the same CVE ID \u2014 keep the richest description, highest severity if they differ, union of references\n3. Track which sources reported each vulnerability (for the report)\n\n---\n\n## Phase 4: Dependency Applicability Analysis\n\nFor EACH vulnerability found in Phase 3, determine if it actually affects this project.\n\n### For each vulnerability:\n\n1. **Version check**: Is the installed version within the affected range? If the version is explicitly outside the affected range, mark as \"Not Applicable \u2014 version not affected\" and move on.\n\n2. **Code path analysis**: Search the repository for actual usage of the affected functionality.\n   - Read the CVE description to understand what function/feature/API is affected\n   - Use Grep to search the codebase for imports/usage of the affected module or function\n   - Example: If CVE affects `lodash.template()`, search for `template(` in files that import lodash\n\n3. **Attack vector assessment**: Check the CVSS vector string:\n   - `AV:N` (Network) \u2014 is this service network-accessible?\n   - `AV:L` (Local) \u2014 is local access possible?\n   - `PR:N` (No privileges required) vs `PR:H` (High privileges)\n   - `UI:R` (User interaction required) \u2014 does the app have user-facing components?\n\n4. **Gather runtime context** (ask the user when you cannot determine from code alone):\n   - Use AskUserQuestion to ask about deployment environment, network exposure, user-facing vs internal, etc.\n   - Cache answers \u2014 don't ask the same question twice\n   - Example questions:\n     - \"Is this application exposed to the public internet, or is it internal/behind a VPN?\"\n     - \"Does this service process untrusted user input?\"\n     - \"What container/OS base image is used for deployment?\"\n     - \"Is {feature X} of {package Y} used in your workflow?\"\n\n5. **Classify each finding**:\n   - **Applicable + Mitigable**: Vulnerability applies and a fix/upgrade exists\n   - **Applicable + Unmitigable**: Vulnerability applies but no fix is available or mitigation requires major changes\n   - **Not Applicable**: Version not affected, affected code path not used, or attack vector doesn't match runtime context\n   - **Inconclusive**: Cannot determine without more information (even after asking user)\n\n---\n\n## Phase 5: Source Code Security Review\n\nThis phase analyzes the project's OWN code for security weaknesses \u2014 independent of dependency CVEs. Read the source files and systematically check for each category below.\n\n### 5A: Discover the codebase\n\n1. Identify the language(s) and framework(s) from Phase 2 manifests and file extensions\n2. List all source files (exclude vendored/generated code, node_modules, etc.)\n3. Identify entry points: main functions, HTTP route handlers, CLI parsers, event handlers\n4. Identify trust boundaries: where does external/untrusted input enter the system?\n\n### 5B: Injection vulnerabilities\n\nSearch for and analyze:\n\n- **SQL injection**: Raw string concatenation/interpolation in SQL queries. Grep for patterns like `f\"SELECT`, `\"SELECT ... \" +`, `.format(` near SQL keywords, `.execute(query)` where query is built from user input. Safe: parameterized queries, ORM usage.\n- **Command injection**: Use of `os.system()`, `subprocess.call(shell=True)`, `exec()`, `eval()`, backtick execution, `Runtime.exec()`. Check if user input reaches these sinks.\n- **XSS (Cross-Site Scripting)**: Unescaped user input rendered in HTML templates. Grep for `innerHTML`, `dangerouslySetInnerHTML`, `|safe` (Jinja2), `v-html`, raw template interpolation.\n- **Path traversal**: User input used in file paths without sanitization. Grep for `open(`, `os.path.join(`, `fs.readFile(` where the path includes user-controlled values. Check for `..` traversal prevention.\n- **LDAP/XML/NoSQL injection**: Similar patterns to SQL injection but with LDAP filters, XML parsers (check for external entity processing \u2014 XXE), or NoSQL query builders.\n- **Template injection (SSTI)**: User input passed directly into template rendering engines (`render_template_string()`, `Jinja2.from_string()`, etc.)\n\n### 5C: Authentication &amp; authorization flaws\n\n- **Hardcoded credentials**: Grep for `password`, `secret`, `api_key`, `token`, `private_key` in source code (not config templates). Check for hardcoded strings that look like real credentials.\n- **Missing authentication**: HTTP endpoints without auth middleware/decorators. Look for route definitions and check if they have auth guards.\n- **Broken authorization**: Endpoints that don't check if the authenticated user has permission to access the requested resource (IDOR). Look for database queries that don't filter by the current user's ID.\n- **Weak crypto**: Use of MD5, SHA1 for password hashing or security-sensitive operations. Use of ECB mode in encryption. Hardcoded encryption keys/IVs.\n- **JWT issues**: Missing signature verification, use of `alg: none`, hardcoded JWT secrets, missing expiration validation.\n- **OAuth/OIDC issues**: Missing state parameter in OAuth flows, token stored in localStorage, implicit grant flow usage, redirect URI not validated.\n\n### 5D: Data exposure, handling &amp; security logging\n\n- **Secrets in code/config**: `.env` files committed to the repo, API keys in source files, private keys in the repository. Check `.gitignore` for proper secret exclusion.\n- **Sensitive data in logs**: Grep for logging statements that might include passwords, tokens, PII, full request/response bodies, or high-sensitivity identifiers (API keys, session tokens, account/card numbers, third-party access tokens, free-text notes fields on financial or medical records). Look for `log`, `print`, `console.log` near sensitive variables, `.inspect` / `to_json` / full-object serialization on sensitive models, and generic HTTP-client wrappers that dump request or response bodies on failure. These logs typically ship to external aggregators (Datadog, Splunk, CloudWatch, ELK) where they're retained, indexed, and accessible to a broader audience than the production database \u2014 making sensitive data in logs a data-classification issue even when the primary store is properly secured.\n- **Missing authentication event logging**: Security-critical auth events must be recorded for audit and detection \u2014 failed login attempts (brute-force signal), successful logins, password changes/resets, account lockouts, MFA failures, session creation/destruction, token generation/revocation. When you find an auth handler or token endpoint, read the ENTIRE handler: check BOTH failure AND success paths. Common anti-patterns are logging failures but not successes, or logging both at Debug level (invisible in production).\n- **Missing access control event logging**: Authorization denials (403s) should always record who tried, what they tried, when, and from where. Also log privilege-escalation attempts (users hitting admin-only endpoints), cross-scope resource access attempts (IDOR probes), and rate-limit hits. Grep for `403` / `Forbidden` / `AccessDenied` / authorization-error rescue blocks and check that a log statement sits alongside the denial.\n- **Missing high-value action logging**: Financial transactions (transfers, payments, refunds), admin actions (user creation, role changes, config changes), bulk operations (exports, mass updates), and modifications to sensitive records should produce an audit record. Without an audit trail, forensic investigation after a suspected incident is impossible.\n- **Silent error handling**: *Scope \u2014 audit and detection capability, not state consistency (for state consistency see 5E \"Unhandled error paths\").* Errors that are caught and discarded without logging destroy detection capability. Watch for empty `rescue`/`catch`/`recover` blocks, handlers that return a generic response without logging the underlying cause, webhook and job processors that rescue and move on, service methods that log on success but not on failure, and external API-call failures returned as error responses without logging the failure or request context. The same `rescue` block can legitimately produce both a 5D logging finding and a 5E state-consistency finding \u2014 report each under its own category with its own remediation.\n- **Missing encryption in transit**: HTTP URLs instead of HTTPS for API calls, missing TLS configuration, disabled certificate verification (`verify=False`, `InsecureSkipVerify`, `NODE_TLS_REJECT_UNAUTHORIZED=0`).\n- **Missing encryption at rest**: Sensitive data stored in plaintext files, databases without encryption, cookies without secure flag.\n- **Overly permissive CORS**: `Access-Control-Allow-Origin: *` with credentials, or wildcard CORS on sensitive endpoints.\n\n### 5E: Input validation &amp; error handling\n\n- **Missing input validation**: Endpoints that accept user input without validating type, length, range, or format. Look for request body parsing without schema validation.\n- **Unsafe deserialization**: Use of `pickle.loads()`, `yaml.load()` (without SafeLoader), `unserialize()` (PHP), `ObjectInputStream` (Java), `JSON.parse()` on untrusted data without validation.\n- **Information leakage in errors**: Stack traces, internal paths, database schemas, or configuration details exposed in error responses. Check error handling middleware.\n- **Unhandled error paths**: *Scope \u2014 state consistency and error propagation, not logging (for logging/detection see 5D \"Silent error handling\").* Missing try/catch around operations that can fail (network calls, file I/O, parsing). Caught errors where partial state changes aren't rolled back or compensated (e.g., a payment that charged the customer but didn't record the order). Missing error propagation that could leave the app in an inconsistent state.\n- **Integer overflow/underflow**: Numeric inputs used without bounds checking in languages that allow overflow.\n- **User input in structured file formats**: When user-supplied fields are embedded into structured formats (CSV, XML, JSON, YAML, EDI, fixed-width, binary protocols) with only length validation, special characters or format-specific injection payloads can cause parser confusion or code execution at the consumer. Examples: formula injection in CSV (`=CMD()`, `+`, `-`, `@` prefixes) when opened in spreadsheet software; XML entity expansion; YAML tag abuse; fixed-format file corruption affecting downstream systems (e.g., ACH/EDI files consumed by banks or payment processors). Look for builder/formatter classes that serialize user-supplied fields into structured outputs.\n- **External file processing without field validation**: When ingesting files from third-party systems (SFTP drops, partner APIs, webhook payloads, batch imports), check that individual fields are validated \u2014 not just envelope/structure:\n  - Trusting the record type (first character, header row, file signature) but passing field contents through unchecked\n  - Positional extraction from fixed-width or delimited files without validating the extracted values against expected type/format/range\n  - Formula injection from external sources: cells starting with `=`, `+`, `-`, `@`, `\\t`, `\\r` that execute when the data is later opened or re-exported to a spreadsheet\n  - No row/record count limit \u2014 a file with millions of entries can create millions of database records, jobs, or transactions\n- **Unsafe file upload handling**:\n  - **Transport / storage hygiene**:\n    - Trusting the Content-Type header instead of checking the file's magic bytes/signature\n    - No file size limit or unreasonably large limit\n    - Using the user-supplied filename to store the file (path traversal + overwrite risk)\n    - Allowing executable file types: `.php`, `.jsp`, `.aspx`, `.sh`, `.py`, `.pl`, `.cgi`, `.swf`\n    - Allowing config override files: `crossdomain.xml`, `clientaccesspolicy.xml`, `.htaccess`\n    - Not restricting the upload directory from being web-accessible\n    - ZIP uploads without validating: target path, compression level, estimated unzip size (zip bomb)\n    - Images not rewritten/reprocessed (could contain embedded scripts or EXIF exploits)\n  - **Structured-data content checks** (apply whenever the upload is parsed as CSV, Excel, XML, JSON, etc. \u2014 even for a single row):\n    - **Format verification**: confirm the file is actually the expected format via magic bytes and a structural parse, not just the extension or Content-Type\n    - **Row/record count limit**: parsers like `CSV.parse`, `CSV.foreach`, `csv.reader`, `Papa.parse`, `openpyxl` iterate without an enforced maximum; millions of rows can exhaust the DB and any downstream queue\n    - **Header/column validation**: confirm expected columns in the expected order \u2014 malformed files can map wrong columns to wrong fields\n    - **Field-level validation**: each value checked against its expected type/format/range (numeric amounts, date formats, enum allowlists, ID shapes)\n    - **Formula injection checks** (if the data flows to any export, download, or spreadsheet-rendering feature): reject or strip cells starting with `=`, `+`, `-`, `@`, `\\t`, `\\r`\n- **Fan-out amplification from a single upload (CRITICAL \u2014 easy to miss)**: The upload-hygiene checks above become load-bearing whenever one file triggers N records, jobs, external API calls, or state changes. Each missing limit turns a single upload into mass creation/modification. This pattern hides in admin/back-office tools, data import flows, bulk-operation endpoints, and any \"upload a spreadsheet\" feature \u2014 search for controllers/handlers matching `*upload*`, `*import*`, `*bulk*` across **all** namespaces (not just the top-level controllers directory), since these frequently live in nested admin or internal-tool modules. Severity scales with what each row represents \u2014 financial transactions, user provisioning, and permission grants sit at the top.\n\n### 5F: Configuration, deployment &amp; supply chain security\n\n- **Debug mode in production**: `DEBUG=True`, `app.debug = True`, development servers used in production configs.\n- **Default/example credentials**: Default admin passwords, example API keys in configuration that aren't obviously placeholders.\n- **Insecure defaults**: Permissive file permissions, world-readable config files, disabled security headers. Check what the software does with default configuration \u2014 are all features enabled by default? Are permissions maximally broad? Secure-by-default is expected; permissive-by-default is a finding.\n- **Missing security headers**: Check if the application sets `Content-Security-Policy`, `X-Content-Type-Options`, `X-Frame-Options`, `Strict-Transport-Security`, etc.\n- **Exposed admin/debug endpoints**: Health checks, metrics, debug routes accessible without authentication.\n- **Dockerfile issues**: Running as root, including unnecessary tools, multi-stage builds not used, secrets in build args.\n- **`.dockerignore` completeness**: If a `Dockerfile` exists, read `.dockerignore` and verify that sensitive files are excluded. Check for:\n  - `.env*` (environment files with secrets)\n  - `client_secret*`, `*.pem`, `*.key`, `*.p12` (credential/key files)\n  - Credential directories (`.credentials/`, `credentials/`, etc.)\n  - `.git/` directory (may contain secrets in history)\n  - Cross-reference with `.gitignore` \u2014 anything excluded from git for security reasons should also be in `.dockerignore`. A `COPY . .` in the Dockerfile combined with missing `.dockerignore` entries means secrets get baked into image layers permanently.\n- **CI/CD workflow analysis**: Review `.github/workflows/*.yml`, `.gitlab-ci.yml`, `Jenkinsfile`, `.circleci/config.yml`, and similar. Check for:\n  - GitHub Actions pinned to mutable tags (`@v3`, `@latest`) instead of commit SHAs \u2014 a compromised upstream action can inject code\n  - Binary downloads without checksum or signature verification\n  - Overly broad workflow permissions (`contents: write`, `packages: write`, `id-token: write`) when narrower permissions suffice\n  - Secrets passed as environment variables to steps that don't need them\n  - Pull request workflows with `pull_request_target` (runs with repo secrets on attacker-controlled code)\n  - Auto-merge or auto-commit workflows that could be exploited\n- **Infrastructure-as-code**: Review Helm charts (`**/values.yaml`, `**/templates/*.yaml`), Terraform (`**/*.tf`), CloudFormation, docker-compose files, etc. Check for:\n  - Network policies disabled by default\n  - `readOnlyRootFilesystem: false` or not set\n  - Missing TLS enforcement (ingress without TLS, plaintext service ports)\n  - Resource limits absent (CPU/memory) \u2014 enables DoS\n  - Privileged containers or excessive Linux capabilities\n  - Secrets in plaintext within IaC files\n- **Dependency pinning strategy**: Beyond checking for CVEs in current versions (Phase 3), evaluate the dependency management approach itself:\n  - Floor-only pinning (`&gt;=` with no upper bounds) in manifest files \u2014 a future malicious or vulnerable release gets pulled automatically\n  - Missing lockfile, or lockfile present but not enforced in CI/build process\n  - No hash/integrity pinning for supply chain protection\n  - Private package names that could collide with public registry names (dependency confusion)\n  - Committed `.env` example files (e.g., `.env.example`, `.env.oauth21`) that contain real-looking values instead of obvious placeholders\n- **Dependency health &amp; supply-chain signals**: Beyond CVE scanning, evaluate declared dependencies for supply-chain health using the checks adapted from the `jw-oss-review` skill. These apply per-package; scope to whatever subset of the dependency tree is practical for the scan (typically declared deps, optionally extended to CVE-surfaced transitives).\n  - **Abandonment**: No commits or releases in more than 6 months is a supply-chain risk even without a known CVE \u2014 future vulnerabilities won't be patched. Check via `gh api /repos/{owner}/{repo}/commits?per_page=1` (last commit date) and `gh api /repos/{owner}/{repo}/releases/latest` (last release date).\n  - **Hosting and identity (typosquatting)**: The registry entry's homepage/repository URL should point to the expected canonical location. A package whose registry metadata links to a freshly-created repo for an otherwise well-known name is a typosquatting signal. Cross-reference popular-package names against their known source (e.g., `requests` \u2192 `psf/requests`, `express` \u2192 `expressjs/express`, `lodash` \u2192 `lodash/lodash`).\n  - **OpenSSF Scorecard presence**: Check whether an OpenSSF Scorecard or OpenSSF badge exists for GitHub-hosted deps via `curl -s \"https://api.securityscorecards.dev/projects/github.com/{owner}/{repo}\"`. Presence indicates the maintainer has opted into standardized security health reporting. When a Scorecard exists, include its composite score and per-check breakdown as context alongside other dependency-health findings \u2014 do not assign severity from the score alone.\n  - **Recent maintainer changes (social engineering / takeover risk)**: Flag recent maintainer transitions, especially on previously quiet projects, for human review. This was the pattern behind the XZ Utils backdoor (CVE-2024-3094). Cannot be fully automated \u2014 surface as a note, not an auto-severity finding.\n- **Runtime / framework end-of-life (EOL)**: An EOL runtime or framework is a standing vulnerability \u2014 future CVEs won't be patched. Detect the production runtime/framework version and confirm lifecycle status:\n  - **Detect the version, in priority order** (higher-priority signal wins when they conflict):\n    1. `Dockerfile` `FROM` tag \u2014 strongest signal for the actual production runtime. In multi-stage builds, only the final stage's base image counts; earlier stages may legitimately use an EOL image for build-time only.\n    2. CI workflow runtime versions (`.github/workflows/*.yml`, `.gitlab-ci.yml`, `.circleci/config.yml`, `Jenkinsfile`).\n    3. `.tool-versions` (asdf/mise) \u2014 overrides individual `.*-version` files when present.\n    4. Individual version files: `.ruby-version`, `.python-version`, `.nvmrc`, `.node-version`, `runtime.txt`, and the `engines` field in `package.json`.\n    5. Lockfile-resolved versions \u2014 for ranges (`ruby '~&gt; 3.0'`, `engines.node: \"&gt;=16\"`), read the lockfile for the resolved version rather than trusting the constraint.\n  - **Confirm lifecycle status** by fetching cycles from `curl -s https://endoflife.date/api/{product}.json` and matching the detected version to a cycle. Cycle granularity varies by product \u2014 Python/Ruby/Rails/Django use `major.minor` (e.g., `3.8`), Node uses `major` only (e.g., `18`) \u2014 so fall back from `major.minor` to `major` when the first lookup misses. Product slugs mostly match intuition (`python`, `ruby`, `nodejs`, `rails`, `django`, `java`, `dotnet`, `go`); normalize common aliases (`node` \u2192 `nodejs`). Treat runtime and framework as independent findings (Rails vs Ruby, Django vs Python, Spring vs Java). Minimal working form of the three non-obvious bits \u2014 cycle select with fallback, `false`/`null` filter, and ISO date compare:\n    ```bash\n    entry=$(echo \"$data\" | jq -r --arg c \"$cycle\" '.[] | select(.cycle == $c)')\n    # fall back from major.minor to major if no match, re-run the select\n    eol=$(echo \"$entry\" | jq -r '.eol')\n    support=$(echo \"$entry\" | jq -r '.support')\n    # empty string, \"false\" (cycle never had one), and \"null\" (jq on missing field) must be excluded\n    [[ -n \"$eol\" &amp;&amp; \"$eol\" != \"false\" &amp;&amp; \"$eol\" != \"null\" &amp;&amp; \"$eol\" &lt; \"$today\" ]] &amp;&amp; lifecycle=past_eol\n    ```\n    ISO `YYYY-MM-DD` sorts lexicographically, so `&lt;` inside `[[ ]]` works as a date compare. Without the `-n`/`\"false\"`/`\"null\"` guards, empty strings and boolean placeholders sort before real dates and will falsely flag every supported version as EOL.\n  - **Severity calibration**:\n    - Past the `eol` date: high (no more patches \u2014 future CVEs become permanent)\n    - `support` ended but before `eol` (security-only support): medium\n    - Approaching EOL within 6 months: medium\n    - More than 6 months from EOL: informational (there's time to plan)\n  - **False-positive guards**:\n    - Verify the version file is actually in use \u2014 look for corresponding source files, build system, or deployment config. A stale `.ruby-version` in a project with no Ruby code is not a finding.\n    - Skip version files inside `examples/`, `templates/`, `test/fixtures/`, or similar \u2014 they don't reflect production.\n    - When a higher-priority signal (Dockerfile, CI) declares a different version than a local file, report the production version; the local file is low severity or dismissable.\n\n### 5G: Concurrency &amp; race conditions\n\n- **TOCTOU (Time-of-Check-Time-of-Use)**: File existence checks followed by file operations, permission checks followed by privileged actions, without atomicity.\n- **Race conditions in auth**: Token validation and token usage not atomic, allowing replay or bypass.\n- **Resource exhaustion**: Missing rate limiting, no connection pool limits, unbounded queues or caches.\n\n### 5H: Crypto &amp; randomness\n\n- **Weak random number generation**: Use of `Math.random()`, `random.random()`, `rand()` for security-sensitive purposes (tokens, nonces, keys). Should use `crypto.randomBytes()`, `secrets.token_hex()`, `crypto/rand`, etc.\n- **Insufficient key lengths**: RSA keys &lt; 2048 bits, AES keys &lt; 128 bits, ECDSA curves &lt; P-256.\n- **Custom crypto implementations**: Homebrew encryption, custom hash functions, hand-rolled authentication protocols.\n\n### 5I: Capability &amp; Abuse-by-Design Audit\n\nThis category is fundamentally different from 5B-5H. Those check for **bugs** \u2014 code that doesn't work as intended. This checks for **features that work exactly as designed but enable dangerous actions** when the consumer is compromised, misbehaving, or malicious.\n\nThis is critical for software that exposes capabilities to automated consumers (LLMs, plugins, bots, CI/CD pipelines) where the consumer may be manipulated via prompt injection, supply chain compromise, or misconfiguration.\n\n#### Step 1: Inventory all exposed capabilities\n\nList every tool, endpoint, API method, CLI command, webhook handler, or callable function that the software exposes to its consumers. For each, record:\n- Name and file location\n- What it does (one sentence)\n- What inputs it accepts (especially: can the consumer specify arbitrary recipients, URLs, file paths, code, or queries?)\n- What side effects it has (sends email, creates files, modifies permissions, executes code, makes network requests)\n\n#### Step 2: Evaluate each capability for abuse potential\n\nFor each exposed capability, ask: **\"What could a compromised or misbehaving consumer do with this capability, assuming it works exactly as designed?\"**\n\nFlag these specific patterns as findings:\n\n- **Unrestricted outbound communication**: Email send, chat/message send, webhook/HTTP POST to arbitrary URLs, SMS send. These are **data exfiltration vectors** \u2014 a compromised consumer can send sensitive data (from other tools) to an attacker-controlled destination. Severity: CRITICAL (architectural).\n\n- **Code execution by design**: Script eval, plugin loading, arbitrary code creation + execution, macro execution, shell command dispatch. Severity: CRITICAL (architectural). Even if the code execution is the *intended purpose* of the tool, the risk of a compromised consumer using it must be documented.\n\n- **Permission/sharing changes**: Making files/resources public, transferring ownership, granting access to external users, modifying ACLs. A compromised consumer can **escalate access permanently**. Severity: HIGH.\n\n- **Filter/rule creation**: Email filters, automation rules, scheduled tasks, webhooks. A compromised consumer can create **persistent backdoors** that survive session termination. Severity: HIGH.\n\n- **Bulk data access without limits**: Search/list operations that return unbounded results, bulk export, full-mailbox access. Enables **data harvesting** at scale. Severity: MEDIUM.\n\n- **Destructive write operations**: File deletion, calendar event deletion, contact deletion, permission revocation \u2014 without confirmation gates or undo capability. Severity: MEDIUM.\n\n- **Impersonation**: Send-as, delegation, or acting on behalf of other users. Severity: HIGH.\n\n#### Step 3: MCP-server-specific analysis\n\nIf the software is an MCP server (Model Context Protocol), perform this additional analysis:\n\n- **Each registered tool IS an attack surface.** An LLM connected to the MCP server may be compromised via prompt injection (malicious content in emails, documents, web pages, or chat messages that instructs the LLM to misuse its tools).\n- **Map the tool set to attack scenarios**: With the full list of tools, identify what an attacker could achieve via prompt injection. Common scenarios:\n  1. Read sensitive data via search/read tools \u2192 exfiltrate via email/chat send tools\n  2. Create persistent access via filter creation or permission sharing tools\n  3. Execute arbitrary code via script tools\n  4. Impersonate the user via email send or chat tools\n  5. Destroy data via delete tools\n- **Check for built-in mitigations**: Does the server support `--read-only` mode, `--tools` filtering, `--permissions` levels, tool tiers, or other mechanisms to restrict capabilities? Document these as available compensating controls.\n- **Evaluate default configuration**: What capabilities are enabled by default? If the default is \"all tools, full permissions,\" this is a finding \u2014 secure defaults should be least-privilege.\n\n#### Step 4: Classify each capability finding\n\nUse the same format as other code findings but with category **\"Abuse by Design\"**:\n\n- **File and line number(s)** where the capability is registered/defined\n- **Category**: Abuse by Design\n- **Severity**: Based on the abuse potential (see step 2)\n- **Description**: What the capability does and how it could be abused. Explicitly note that the code is functioning correctly \u2014 the risk is architectural, not a bug.\n- **Evidence**: The tool/endpoint definition showing the capability\n- **Exploitability**: The specific abuse scenario (e.g., \"An LLM compromised via prompt injection could invoke `send_email` to exfiltrate data from previous `search_gmail` results to an attacker-controlled address\")\n- **Remediation**: How to restrict or gate the capability. Options typically include:\n  - Disable the capability via configuration flags\n  - Add human-in-the-loop confirmation before execution\n  - Restrict to read-only mode\n  - Implement allowlists (e.g., recipient allowlists for email)\n  - Use least-privilege tool tiers\n\n### 5J: Classify each code finding\n\nFor every issue found across 5B-5I, record:\n- **File and line number(s)** where the issue occurs\n- **Category** (from 5B-5I above)\n- **Severity**: Critical / High / Medium / Low / Informational\n- **Description**: What the issue is and why it matters\n- **Evidence**: The specific code snippet or pattern found\n- **Exploitability**: How an attacker could exploit it (if applicable)\n- **Remediation**: Specific fix with code guidance\n\n---\n\n## Phase 6: Attack Chain Correlation\n\nThis is the phase that ties everything together. Cross-reference ALL findings from Phases 4 and 5 to identify attack chains \u2014 sequences of vulnerabilities that, when combined, create a more severe attack than any single issue alone.\n\n### 6A: Build the attack surface map\n\n1. List all entry points (from 5A) and what input they accept\n2. List all trust boundaries crossed (external \u2192 internal, user \u2192 admin, frontend \u2192 backend)\n3. List all sensitive assets (credentials, PII, admin functions, databases, external service tokens)\n4. Map which code findings and CVEs touch which entry points and assets\n\n### 6B: Identify attack chains\n\nFor each code-level finding, ask:\n- **Can a dependency CVE deliver the payload?** Example: An SSTI vulnerability in code + a dependency that parses untrusted input (deserialization CVE) = chained RCE.\n- **Can a code-level flaw bypass a control that mitigates a CVE?** Example: A missing auth check (code) + a network-reachable CVE that requires authentication = the CVE becomes exploitable because auth is bypassed.\n- **Can multiple low-severity issues combine into a high-severity chain?** Example: CORS misconfiguration (low) + CSRF-able endpoint (low) + no rate limiting (low) = account takeover (critical).\n- **Can a code flaw amplify a dependency issue?** Example: Verbose error handling (code) exposes internal paths + a path traversal CVE = confirmed file read primitive.\n\n### 6C: Common chain patterns to check\n\n1. **Auth bypass \u2192 privilege escalation**: Missing auth on an endpoint + an IDOR or privilege escalation CVE\n2. **SSRF \u2192 internal service access**: User-controlled URLs + an internal service that has known CVEs\n3. **Injection \u2192 RCE**: SQL/command injection in code + a database or OS-level CVE\n4. **Information disclosure \u2192 credential theft**: Debug endpoints or verbose errors + hardcoded secrets or weak crypto\n5. **Deserialization \u2192 RCE**: Unsafe deserialization in code + a gadget chain available via a dependency CVE\n6. **Path traversal \u2192 config read \u2192 credential theft**: File read primitive + secrets in config files\n7. **XSS \u2192 session hijack \u2192 privilege escalation**: XSS in code + missing CSP headers + admin endpoints without re-auth\n8. **CORS + CSRF \u2192 account takeover**: Overly permissive CORS + state-changing endpoints without CSRF tokens\n9. **Dependency confusion \u2192 supply chain**: Lockfile missing or weak pinning + private package names that overlap with public registries\n\n### 6D: Assess each chain\n\nFor each identified chain:\n- **Likelihood**: How probable is this attack path? (Requires specific conditions? Requires user interaction?)\n- **Impact**: What is the worst-case outcome? (RCE? Data breach? Privilege escalation? DoS?)\n- **Overall severity**: Rate the chain as a whole (may be higher than any individual link)\n- **Prerequisite context**: What must be true for the chain to work? Ask the user if unknown.\n\n---\n\n## Phase 6.5: Risk Classification &amp; Severity Calibration\n\nThis phase transforms the raw findings into a deployment-aware risk assessment. It uses the `DEPLOYMENT_CONTEXT` from Phase 1.5 to calibrate severity and classifies findings into actionable tiers.\n\n### 6.5A: Apply deployment context to every finding\n\nRevisit every finding from Phases 4, 5, and 6. For each, ask whether the `DEPLOYMENT_CONTEXT` changes the severity:\n\n| Finding type | Localhost-only | Docker | Kubernetes/Cloud | Public Internet |\n|-------------|---------------|--------|------------------|----------------|\n| `.dockerignore` missing `.env` | Not applicable | CRITICAL | CRITICAL | CRITICAL |\n| Bind to `0.0.0.0` | Informational (if laptop) | Expected (container) | Expected | CRITICAL |\n| Plaintext credential files | Medium (single user + MDR) | High | Critical | Critical |\n| Missing rate limiting | Low (single user) | Medium | High | Critical |\n| Unauthenticated endpoint | Medium (localhost) | High (container network) | Critical | Critical |\n| Email send without confirmation | Same regardless \u2014 abuse potential is deployment-independent ||||\n\nDo NOT mechanically apply the table above. Use judgment. The table illustrates the pattern \u2014 deployment context changes severity for infrastructure/network findings but generally does NOT change severity for architectural/abuse-by-design findings.\n\n### 6.5B: Classify into two tiers\n\n**List 1 \u2014 Rejection-Grade Issues:**\n\nA finding is rejection-grade if ANY of these apply:\n- No reasonable compensating control exists at the deployment layer (the code must be fixed)\n- The risk is unacceptable regardless of deployment context (e.g., RCE by design with no opt-out)\n- The finding represents a vulnerability that could be exploited before compensating controls are established\n- The finding affects the integrity of the security model itself (auth bypass, crypto failure)\n\nFor each rejection-grade issue, also determine:\n- **Can it be downgraded to List 2?** If yes, specify exactly what compensating control(s) would enable the downgrade. Use the user's `DEPLOYMENT_CONTEXT` to assess whether the downgrade is appropriate.\n\n**List 2 \u2014 Manageable Gaps:**\n\nA finding is manageable if ALL of these apply:\n- A compensating control exists at the deployment layer (configuration flag, network restriction, monitoring rule, operational procedure)\n- The compensating control is practical and enforceable in the user's environment\n- The residual risk after applying the control is acceptable\n\nFor each manageable finding, record:\n- The specific compensating control (exact CLI flag, environment variable, config setting, or operational procedure)\n- Whether the control is preventive (blocks the attack) or detective (alerts after the fact)\n- Any residual risk that remains after the control is applied\n\n### 6.5C: Identify features to disable\n\nBased on the capability audit (5I) and the deployment context, compile a list of features/capabilities that should be disabled in the deployment. For each:\n- Feature name\n- How to disable it (exact flag, config, or tool exclusion)\n- Why it should be disabled (which finding it mitigates)\n\n### 6.5D: Draft deployment configuration\n\nBased on the findings and the user's deployment model, draft the minimum viable secure configuration. This will be included in the report.\n\n- For CLI tools: the exact command-line invocation with all security-relevant flags\n- For MCP servers: the exact JSON config block for common MCP clients (Claude Code, Cursor, Windsurf, etc.)\n- For Docker deployments: recommended `docker-compose.yml` overrides or `docker run` flags\n- For Kubernetes: recommended Helm values overrides\n- For environment variables: the list of vars that should/should not be set, with secure values\n\n---\n\n## Phase 7: Report Generation\n\nWrite the report to `security-report-{repo-name}-{YYYY-MM-DD}.md` in the current working directory (NOT in the scanned repo).\n\n### Report template:\n\n```markdown\n# Security Analysis Report: {repo-name}\n\n**Repository**: {repo-url-or-path}\n**Date**: {YYYY-MM-DD}\n**Commit**: {commit-hash}\n**Analyst**: Claude Code Security Analyst Skill\n\n---\n\n## Executive Summary\n\n| Metric | Count |\n|--------|-------|\n| **Verdict** | {Reject / Conditional Approval / Approve} |\n| Dependencies scanned | N (M direct + K key transitive) |\n| Ecosystems | {list} |\n| Dependency CVEs (applicable) | N |\n| Code security findings | N |\n| Capability/abuse-by-design findings | N |\n| Attack chains identified | N |\n| Rejection-grade issues (List 1) | N |\n| Manageable gaps (List 2) | N |\n\n**Deployment Context**: {One-line summary from Phase 1.5, e.g., \"Local laptop deployment, localhost-only, single user, MDR-monitored\"}\n\n{2-3 sentence narrative summary: overall security posture, key strengths, most critical concerns, and whether conditional approval is viable.}\n\n---\n\n## List 1: Rejection-Grade Issues\n\nThese are vulnerabilities or architectural flaws that pose unacceptable risk and should block approval until remediated or mitigated with specific compensating controls.\n\n### R1. {Title}\n\n| Attribute | Detail |\n|-----------|--------|\n| **Location** | {file:line} |\n| **Severity** | {CRITICAL / HIGH} |\n| **Type** | {Bug / Architectural / Configuration / Data exposure} |\n\n**Description**: {Detailed explanation of the issue, including code evidence}\n\n**Evidence**:\n```{lang}\n{code snippet}\n```\n\n**Required Remediation**: {What must be done to fix this}\n\n**Can it be downgraded to List 2?** {Yes/No}. {If yes: \"With the following compensating controls: {exact controls}. Given the deployment context ({context}), this downgrade is {appropriate/not appropriate} because {reason}.\"}\n\n---\n\n{Repeat for R2, R3, etc.}\n\n---\n\n## List 2: Manageable Gaps\n\nThese are real issues that can be addressed through compensating controls, configuration restrictions, or operational procedures.\n\n### M1. {Title}\n\n| Attribute | Detail |\n|-----------|--------|\n| **Location** | {file:line or general area} |\n| **Risk** | {One-line risk description} |\n| **Compensating Control** | {Exact CLI flag, config setting, or operational procedure that mitigates this} |\n| **Control Type** | {Preventive / Detective} |\n| **Residual Risk** | {What risk remains after the control is applied, or \"None\"} |\n\n{Repeat for M2, M3, etc.}\n\n---\n\n## Features Recommended to Be Disabled\n\nThese should be communicated as **mandatory configuration restrictions** for any approved deployment.\n\n| Feature | Disable Via | Reason |\n|---------|-------------|--------|\n| {feature name} | {exact CLI flag, config key, or exclusion method} | {which finding it mitigates \u2014 reference R/M number} |\n| ... | ... | ... |\n\n---\n\n## Deployment Recommendations\n\n### Mandatory Configuration\n\n{For the user's specific deployment model, provide the exact copy-pasteable configuration.}\n\n{For MCP servers \u2014 include JSON config for common clients:}\n\n**For Claude Code** (in `~/.claude/settings.json` or project `.claude/settings.json`):\n```json\n{\n  \"mcpServers\": {\n    \"{server-name}\": {\n      \"command\": \"{command}\",\n      \"args\": [{args with security flags}],\n      \"env\": {\n        {security-relevant env vars}\n      }\n    }\n  }\n}\n```\n\n{For Docker \u2014 include docker-compose overrides or docker run flags}\n{For Kubernetes \u2014 include Helm values overrides}\n{For environment variables \u2014 list what should/shouldn't be set}\n\n### What This Config Blocks\n\n| Threat | Blocked By |\n|--------|-----------|\n| {threat from findings} | {which config flag/setting blocks it} |\n| ... | ... |\n\n---\n\n## Attack Chains\n\nAttack chains represent sequences of vulnerabilities that combine to create a more severe attack than any single issue alone.\n\n### Chain 1: {Attack chain title} \u2014 {Overall severity}\n\n**Path**: {Step 1 (code finding or CVE)} \u2192 {Step 2} \u2192 {Step 3} \u2192 {Impact}\n\n| Step | Finding | Type | Severity Alone |\n|------|---------|------|----------------|\n| 1 | {description} | Code / CVE / Abuse-by-Design | {sev} |\n| 2 | {description} | Code / CVE / Abuse-by-Design | {sev} |\n| ... | ... | ... | ... |\n\n**Combined Impact**: {What an attacker achieves by chaining these together}\n**Likelihood**: {High / Medium / Low} \u2014 {explanation}\n**Overall Severity**: {severity \u2014 may exceed individual findings}\n**Remediation**: {Breaking the chain \u2014 fix the weakest link, or fix all}\n\n---\n\n## Detailed Technical Findings\n\nOrganize findings by domain area for reference. Each finding should already be classified as R{n} or M{n} in the lists above \u2014 this section provides the full technical detail.\n\n### Authentication &amp; Authorization\n{Findings related to auth, OAuth, JWT, session management, access control}\n\n### Credential &amp; Data Storage\n{Findings related to credential storage, encryption at rest, file permissions}\n\n### Input Validation &amp; Injection\n{Findings related to injection, path traversal, query construction}\n\n### Capability &amp; Abuse-by-Design\n{Findings from Phase 5I \u2014 tools/endpoints that work correctly but enable dangerous actions}\n\n### Configuration &amp; Deployment\n{Findings related to defaults, Docker, CI/CD, infrastructure-as-code}\n\n### Dependencies\n{Dependency CVE findings from Phase 4, plus dependency strategy findings from Phase 5F}\n\n### Error Handling &amp; Information Leakage\n{Findings related to error messages, logging, debug endpoints}\n\n---\n\n## Positive Security Practices\n\n{List specific security-positive patterns found in the codebase. This helps the reader understand what the project does well and provides context for the severity of findings.}\n\n1. **{Practice name}**: {Where it is and what it does right}\n2. ...\n\n---\n\n## Verdict\n\n**Assessment**: {Reject / Conditional Approval / Approve}\n\n{If Reject: \"The following issues must be remediated before deployment: {list R numbers}\"}\n\n{If Conditional Approval:}\n\n**Conditions for approval:**\n1. The mandatory configuration above must be enforced for all deployments\n2. {Any additional conditions \u2014 e.g., \"File upstream issues for R5 and R6\"}\n\n### Revised Severity After Compensating Controls\n\n{For each rejection-grade issue that was downgraded, explain the rationale}\n\n| Original | Revised | Rationale |\n|----------|---------|-----------|\n| R{n}: {title} | Downgraded to M{n} | {Compensating control + deployment context that justifies downgrade} |\n\n### Items Not Applicable to This Deployment\n\n| Item | Reason |\n|------|--------|\n| {finding ID and title} | {Why it doesn't apply given DEPLOYMENT_CONTEXT} |\n\n### Upstream Issues to File\n\n{Checklist of specific fixes to request from the upstream maintainer. Provide enough detail that the user could file the issue or PR directly.}\n\n1. [ ] {Issue title} \u2014 {one-line description of the fix needed, referencing the finding}\n2. [ ] ...\n\n### Ongoing Monitoring\n\n{Operational recommendations for maintaining security posture over time}\n\n- {e.g., \"Run dependency scanning weekly against uv.lock\"}\n- {e.g., \"Review upstream releases before upgrading \u2014 new tools may re-introduce disabled features\"}\n\n---\n\n## Not Applicable (Filtered)\n\n{Dependency CVEs that were evaluated and found not applicable to the pinned versions}\n\n| Advisory | Package | Affects | Pinned Version | Status |\n|----------|---------|---------|----------------|--------|\n| {ID} | {package} | {affected range} | {installed version} | Patched / Not affected |\n\n---\n\n## Data Sources\n\n- [OSV.dev](https://osv.dev) \u2014 Open Source Vulnerability Database (batch query API)\n- [GitHub Advisory Database](https://github.com/advisories) \u2014 GitHub Security Advisories (GraphQL API)\n- [NVD](https://nvd.nist.gov) \u2014 National Vulnerability Database (NIST)\n- Source Code Review \u2014 Static analysis of project source files\n\n## Scan Metadata\n\n- **Repository**: {owner/repo or path}\n- **Dependencies by ecosystem**: {breakdown}\n- **Source files reviewed**: {count} {language} files + {other files reviewed}\n- **API queries**: OSV ({n} batch), GitHub ({n} GraphQL), NVD ({n})\n- **Deployment context**: {summary from Phase 1.5}\n- **Clone location**: {path, if cloned} (can be removed)\n```\n\n---\n\n## Error Handling\n\n- **Rate limited**: Wait and retry with exponential backoff. Report which source was rate-limited.\n- **API unreachable**: Skip that source, note it in the report, continue with remaining sources. This applies to ALL external data sources used by the scan: OSV, GitHub Advisory, NVD (Phase 3), endoflife.date (5F runtime/framework EOL check), and api.securityscorecards.dev (5F dependency-health check). Never silently skip \u2014 a missing EOL or health check must appear in the report as a scan gap, not absence-as-evidence-of-no-finding.\n- **Parse failure**: If a manifest file can't be parsed, report the error and continue with other manifests.\n- **Private repo / auth failure**: Ask the user for credentials. Don't proceed without access.\n- **No manifests found**: Report that no supported ecosystems were detected. Still proceed with code review.\n- **No vulnerabilities found**: Still generate a clean report confirming the scan was performed and no issues were found.\n- **Large codebase**: If the repo has thousands of source files, prioritize: entry points and route handlers first, then files that handle auth/crypto/user input, then the rest. Note in the report if coverage was partial.\n\n---\n\n## Important Guidelines\n\n1. **Be thorough**: Query ALL three data sources. Review ALL source files for security issues. Audit ALL exposed capabilities for abuse potential. Don't stop at the first finding.\n2. **Be precise**: Version matching matters. Code findings must include file paths and line numbers. Don't speculate without evidence.\n3. **Be honest**: If you can't determine applicability or exploitability, say so. Don't guess.\n4. **Be efficient**: Use batch APIs where available. When reviewing code, focus on security-relevant patterns rather than reading every line.\n5. **Ask early**: Gather deployment context in Phase 1.5. If additional runtime context is needed for multiple findings, batch your questions to the user.\n6. **Deduplicate**: The same CVE from multiple sources should appear once. The same code pattern in multiple files can be grouped.\n7. **Classify, don't just list**: The two-tier system (Rejection-Grade vs. Manageable) in Phase 6.5 is what makes the report actionable. Every finding must land in one tier with clear rationale.\n8. **Connect the dots**: The attack chain analysis in Phase 6 and abuse-by-design audit in Phase 5I are what distinguish this scan from basic tooling. Always look for how findings amplify each other and how correctly-functioning features create risk.\n9. **Be actionable**: The report must include copy-pasteable deployment configuration and a features-to-disable table. The reader should know exactly what to do, not just what's wrong.\n10. **Clean up**: If you cloned the repo to a temp directory, inform the user of the location so they can clean it up, or offer to delete it.\n", "creation_timestamp": "2026-09-18T15:57:20.738182Z"}