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.
- package/package.json +1 -1
- package/.claude/settings.local.json +0 -19
- package/.dockerignore +0 -17
- package/.env.development +0 -8
- package/.env.setup +0 -214
- package/.github/workflows/codeprobe-scan.yml +0 -137
- package/.github/workflows/codeprobe.yml +0 -84
- package/.github/workflows/scan-schedule.yml +0 -28
- package/ANALYSIS_SUMMARY.md +0 -365
- package/API_INTEGRATIONS.md +0 -469
- package/BUILD_PLAYBOOK.md +0 -349
- package/CLAUDE.md +0 -106
- package/DEPLOY.md +0 -452
- package/DEPLOYMENT_STATUS.md +0 -240
- package/DEPLOY_CHECKLIST.md +0 -316
- package/Dockerfile +0 -24
- package/EXECUTION_PLAN.html +0 -1086
- package/IMPLEMENTATION_COMPLETE.md +0 -288
- package/IMPLEMENTATION_SUMMARY.md +0 -443
- package/INTERACTIVE_FIX_FLOW.md +0 -308
- package/MIGRATION_COMPLETE.md +0 -327
- package/ORCHESTRATOR_SYNTHESIS.json +0 -80
- package/PENDING_WORK.md +0 -308
- package/PREFLIGHT_PLAN.md +0 -182
- package/QUICKSTART.md +0 -305
- package/STAGE_1_SETUP_ENGINE.md +0 -245
- package/STAGE_2_ARCHITECTURE.md +0 -714
- package/STAGE_2_CLI_VERIFICATION.md +0 -269
- package/STAGE_2_COMPLETE.md +0 -332
- package/STAGE_2_IMPLEMENTATION_PLAN.md +0 -679
- package/STAGE_3_COMPLETE.md +0 -246
- package/STAGE_3_DASHBOARD_POLISH.md +0 -371
- package/STAGE_3_SETUP.md +0 -155
- package/VIDEODB_INTEGRATION.md +0 -237
- package/archived/DASHBOARD_UI_WALKTHROUGH.md +0 -392
- package/archived/FRONTEND_SETUP.md +0 -236
- package/archived/auth.ts +0 -40
- package/archived/dashboard/components/BusinessImpactCard.tsx +0 -48
- package/archived/dashboard/components/CVETable.tsx +0 -104
- package/archived/dashboard/components/ErrorBoundary.tsx +0 -48
- package/archived/dashboard/components/PatchDiffViewer.tsx +0 -43
- package/archived/dashboard/components/RiskGauge.tsx +0 -64
- package/archived/dashboard/frontend.tsx +0 -104
- package/archived/dashboard/hooks/useAuth.ts +0 -32
- package/archived/dashboard/hooks/useScan.ts +0 -65
- package/archived/dashboard/index.html +0 -15
- package/archived/dashboard/pages/LoginPage.tsx +0 -28
- package/archived/dashboard/pages/ScanDetailPage.tsx +0 -143
- package/archived/dashboard/pages/ScansListPage.tsx +0 -160
- package/bun.lock +0 -603
- package/codeprobe-prd.md +0 -674
- package/cve-cache.json +0 -25
- package/demo-vulnerable-app/.github/workflows/codeprobe.yml +0 -32
- package/demo-vulnerable-app/README.md +0 -70
- package/demo-vulnerable-app/package-lock.json +0 -27
- package/demo-vulnerable-app/package.json +0 -15
- package/demo-vulnerable-app/server.js +0 -34
- package/demo.sh +0 -45
- package/index.ts +0 -19
- package/patches.json +0 -12
- package/serve-dashboard.ts +0 -23
- package/src/cli/index.ts +0 -137
- package/src/engine/index.ts +0 -90
- package/src/test/cli.test.ts +0 -211
- package/src/test/dashboard.test.ts +0 -38
- package/src/test/demo-scan.json +0 -32
- package/src/test/engine.test.ts +0 -157
- package/tailwind.config.js +0 -11
- package/tsconfig.json +0 -30
- package/verify-dashboard.ts +0 -87
- 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=<%= '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
|
-
]
|
package/serve-dashboard.ts
DELETED
|
@@ -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
|
-
});
|
package/src/engine/index.ts
DELETED
|
@@ -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();
|