codeprobe-scanner 1.0.4 → 1.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/package.json +1 -1
  2. package/.claude/settings.local.json +0 -19
  3. package/.dockerignore +0 -17
  4. package/.env.development +0 -8
  5. package/.env.setup +0 -214
  6. package/.github/workflows/codeprobe-scan.yml +0 -137
  7. package/.github/workflows/codeprobe.yml +0 -84
  8. package/.github/workflows/scan-schedule.yml +0 -28
  9. package/ANALYSIS_SUMMARY.md +0 -365
  10. package/API_INTEGRATIONS.md +0 -469
  11. package/BUILD_PLAYBOOK.md +0 -349
  12. package/CLAUDE.md +0 -106
  13. package/DEPLOY.md +0 -452
  14. package/DEPLOYMENT_STATUS.md +0 -240
  15. package/DEPLOY_CHECKLIST.md +0 -316
  16. package/Dockerfile +0 -24
  17. package/EXECUTION_PLAN.html +0 -1086
  18. package/IMPLEMENTATION_COMPLETE.md +0 -288
  19. package/IMPLEMENTATION_SUMMARY.md +0 -443
  20. package/INTERACTIVE_FIX_FLOW.md +0 -308
  21. package/MIGRATION_COMPLETE.md +0 -327
  22. package/ORCHESTRATOR_SYNTHESIS.json +0 -80
  23. package/PENDING_WORK.md +0 -308
  24. package/PREFLIGHT_PLAN.md +0 -182
  25. package/QUICKSTART.md +0 -305
  26. package/STAGE_1_SETUP_ENGINE.md +0 -245
  27. package/STAGE_2_ARCHITECTURE.md +0 -714
  28. package/STAGE_2_CLI_VERIFICATION.md +0 -269
  29. package/STAGE_2_COMPLETE.md +0 -332
  30. package/STAGE_2_IMPLEMENTATION_PLAN.md +0 -679
  31. package/STAGE_3_COMPLETE.md +0 -246
  32. package/STAGE_3_DASHBOARD_POLISH.md +0 -371
  33. package/STAGE_3_SETUP.md +0 -155
  34. package/VIDEODB_INTEGRATION.md +0 -237
  35. package/archived/DASHBOARD_UI_WALKTHROUGH.md +0 -392
  36. package/archived/FRONTEND_SETUP.md +0 -236
  37. package/archived/auth.ts +0 -40
  38. package/archived/dashboard/components/BusinessImpactCard.tsx +0 -48
  39. package/archived/dashboard/components/CVETable.tsx +0 -104
  40. package/archived/dashboard/components/ErrorBoundary.tsx +0 -48
  41. package/archived/dashboard/components/PatchDiffViewer.tsx +0 -43
  42. package/archived/dashboard/components/RiskGauge.tsx +0 -64
  43. package/archived/dashboard/frontend.tsx +0 -104
  44. package/archived/dashboard/hooks/useAuth.ts +0 -32
  45. package/archived/dashboard/hooks/useScan.ts +0 -65
  46. package/archived/dashboard/index.html +0 -15
  47. package/archived/dashboard/pages/LoginPage.tsx +0 -28
  48. package/archived/dashboard/pages/ScanDetailPage.tsx +0 -143
  49. package/archived/dashboard/pages/ScansListPage.tsx +0 -160
  50. package/bun.lock +0 -603
  51. package/codeprobe-prd.md +0 -674
  52. package/cve-cache.json +0 -25
  53. package/demo-vulnerable-app/.github/workflows/codeprobe.yml +0 -32
  54. package/demo-vulnerable-app/README.md +0 -70
  55. package/demo-vulnerable-app/package-lock.json +0 -27
  56. package/demo-vulnerable-app/package.json +0 -15
  57. package/demo-vulnerable-app/server.js +0 -34
  58. package/demo.sh +0 -45
  59. package/index.ts +0 -19
  60. package/patches.json +0 -12
  61. package/serve-dashboard.ts +0 -23
  62. package/src/cli/index.ts +0 -137
  63. package/src/engine/index.ts +0 -90
  64. package/src/test/cli.test.ts +0 -211
  65. package/src/test/dashboard.test.ts +0 -38
  66. package/src/test/demo-scan.json +0 -32
  67. package/src/test/engine.test.ts +0 -157
  68. package/tailwind.config.js +0 -11
  69. package/tsconfig.json +0 -30
  70. package/verify-dashboard.ts +0 -87
  71. package/verify-env.sh +0 -98
@@ -1,32 +0,0 @@
1
- name: CodeProbe Demo - Security Scan
2
-
3
- on: [push, pull_request]
4
-
5
- jobs:
6
- scan:
7
- runs-on: ubuntu-latest
8
- steps:
9
- - uses: actions/checkout@v4
10
- with:
11
- fetch-depth: 0
12
-
13
- - name: Setup Bun
14
- uses: oven-sh/setup-bun@v1
15
-
16
- - name: Install CodeProbe
17
- run: |
18
- cd ..
19
- bun install
20
-
21
- - name: Run CodeProbe scan
22
- run: |
23
- cd ..
24
- bun run src/cli/index.ts scan ./demo-vulnerable-app --json
25
- env:
26
- BRIGHT_DATA_API_KEY: ${{ secrets.BRIGHT_DATA_API_KEY }}
27
- DAYTONA_API_KEY: ${{ secrets.DAYTONA_API_KEY }}
28
-
29
- - name: Check for exploitable vulnerabilities
30
- run: |
31
- cd ..
32
- bun run src/cli/index.ts scan ./demo-vulnerable-app --json | grep -q '"exploitable": true' && echo "✅ Vulnerability verified" || echo "⚠️ No exploitable vulnerabilities found"
@@ -1,70 +0,0 @@
1
- # CodeProbe Demo: Vulnerable Node.js App
2
-
3
- This is a deliberately vulnerable Node.js application used to demonstrate CodeProbe's exploit verification capabilities.
4
-
5
- ## Vulnerabilities
6
-
7
- ### CVE-2022-29078: EJS Template Injection RCE
8
-
9
- **Affected Package:** `ejs@3.1.6`
10
- **Severity:** CRITICAL (CVSS 9.8)
11
- **Issue:** The EJS template engine allows template injection attacks that lead to arbitrary code execution.
12
-
13
- **How it's vulnerable:**
14
- - Line in `server.js`: `ejs.render(req.query.template, ...)`
15
- - User can inject malicious EJS template expressions
16
- - Server executes arbitrary JavaScript code
17
-
18
- **Exploit:**
19
- ```bash
20
- curl "http://localhost:3000/?template=<%= require('child_process').execSync('whoami') %>"
21
- ```
22
-
23
- **Fix:** Upgrade `ejs` to version 3.1.7 or higher.
24
-
25
- ## Running the Demo App
26
-
27
- ```bash
28
- cd demo-vulnerable-app
29
- npm install
30
- npm start
31
- ```
32
-
33
- The app listens on `http://localhost:3000`.
34
-
35
- ## Using CodeProbe to Scan
36
-
37
- ```bash
38
- # From the codeprobe root directory:
39
- bun run src/cli/index.ts scan ./demo-vulnerable-app
40
-
41
- # Or with JSON output:
42
- bun run src/cli/index.ts scan ./demo-vulnerable-app --json
43
- ```
44
-
45
- ## Expected Output
46
-
47
- CodeProbe will:
48
- 1. **Parse dependencies** — Extract EJS 3.1.6 from package.json
49
- 2. **Scrape CVE data** — Find CVE-2022-29078 in NVD (via Bright Data)
50
- 3. **Match versions** — Detect that EJS 3.1.6 is vulnerable
51
- 4. **Verify in sandbox** — Spawn a Daytona container and execute the PoC exploit
52
- 5. **Generate patch** — Create a patch to upgrade EJS to 3.1.7
53
- 6. **Report findings** — Display "CONFIRMED EXPLOITABLE" with business impact ($4.9M breach cost)
54
-
55
- ## Why This Demo?
56
-
57
- - **Realistic vulnerability**: EJS template injection is a real, widely-exploited vulnerability
58
- - **Node.js native**: Works in isolated containers without external dependencies
59
- - **Clear proof**: Exploit evidence is captured in sandbox logs
60
- - **Fast verification**: Exploit runs in < 2 seconds
61
-
62
- ## Files
63
-
64
- - `package.json` — Intentionally pinned to vulnerable EJS 3.1.6
65
- - `server.js` — Express server with template injection vulnerability
66
- - `.github/workflows/codeprobe.yml` — CI/CD integration example
67
-
68
- ## Disclaimer
69
-
70
- This app is for **security research and education only**. Do not use in production or with untrusted code.
@@ -1,27 +0,0 @@
1
- {
2
- "name": "demo-vulnerable-app",
3
- "version": "1.0.0",
4
- "lockfileVersion": 3,
5
- "requires": true,
6
- "packages": {
7
- "": {
8
- "name": "demo-vulnerable-app",
9
- "version": "1.0.0",
10
- "dependencies": {
11
- "express": "^4.18.2",
12
- "ejs": "3.1.6"
13
- }
14
- },
15
- "node_modules/express": {
16
- "version": "4.18.2",
17
- "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz"
18
- },
19
- "node_modules/ejs": {
20
- "version": "3.1.6",
21
- "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.6.tgz",
22
- "engines": {
23
- "node": ">=0.10.0"
24
- }
25
- }
26
- }
27
- }
@@ -1,15 +0,0 @@
1
- {
2
- "name": "demo-vulnerable-app",
3
- "version": "1.0.0",
4
- "description": "Demo application with intentional vulnerability for CodeProbe testing",
5
- "main": "server.js",
6
- "scripts": {
7
- "start": "node server.js",
8
- "test": "bun test"
9
- },
10
- "dependencies": {
11
- "express": "^4.18.2",
12
- "ejs": "3.1.6"
13
- },
14
- "devDependencies": {}
15
- }
@@ -1,34 +0,0 @@
1
- const express = require("express");
2
- const ejs = require("ejs");
3
- const app = express();
4
-
5
- app.use(express.urlencoded({ extended: false }));
6
-
7
- // Vulnerable endpoint: directly renders user input as template
8
- app.get("/render", (req, res) => {
9
- const template = req.query.template || "Hello <%= name %>";
10
-
11
- try {
12
- // VULNERABLE: ejs.render() executes arbitrary code in templates
13
- // An attacker can inject: <%= require('child_process').execSync('id') %>
14
- const result = ejs.render(template, { name: "World" });
15
- res.send(`<pre>${result}</pre>`);
16
- } catch (error) {
17
- res.status(500).send(`<pre>Error: ${error.message}</pre>`);
18
- }
19
- });
20
-
21
- app.get("/", (req, res) => {
22
- res.send(`
23
- <h1>CodeProbe Demo - EJS Template Injection</h1>
24
- <p>This app uses EJS ${require("ejs/package.json").version}</p>
25
- <p>Visit: <a href="/render?template=&lt;%= 'VULNERABLE' %>">/render</a> to test</p>
26
- <p>Or send a template parameter to exploit</p>
27
- `);
28
- });
29
-
30
- const port = 3000;
31
- app.listen(port, () => {
32
- console.log(`Demo app listening on http://localhost:${port}`);
33
- console.log(`Vulnerable ejs version: ${require("ejs/package.json").version}`);
34
- });
package/demo.sh DELETED
@@ -1,45 +0,0 @@
1
- #!/bin/bash
2
- set -e
3
-
4
- echo "=== CodeProbe Demo Script ==="
5
- echo ""
6
-
7
- # Colors for output
8
- RED='\033[0;31m'
9
- GREEN='\033[0;32m'
10
- YELLOW='\033[1;33m'
11
- BLUE='\033[0;34m'
12
- NC='\033[0m' # No Color
13
-
14
- # Check if bun is installed
15
- if ! command -v bun &> /dev/null; then
16
- echo -e "${RED}Error: bun is not installed${NC}"
17
- exit 1
18
- fi
19
-
20
- echo -e "${BLUE}1. Clearing previous scans...${NC}"
21
- rm -rf ~/.codeprobe/scans/*
22
- echo -e "${GREEN}✓ Scans cleared${NC}"
23
- echo ""
24
-
25
- echo -e "${BLUE}2. Running scan...${NC}"
26
- time bun run src/cli/index.ts scan .
27
- echo -e "${GREEN}✓ Scan complete${NC}"
28
- echo ""
29
-
30
- echo -e "${BLUE}3. Displaying report...${NC}"
31
- bun run src/cli/index.ts report
32
- echo ""
33
-
34
- echo -e "${BLUE}4. Testing with --json flag...${NC}"
35
- bun run src/cli/index.ts scan . --json | head -20
36
- echo "..."
37
- echo ""
38
-
39
- echo -e "${GREEN}✅ Demo successful!${NC}"
40
- echo ""
41
- echo -e "${YELLOW}Next steps:${NC}"
42
- echo " • Run scan with fix: bun run src/cli/index.ts scan . --fix"
43
- echo " • View config: bun run src/cli/index.ts config get"
44
- echo " • Set API key: bun run src/cli/index.ts config set bright_data_api_key <key>"
45
- echo ""
package/index.ts DELETED
@@ -1,19 +0,0 @@
1
- import { createEngine } from "./src/engine/index";
2
-
3
- const engine = createEngine();
4
- const repoPath = process.argv[2] || "./demo-vulnerable-app";
5
-
6
- console.log(`\n⚡ CodeProbe v1.0.0`);
7
- console.log(`Scanning repository: ${repoPath}\n`);
8
-
9
- try {
10
- const report = await engine.scan(repoPath);
11
- const formatted = (await import("./src/engine/report")).createReportBuilder().formatForTerminal(report);
12
- console.log(formatted);
13
-
14
- // Exit with appropriate code
15
- process.exit(report.summary.exploitable_count > 0 ? 1 : 0);
16
- } catch (error) {
17
- console.error("❌ Scan failed:", error instanceof Error ? error.message : String(error));
18
- process.exit(2);
19
- }
package/patches.json DELETED
@@ -1,12 +0,0 @@
1
- [
2
- {
3
- "cve_id": "CVE-2022-29078",
4
- "package": "ejs",
5
- "from_version": "3.1.0",
6
- "to_version": "3.1.7",
7
- "description": "Fixes template injection RCE vulnerability by sanitizing template inputs",
8
- "diff": "--- a/package.json\n+++ b/package.json\n@@ -5,1 +5,1 @@\n- \"ejs\": \"3.1.6\"\n+ \"ejs\": \"3.1.7\"\n--- a/package-lock.json\n+++ b/package-lock.json\n@@ -10,1 +10,1 @@\n- \"version\": \"3.1.6\",\n+ \"version\": \"3.1.7\",",
9
- "severity": "CRITICAL",
10
- "cvss": 9.8
11
- }
12
- ]
@@ -1,23 +0,0 @@
1
- import { serve } from "bun";
2
- import path from "path";
3
-
4
- const distDir = "dist";
5
-
6
- export default serve({
7
- port: 5173,
8
- fetch(req) {
9
- const url = new URL(req.url);
10
- let filePath = url.pathname;
11
-
12
- if (filePath === "/" || filePath === "") {
13
- filePath = "index.html";
14
- }
15
-
16
- const file = Bun.file(path.join(distDir, filePath));
17
- return file.exists().then(() => new Response(file));
18
- },
19
- });
20
-
21
- console.log("🎨 Dashboard serving on http://localhost:5173");
22
- console.log("📡 API on http://localhost:3000");
23
- console.log("📂 Serving: dist/");
package/src/cli/index.ts DELETED
@@ -1,137 +0,0 @@
1
- #!/usr/bin/env bun
2
-
3
- import chalk from 'chalk';
4
- import { APP_NAME, APP_VERSION, EXIT_CODES } from '../shared/constants.js';
5
- import { ProgressLogger } from './progress.js';
6
- import { handleError } from './errors.js';
7
- import { scanCommand } from './commands/scan.js';
8
- import { reportCommand } from './commands/report.js';
9
-
10
- const logger = new ProgressLogger();
11
-
12
- function showHelp(): void {
13
- console.log(`
14
- ${chalk.bold.cyan(`⚡ ${APP_NAME} v${APP_VERSION}`)}
15
-
16
- ${chalk.bold('USAGE')}
17
- codeprobe <command> [options] [arguments]
18
-
19
- ${chalk.bold('COMMANDS')}
20
- scan [path] Scan a repository for vulnerabilities (default: current dir)
21
- report Display last scan results
22
- config Manage configuration
23
- help Show this help message
24
-
25
- ${chalk.bold('OPTIONS')}
26
- --fix Auto-fix vulnerabilities (creates git branch & commits)
27
- --json Output results as JSON
28
- --verbose Show detailed logs
29
- --help Show help
30
-
31
- ${chalk.bold('EXAMPLES')}
32
- codeprobe scan
33
- codeprobe scan ./my-app
34
- codeprobe scan --fix
35
- codeprobe scan --json > report.json
36
- codeprobe report
37
- codeprobe config set bright_data_api_key <key>
38
-
39
- ${chalk.bold('DOCS')}
40
- https://github.com/codeprobe/codeprobe
41
- `);
42
- }
43
-
44
- async function main(): Promise<void> {
45
- const args = process.argv.slice(2);
46
-
47
- // No args = show help
48
- if (args.length === 0) {
49
- showHelp();
50
- process.exit(EXIT_CODES.SUCCESS);
51
- }
52
-
53
- const command = args[0];
54
- const restArgs = args.slice(1);
55
-
56
- try {
57
- switch (command) {
58
- case 'scan':
59
- await scanCommand(restArgs);
60
- break;
61
-
62
- case 'report':
63
- await reportCommand(restArgs);
64
- break;
65
-
66
- case 'config':
67
- await handleConfigCommand(restArgs);
68
- break;
69
-
70
- case '--help':
71
- case '-h':
72
- case 'help':
73
- showHelp();
74
- break;
75
-
76
- default:
77
- console.error(chalk.red(`Unknown command: ${command}`));
78
- console.log(`Run ${chalk.cyan('codeprobe --help')} for usage`);
79
- process.exit(EXIT_CODES.SCAN_FAILED);
80
- }
81
- } catch (error) {
82
- handleError(error, logger, true);
83
- }
84
- }
85
-
86
- async function handleConfigCommand(args: string[]): Promise<void> {
87
- const { getConfig, setConfig, clearConfig } = await import('./config.js');
88
-
89
- const subcommand = args[0];
90
-
91
- switch (subcommand) {
92
- case 'get':
93
- {
94
- const key = args[1];
95
- if (!key) {
96
- const config = await getConfig();
97
- console.log(JSON.stringify(config, null, 2));
98
- } else {
99
- const value = await getConfig(key);
100
- console.log(value || `${key} not set`);
101
- }
102
- }
103
- break;
104
-
105
- case 'set':
106
- {
107
- const key = args[1];
108
- const value = args[2];
109
- if (!key || !value) {
110
- console.error(chalk.red('Usage: codeprobe config set <key> <value>'));
111
- process.exit(EXIT_CODES.SCAN_FAILED);
112
- }
113
- await setConfig(key, value);
114
- }
115
- break;
116
-
117
- case 'clear':
118
- {
119
- const key = args[1];
120
- if (!key) {
121
- console.error(chalk.red('Usage: codeprobe config clear <key>'));
122
- process.exit(EXIT_CODES.SCAN_FAILED);
123
- }
124
- await clearConfig(key);
125
- }
126
- break;
127
-
128
- default:
129
- console.error(chalk.red(`Unknown config subcommand: ${subcommand}`));
130
- console.log(`Usage: codeprobe config [get|set|clear]`);
131
- process.exit(EXIT_CODES.SCAN_FAILED);
132
- }
133
- }
134
-
135
- main().catch((error) => {
136
- handleError(error, logger, true);
137
- });
@@ -1,90 +0,0 @@
1
- import { createParser } from "./parser";
2
- import { createScraper } from "./scraper";
3
- import { createSandbox } from "./sandbox";
4
- import { createMatcher } from "./matcher";
5
- import { createPatcher } from "./patcher";
6
- import { createReportBuilder } from "./report";
7
- import { Report } from "../shared/types";
8
-
9
- export class CodeProbeEngine {
10
- private parser = createParser();
11
- private scraper = createScraper();
12
- private sandbox = createSandbox();
13
- private matcher = createMatcher();
14
- private patcher = createPatcher();
15
- private reportBuilder = createReportBuilder();
16
-
17
- getVideoRecorder() {
18
- return this.sandbox.getVideoRecorder();
19
- }
20
-
21
- async scan(repoPath: string): Promise<Report> {
22
- const startTime = Date.now();
23
-
24
- try {
25
- // Step 1: Parse dependencies
26
- console.log("📦 Parsing dependencies...");
27
- const dependencies = await this.parser.parseDependencies(repoPath);
28
- console.log(` Found ${dependencies.length} dependencies`);
29
-
30
- // Step 2: Scrape CVEs (Bright Data)
31
- console.log("\x1b[33m[Bright Data]\x1b[0m 🔍 Scraping CVE data from NVD, Exploit-DB, Snyk...");
32
- const cves = await this.scraper.scrapeAll(dependencies);
33
- console.log(` Found ${cves.length} CVEs`);
34
-
35
- // Step 3: Match dependencies to CVEs
36
- console.log("🎯 Matching dependencies to CVEs...");
37
- const matchedCves = this.matcher.matchDependenciesToCVEs(dependencies, cves);
38
- console.log(` Matched ${matchedCves.length} CVEs`);
39
-
40
- // Step 4: Filter CRITICAL/HIGH for sandbox verification
41
- const criticalCves = this.matcher.filterBySeverity(matchedCves, "HIGH");
42
- console.log(` Testing ${criticalCves.length} critical/high severity CVEs...`);
43
-
44
- // Step 5: Run exploit verification in sandboxes (Daytona)
45
- const exploits = criticalCves.map((cve) => ({
46
- packageName: cve.package,
47
- version: cve.version_vulnerable,
48
- cveId: cve.id,
49
- }));
50
-
51
- console.log("\x1b[33m[Daytona]\x1b[0m 🏗️ Spawning isolated sandboxes for exploit verification...");
52
- const sandboxResults = await this.sandbox.parallelRun(exploits);
53
-
54
- // Step 6: Update CVEs with sandbox results
55
- for (const cve of matchedCves) {
56
- const sandboxResult = sandboxResults.get(cve.id);
57
- if (sandboxResult) {
58
- cve.exploitable = sandboxResult.success;
59
- cve.exploit_evidence = sandboxResult.stdout;
60
- cve.verification_time_ms = sandboxResult.time_ms;
61
- }
62
- }
63
-
64
- // Step 7: Generate patches (Nosana)
65
- console.log("\x1b[33m[Nosana]\x1b[0m 🔧 Generating patches with LLM...");
66
- await this.patcher.loadPrebakedPatches();
67
- const patches = await this.patcher.generateAllPatches(matchedCves.filter((c) => c.exploitable));
68
- for (const cve of matchedCves) {
69
- if (patches.has(cve.id)) {
70
- cve.patch_diff = patches.get(cve.id);
71
- }
72
- }
73
-
74
- // Step 8: Calculate risk score
75
- const riskScore = this.matcher.calculateRiskScore(matchedCves);
76
-
77
- // Step 9: Build and save report
78
- const scanDuration = Date.now() - startTime;
79
- const report = await this.reportBuilder.buildReport(repoPath, matchedCves, riskScore, scanDuration, dependencies.length);
80
-
81
- await this.reportBuilder.saveReport(report);
82
-
83
- return report;
84
- } catch (error) {
85
- throw new Error(`Scan failed: ${error instanceof Error ? error.message : String(error)}`);
86
- }
87
- }
88
- }
89
-
90
- export const createEngine = () => new CodeProbeEngine();