{
  "schemaVersion": "1.0.0",
  "product": "VibeCode ShipCheck",
  "generatedAt": "2026-07-18T00:00:00.000Z",
  "scope": {
    "rootName": "vulnerable-app",
    "authorization": "local repository supplied by the operator",
    "mode": "static pre-launch readiness review; no penetration testing"
  },
  "project": {
    "frameworks": [
      "Next.js"
    ],
    "packageManager": null,
    "scripts": {
      "build": "present",
      "test": "missing"
    }
  },
  "scan": {
    "textFilesScanned": 6,
    "ignored": 0,
    "skippedBinary": 0,
    "skippedLarge": 0,
    "skippedSymlink": 0,
    "dependencyAudit": {
      "status": "skipped",
      "packageManager": null,
      "counts": null,
      "reason": "Not requested"
    }
  },
  "summary": {
    "verdict": "block",
    "readinessScore": 0,
    "counts": {
      "critical": 4,
      "high": 4,
      "medium": 3,
      "low": 4,
      "total": 15
    }
  },
  "findings": [
    {
      "findingId": "F-001",
      "ruleId": "SHIP-ENV-002",
      "severity": "critical",
      "category": "environment",
      "title": "Sensitive-looking variable is explicitly marked public",
      "location": {
        "file": "app/page.tsx",
        "line": 3
      },
      "evidence": "NEXT_PUBLIC_ADMIN_TOKEN=<redacted>",
      "impact": "Public-prefixed environment variables are normally embedded into browser-delivered JavaScript.",
      "remediation": "Move the operation requiring this value to server-only code, rename the variable without a public prefix, then rotate any previously deployed value.",
      "falsePositiveNotes": "Some provider identifiers are intentionally publishable. Confirm the provider's documentation and least-privilege scope.",
      "blocksLaunch": true
    },
    {
      "findingId": "F-002",
      "ruleId": "SHIP-SECRET-001",
      "severity": "critical",
      "category": "secrets",
      "title": "Credential-like value is present in repository content",
      "location": {
        "file": "env.production",
        "line": 2
      },
      "evidence": "OpenAI-style key=<redacted:openai-key>",
      "impact": "A committed or shared credential can be reused outside the intended system.",
      "remediation": "Revoke and rotate the credential, remove it from repository history, and load the replacement only from a server-side secret store.",
      "falsePositiveNotes": "Pattern matching cannot prove validity. Confirm whether the value is synthetic, but keep it redacted while checking.",
      "blocksLaunch": true
    },
    {
      "findingId": "F-003",
      "ruleId": "SHIP-ENV-002",
      "severity": "critical",
      "category": "environment",
      "title": "Sensitive-looking variable is explicitly marked public",
      "location": {
        "file": "env.production",
        "line": 3
      },
      "evidence": "NEXT_PUBLIC_ADMIN_TOKEN=<redacted>",
      "impact": "Public-prefixed environment variables are normally embedded into browser-delivered JavaScript.",
      "remediation": "Move the operation requiring this value to server-only code, rename the variable without a public prefix, then rotate any previously deployed value.",
      "falsePositiveNotes": "Some provider identifiers are intentionally publishable. Confirm the provider's documentation and least-privilege scope.",
      "blocksLaunch": true
    },
    {
      "findingId": "F-004",
      "ruleId": "SHIP-SECRET-002",
      "severity": "critical",
      "category": "secrets",
      "title": "Credential-like value is stored in a public asset",
      "location": {
        "file": "public/runtime-config.js",
        "line": 3
      },
      "evidence": "OpenAI-style key=<redacted:openai-key>",
      "impact": "A deployed public asset can expose the credential to every visitor.",
      "remediation": "Revoke and rotate the credential, remove it from repository history, and load the replacement only from a server-side secret store.",
      "falsePositiveNotes": "Pattern matching cannot prove validity. Confirm whether the value is synthetic, but keep it redacted while checking.",
      "blocksLaunch": true
    },
    {
      "findingId": "F-005",
      "ruleId": "SHIP-ENV-001",
      "severity": "high",
      "category": "environment",
      "title": "Non-template environment file is inside the scanned tree",
      "location": {
        "file": "env.production",
        "line": 1
      },
      "evidence": "env.production (contents withheld)",
      "impact": "Environment files are frequently committed, copied, or uploaded with deploy artifacts by mistake.",
      "remediation": "Keep only a value-free .env.example in the repository, ignore runtime env files, and configure secrets in the deployment platform.",
      "falsePositiveNotes": "Presence does not prove the file is tracked. Verify with the source-control index and deployment include rules.",
      "blocksLaunch": false
    },
    {
      "findingId": "F-006",
      "ruleId": "SHIP-NEXT-003",
      "severity": "high",
      "category": "security-config",
      "title": "Server Actions accept every origin",
      "location": {
        "file": "next.config.mjs",
        "line": 3
      },
      "evidence": "allowedOrigins: [\"*\"],",
      "impact": "An unrestricted origin policy weakens a key cross-site request protection boundary.",
      "remediation": "Remove the override or list only the exact trusted origins required by the deployment.",
      "falsePositiveNotes": null,
      "blocksLaunch": true
    },
    {
      "findingId": "F-007",
      "ruleId": "SHIP-BUILD-002",
      "severity": "high",
      "category": "release-readiness",
      "title": "Build script starts a development server",
      "location": {
        "file": "package.json",
        "line": 1
      },
      "evidence": "scripts.build=next dev",
      "impact": "Development mode is not a reproducible or hardened production build and can stall release automation.",
      "remediation": "Replace the script with the framework's production build command, such as next build or vite build.",
      "falsePositiveNotes": null,
      "blocksLaunch": true
    },
    {
      "findingId": "F-008",
      "ruleId": "SHIP-CODE-001",
      "severity": "high",
      "category": "security-config",
      "title": "Dynamic code execution primitive is present",
      "location": {
        "file": "src/render.mjs",
        "line": 3
      },
      "evidence": "return eval(templateSource);",
      "impact": "If attacker-influenced data reaches this call, it can become arbitrary JavaScript execution.",
      "remediation": "Replace string-to-code execution with explicit parsing, validated data structures, and allowlisted handlers.",
      "falsePositiveNotes": "This is a static signal. Confirm whether untrusted data can reach the code and whether an equivalent external control exists.",
      "blocksLaunch": false
    },
    {
      "findingId": "F-009",
      "ruleId": "SHIP-ENV-003",
      "severity": "medium",
      "category": "environment",
      "title": "Environment files are not visibly ignored",
      "location": null,
      "evidence": ".gitignore not found",
      "impact": "A developer can accidentally add local credentials to source control.",
      "remediation": "Ignore .env and .env.* while explicitly allowing only value-free templates such as .env.example.",
      "falsePositiveNotes": null,
      "blocksLaunch": false
    },
    {
      "findingId": "F-010",
      "ruleId": "SHIP-CODE-002",
      "severity": "medium",
      "category": "security-config",
      "title": "Raw HTML rendering sink requires review",
      "location": {
        "file": "app/page.tsx",
        "line": 7
      },
      "evidence": "return <main data-token=<redacted>} dangerouslySetInnerHTML={{ __html: html }} />;",
      "impact": "Unsanitized or attacker-influenced HTML can execute script in a visitor's browser.",
      "remediation": "Render structured components or plain text. If rich HTML is required, use a maintained allowlist sanitizer and a restrictive CSP.",
      "falsePositiveNotes": "This is a static signal. Confirm whether untrusted data can reach the code and whether an equivalent external control exists.",
      "blocksLaunch": false
    },
    {
      "findingId": "F-011",
      "ruleId": "SHIP-TEST-001",
      "severity": "medium",
      "category": "release-readiness",
      "title": "No meaningful automated test command is defined",
      "location": {
        "file": "package.json",
        "line": 1
      },
      "evidence": "scripts.test is missing",
      "impact": "Core behavior can regress without a repeatable pre-release signal.",
      "remediation": "Add a deterministic test command that exits non-zero on failure and run it before deployment.",
      "falsePositiveNotes": null,
      "blocksLaunch": false
    },
    {
      "findingId": "F-012",
      "ruleId": "SHIP-DEP-002",
      "severity": "low",
      "category": "dependencies",
      "title": "No supported dependency lockfile was found",
      "location": null,
      "evidence": "Expected package-lock.json, pnpm-lock.yaml, or yarn.lock",
      "impact": "Different installs can resolve different dependency versions.",
      "remediation": "Generate and commit exactly one lockfile with the package manager used by CI and production.",
      "falsePositiveNotes": null,
      "blocksLaunch": false
    },
    {
      "findingId": "F-013",
      "ruleId": "SHIP-HEADERS-001",
      "severity": "low",
      "category": "security-config",
      "title": "Content Security Policy is not visible in repository configuration",
      "location": null,
      "evidence": "No Content-Security-Policy declaration found in scanned text files",
      "impact": "A browser-side injection flaw would have fewer defense-in-depth constraints.",
      "remediation": "Verify the live response headers. If the edge does not provide CSP, add and test a restrictive policy appropriate to the app.",
      "falsePositiveNotes": "The CDN, reverse proxy, or hosting platform may inject this header outside the repository.",
      "blocksLaunch": false
    },
    {
      "findingId": "F-014",
      "ruleId": "SHIP-DEBT-001",
      "severity": "low",
      "category": "release-readiness",
      "title": "1 unresolved release marker in one file",
      "location": {
        "file": "app/page.tsx",
        "line": 6
      },
      "evidence": "// TODO: replace raw HTML before a real release.",
      "impact": "An unfinished note can represent intentionally deferred behavior or a forgotten release blocker.",
      "remediation": "Classify each marker as release-blocking, scheduled follow-up, or obsolete; remove or link it to a tracked issue.",
      "falsePositiveNotes": "Documentation may mention marker words without representing unfinished work.",
      "blocksLaunch": false
    },
    {
      "findingId": "F-015",
      "ruleId": "SHIP-DEBT-001",
      "severity": "low",
      "category": "release-readiness",
      "title": "1 unresolved release marker in one file",
      "location": {
        "file": "src/render.mjs",
        "line": 2
      },
      "evidence": "// FIXME: dynamic evaluation is intentionally unsafe in this test fixture.",
      "impact": "An unfinished note can represent intentionally deferred behavior or a forgotten release blocker.",
      "remediation": "Classify each marker as release-blocking, scheduled follow-up, or obsolete; remove or link it to a tracked issue.",
      "falsePositiveNotes": "Documentation may mention marker words without representing unfinished work.",
      "blocksLaunch": false
    }
  ],
  "limitations": [
    "Static heuristics can produce false positives and cannot prove exploitability or runtime reachability.",
    "Files larger than the configured limit, binary files, symlinks, generated output, dependencies, and ignored directories are not inspected.",
    "Runtime headers, deployment-platform settings, secret-manager configuration, and external services require separate verification.",
    "A pass verdict is not a security guarantee; it means this bounded scan found no medium-or-higher release condition."
  ]
}
