Skip to content

Commit f886214

Browse files
committed
Add native AV scans on all 3 platforms + update SECURITY.md
Every platform now has a real antivirus gate that fails the build: - Windows: Windows Defender with ML heuristics (MpCmdRun.exe) - Linux: ClamAV with freshclam signature update - macOS: ClamAV with freshclam signature update Any detection on any platform blocks the release-draft from being created. This is on top of the VirusTotal zero-tolerance gate in the verify job. SECURITY.md updated with complete security architecture.
1 parent 75b5dcb commit f886214

3 files changed

Lines changed: 114 additions & 17 deletions

File tree

.github/workflows/dry-run.yml

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,24 @@ jobs:
302302
if: matrix.variant == 'standard' && matrix.goos == 'linux' && matrix.goarch == 'amd64'
303303
run: scripts/security-fuzz.sh ./codebase-memory-mcp
304304

305+
- name: ClamAV scan (Linux)
306+
if: matrix.variant == 'standard' && startsWith(matrix.os, 'ubuntu')
307+
run: |
308+
sudo apt-get update -qq && sudo apt-get install -y -qq clamav > /dev/null 2>&1
309+
sudo freshclam --quiet 2>/dev/null || true
310+
echo "=== ClamAV scan ==="
311+
clamscan --no-summary ./codebase-memory-mcp
312+
echo "=== ClamAV: clean ==="
313+
314+
- name: ClamAV scan (macOS)
315+
if: matrix.variant == 'standard' && startsWith(matrix.os, 'macos')
316+
run: |
317+
brew install clamav > /dev/null 2>&1
318+
freshclam --quiet 2>/dev/null || true
319+
echo "=== ClamAV scan (macOS) ==="
320+
clamscan --no-summary ./codebase-memory-mcp
321+
echo "=== ClamAV: clean ==="
322+
305323
smoke-windows:
306324
if: ${{ !inputs.skip_builds }}
307325
needs: [build-windows]
@@ -345,3 +363,17 @@ jobs:
345363
if: matrix.variant == 'standard'
346364
shell: msys2 {0}
347365
run: scripts/security-install.sh ./codebase-memory-mcp.exe
366+
367+
- name: Windows Defender scan
368+
if: matrix.variant == 'standard'
369+
shell: pwsh
370+
run: |
371+
Write-Host "=== Windows Defender scan (with ML heuristics) ==="
372+
& "C:\Program Files\Windows Defender\MpCmdRun.exe" -SignatureUpdate 2>$null
373+
$result = & "C:\Program Files\Windows Defender\MpCmdRun.exe" -Scan -ScanType 3 -File "$PWD\codebase-memory-mcp.exe" -DisableRemediation
374+
Write-Host $result
375+
if ($LASTEXITCODE -ne 0) {
376+
Write-Host "BLOCKED: Windows Defender flagged the binary!"
377+
exit 1
378+
}
379+
Write-Host "=== Windows Defender: clean ==="

.github/workflows/release.yml

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,25 @@ jobs:
297297
if: matrix.variant == 'standard' && matrix.goos == 'linux' && matrix.goarch == 'amd64'
298298
run: scripts/security-fuzz.sh ./codebase-memory-mcp
299299

300+
# Native platform antivirus scan
301+
- name: ClamAV scan (Linux)
302+
if: matrix.variant == 'standard' && startsWith(matrix.os, 'ubuntu')
303+
run: |
304+
sudo apt-get update -qq && sudo apt-get install -y -qq clamav > /dev/null 2>&1
305+
sudo freshclam --quiet 2>/dev/null || true
306+
echo "=== ClamAV scan ==="
307+
clamscan --no-summary ./codebase-memory-mcp
308+
echo "=== ClamAV: clean ==="
309+
310+
- name: ClamAV scan (macOS)
311+
if: matrix.variant == 'standard' && startsWith(matrix.os, 'macos')
312+
run: |
313+
brew install clamav > /dev/null 2>&1
314+
freshclam --quiet 2>/dev/null || true
315+
echo "=== ClamAV scan (macOS) ==="
316+
clamscan --no-summary ./codebase-memory-mcp
317+
echo "=== ClamAV: clean ==="
318+
300319
smoke-windows:
301320
needs: [build-windows]
302321
strategy:
@@ -339,6 +358,24 @@ jobs:
339358
shell: msys2 {0}
340359
run: scripts/security-install.sh ./codebase-memory-mcp.exe
341360

361+
# Windows Defender scan (includes ML heuristics — catches what VirusTotal misses)
362+
- name: Windows Defender scan
363+
if: matrix.variant == 'standard'
364+
shell: pwsh
365+
run: |
366+
Write-Host "=== Windows Defender scan (with ML heuristics) ==="
367+
# Update definitions first
368+
& "C:\Program Files\Windows Defender\MpCmdRun.exe" -SignatureUpdate 2>$null
369+
# Full scan of the binary
370+
$result = & "C:\Program Files\Windows Defender\MpCmdRun.exe" -Scan -ScanType 3 -File "$PWD\codebase-memory-mcp.exe" -DisableRemediation
371+
Write-Host $result
372+
if ($LASTEXITCODE -ne 0) {
373+
Write-Host "BLOCKED: Windows Defender flagged the binary!"
374+
Write-Host "Exit code: $LASTEXITCODE"
375+
exit 1
376+
}
377+
Write-Host "=== Windows Defender: clean ==="
378+
342379
# ── Step 5: Create DRAFT release (not public yet) ─────────────
343380
release-draft:
344381
needs: [smoke-unix, smoke-windows, security-static]
@@ -634,8 +671,16 @@ jobs:
634671
REPORT+=$'**Sigstore cosign** — keyless signature verification:\n'
635672
REPORT+=$'```\ncosign verify-blob --bundle <file>.bundle <file>\n```\n\n'
636673
674+
# Native AV scans
675+
REPORT+=$'**Native antivirus scans** — every binary scanned during CI build:\n'
676+
REPORT+=$'- Windows: Windows Defender with ML heuristics (the same engine end users run)\n'
677+
REPORT+=$'- Linux: ClamAV with daily signature updates\n'
678+
REPORT+=$'- macOS: ClamAV with daily signature updates\n\n'
679+
637680
# SBOM
638-
REPORT+=$'**SBOM** — Software Bill of Materials (`sbom.json`) lists all vendored dependencies.\n'
681+
REPORT+=$'**SBOM** — Software Bill of Materials (`sbom.json`) lists all vendored dependencies.\n\n'
682+
683+
REPORT+=$'See [SECURITY.md](https://github.com/DeusData/codebase-memory-mcp/blob/main/SECURITY.md) for full details.\n'
639684
640685
# Append to release notes
641686
EXISTING=$(gh release view "$VERSION" --json body --jq '.body' --repo "$GITHUB_REPOSITORY")

SECURITY.md

Lines changed: 36 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -12,29 +12,46 @@ We will acknowledge your report within 48 hours and provide a fix timeline withi
1212

1313
## Security Measures
1414

15-
This project implements multiple layers of security verification:
16-
17-
### Build-Time (CI)
18-
19-
- **8-layer security audit suite** runs on every build (static analysis, binary string audit, network egress monitoring, install path validation, MCP robustness testing, UI security audit, vendored dependency integrity, smoke test hardening)
20-
- **All dangerous function calls** (`system()`, `popen()`, `fork()`, `connect()`) require a reviewed entry in `scripts/security-allowlist.txt`
21-
- **Vendored dependency checksums** verified on every build (72 files, SHA-256)
22-
23-
### Release-Time
24-
25-
- **VirusTotal scanning** — all release binaries scanned by 70+ antivirus engines, reports linked in release notes
26-
- **SLSA build provenance** — cryptographic attestation proving each binary was built by GitHub Actions from this repository
27-
- **Sigstore cosign signing** — keyless signatures verifiable by anyone
28-
- **SBOM** — Software Bill of Materials listing all vendored dependencies
29-
- **SHA-256 checksums** — published with every release
15+
This project implements multiple layers of security verification. Every release binary must pass all checks before users can download it (draft → verify → publish flow).
16+
17+
### Build-Time (CI — every commit)
18+
19+
- **8-layer security audit suite** runs on every build:
20+
- Layer 1: Static allow-list for dangerous calls (`system`/`popen`/`fork`) + hardcoded URLs
21+
- Layer 2: Binary string audit (URLs, credentials, dangerous commands)
22+
- Layer 3: Network egress monitoring via strace (Linux)
23+
- Layer 4: Install output path + content validation
24+
- Layer 5: Smoke test hardening (clean shutdown, residual processes, version integrity)
25+
- Layer 6: Graph UI audit (external domains, CORS, server binding, eval/iframe)
26+
- Layer 7: MCP robustness (23 adversarial JSON-RPC payloads)
27+
- Layer 8: Vendored dependency integrity (SHA-256 checksums, dangerous call scan)
28+
- **All dangerous function calls** require a reviewed entry in `scripts/security-allowlist.txt`
29+
- **Native antivirus scanning** on every platform (any detection fails the build):
30+
- **Windows**: Windows Defender with ML heuristics — the same engine end users run
31+
- **Linux**: ClamAV with daily signature updates
32+
- **macOS**: ClamAV with daily signature updates
33+
34+
### Release-Time (draft → verify → publish)
35+
36+
Releases are created as **drafts** (invisible to users) and only published after all verification passes:
37+
38+
1. **SLSA build provenance** — cryptographic attestation proving each binary was built by GitHub Actions from this repository
39+
2. **Sigstore cosign signing** — keyless digital signatures verifiable by anyone
40+
3. **SBOM** — Software Bill of Materials (CycloneDX) listing all vendored dependencies
41+
4. **SHA-256 checksums** — published with every release
42+
5. **VirusTotal scanning** — all binaries scanned by 70+ antivirus engines (zero-tolerance: any detection blocks the release)
43+
6. **OpenSSF Scorecard** — repository security health score
44+
45+
If ANY antivirus engine flags ANY binary, the release stays as a draft and is not published until the issue is investigated and resolved.
3046

3147
### Code-Level Defenses
3248

3349
- **Shell injection prevention**`cbm_validate_shell_arg()` rejects metacharacters before all `popen()`/`system()` calls
34-
- **SQLite authorizer** — blocks `ATTACH`/`DETACH` at engine level
50+
- **SQLite authorizer** — blocks `ATTACH`/`DETACH` at engine level (prevents file creation via SQL injection)
3551
- **CORS locked to localhost** — graph UI only accessible from localhost origins
3652
- **Path containment**`realpath()` check prevents reading files outside project root
3753
- **Process-kill restriction** — only server-spawned PIDs can be terminated
54+
- **SHA-256 checksum verification** — update command verifies downloaded binary before installing
3855

3956
### Verification
4057

@@ -49,6 +66,9 @@ cosign verify-blob --bundle <file>.bundle <file>
4966

5067
# SHA-256 checksum
5168
sha256sum -c checksums.txt
69+
70+
# VirusTotal (upload binary or check the report links in the release notes)
71+
# https://www.virustotal.com/
5272
```
5373

5474
## Supported Versions

0 commit comments

Comments
 (0)