Skip to content

Commit c371e9f

Browse files
committed
Add time-bomb + MCP file read audit, tracked pre-commit hooks
Security audit (Layer 1) new checks: - Time-bomb scan: flags time()/sleep()/clock() near dangerous calls - MCP file read audit: tracks fopen/fread count in mcp.c against expected max (detects data exfiltration through tool responses) Pre-commit hooks now tracked in scripts/hooks/: - Contributors activate with: git config core.hooksPath scripts/hooks - Runs: lint → security audit → build + test - setup.sh already configures this automatically
1 parent e0bce84 commit c371e9f

File tree

4 files changed

+79
-33
lines changed

4 files changed

+79
-33
lines changed

CONTRIBUTING.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ Contributions are welcome. This guide covers setup, testing, and PR guidelines.
1111
```bash
1212
git clone https://github.com/DeusData/codebase-memory-mcp.git
1313
cd codebase-memory-mcp
14+
git config core.hooksPath scripts/hooks # activates pre-commit security checks
1415
scripts/build.sh
1516
```
1617

SECURITY.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ This project implements multiple layers of security verification. Every release
2626
- Layer 7: MCP robustness (23 adversarial JSON-RPC payloads)
2727
- Layer 8: Vendored dependency integrity (SHA-256 checksums, dangerous call scan)
2828
- **All dangerous function calls** require a reviewed entry in `scripts/security-allowlist.txt`
29+
- **Time-bomb pattern detection** — scans for `time()`/`sleep()` near dangerous calls (could indicate delayed activation)
30+
- **MCP tool handler file read audit** — tracks file read count in `mcp.c` against an expected maximum (detects added file reads that could exfiltrate data through tool responses)
2931
- **Native antivirus scanning** on every platform (any detection fails the build):
3032
- **Windows**: Windows Defender with ML heuristics — the same engine end users run
3133
- **Linux**: ClamAV with daily signature updates

scripts/hooks/pre-commit

Lines changed: 7 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,16 @@
11
#!/usr/bin/env bash
22
set -euo pipefail
33

4-
# Pre-commit hook: C linting + tests.
5-
# Mirrors the lint targets in Makefile.cbm.
4+
# Pre-commit hook: linters + security audit + build + tests.
65
#
7-
# Setup (once after clone):
6+
# Activated automatically via scripts/setup.sh or manually:
87
# git config core.hooksPath scripts/hooks
98

10-
LLVM_BIN="$(brew --prefix llvm 2>/dev/null)/bin"
9+
echo "pre-commit: running all linters in parallel..."
10+
make -j3 -f Makefile.cbm lint
1111

12-
# Resolve tool paths (Homebrew LLVM is keg-only on macOS)
13-
CLANG_TIDY="${LLVM_BIN}/clang-tidy"
14-
CLANG_FORMAT="${LLVM_BIN}/clang-format"
15-
[ -x "$CLANG_TIDY" ] || CLANG_TIDY="clang-tidy"
16-
[ -x "$CLANG_FORMAT" ] || CLANG_FORMAT="clang-format"
12+
echo "pre-commit: security audit (source-level)..."
13+
scripts/security-audit.sh
1714

18-
# --- clang-format (blocking — fastest, check first) ---
19-
echo "pre-commit: checking formatting..."
20-
make -f Makefile.cbm lint-format CLANG_FORMAT="$CLANG_FORMAT"
21-
22-
# --- cppcheck (blocking) ---
23-
if command -v cppcheck &>/dev/null; then
24-
echo "pre-commit: running cppcheck..."
25-
make -f Makefile.cbm lint-cppcheck
26-
else
27-
echo "pre-commit: cppcheck not found, skipping"
28-
echo " install: brew install cppcheck"
29-
fi
30-
31-
# --- clang-tidy (blocking) ---
32-
if command -v "$CLANG_TIDY" &>/dev/null; then
33-
echo "pre-commit: running clang-tidy..."
34-
make -f Makefile.cbm lint-tidy CLANG_TIDY="$CLANG_TIDY"
35-
else
36-
echo "pre-commit: clang-tidy not found, skipping"
37-
echo " install: brew install llvm"
38-
fi
39-
40-
# --- Build + Tests (blocking) ---
4115
echo "pre-commit: building and running tests..."
42-
make -f Makefile.cbm test
16+
make -j$(sysctl -n hw.ncpu 2>/dev/null || nproc) -f Makefile.cbm test

scripts/security-audit.sh

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,75 @@ if ! $FOPEN_FOUND; then
184184
echo "OK: All file writes are in expected locations."
185185
fi
186186

187+
# ── 4. Time-bomb pattern detection ────────────────────────────────
188+
# Scan for time/clock/sleep near dangerous calls — could indicate
189+
# code that activates malicious behavior after a delay or date.
190+
191+
echo ""
192+
echo "--- Scanning for time-bomb patterns ---"
193+
194+
TIMEBOMB_FOUND=false
195+
while IFS= read -r file; do
196+
relfile="${file#"$ROOT/"}"
197+
198+
# Extract line numbers of dangerous calls
199+
DANGER_LINES=$(grep -n 'system(\|popen(\|cbm_popen(\|connect(\|execl(' "$file" 2>/dev/null \
200+
| grep -v '^\s*//' | grep -v '^\s*\*' | grep -v '#define' \
201+
| cut -d: -f1 || true)
202+
203+
[ -z "$DANGER_LINES" ] && continue
204+
205+
# For each dangerous call, check if time/clock/sleep appears within 10 lines
206+
for dline in $DANGER_LINES; do
207+
start=$((dline > 10 ? dline - 10 : 1))
208+
end=$((dline + 10))
209+
NEARBY=$(sed -n "${start},${end}p" "$file" 2>/dev/null \
210+
| grep -E 'time\(|clock\(|sleep\(|nanosleep\(|usleep\(' \
211+
| grep -v '^\s*//' | grep -v '^\s*\*' | grep -v 'timeout' | grep -v 'elapsed' || true)
212+
if [ -n "$NEARBY" ]; then
213+
echo "REVIEW: ${relfile}:${dline}: time-related call near dangerous function"
214+
echo " $NEARBY"
215+
TIMEBOMB_FOUND=true
216+
fi
217+
done
218+
done < <(find "$ROOT/src" -name '*.c' -type f | sort)
219+
220+
if ! $TIMEBOMB_FOUND; then
221+
echo "OK: No suspicious time-bomb patterns found."
222+
fi
223+
224+
# ── 5. MCP tool handler file read audit ──────────────────────────
225+
# The MCP server (mcp.c) handles tool calls that return data to the
226+
# client. A malicious PR could add file reads that exfiltrate sensitive
227+
# data (e.g., ~/.ssh/id_rsa) through the normal tool response channel.
228+
# Track all file-reading functions in mcp.c against an allow-list.
229+
230+
echo ""
231+
echo "--- Scanning MCP tool handlers for file reads ---"
232+
233+
MCP_FILE="$ROOT/src/mcp/mcp.c"
234+
MCP_READS_OK=true
235+
if [ -f "$MCP_FILE" ]; then
236+
# Known safe file reads in mcp.c (with line-range context)
237+
# - search_code: writes pattern to tmpfile, reads grep output
238+
# - get_code_snippet: reads source via read_file_lines (path-contained)
239+
# - manage_adr: reads/writes ADR files
240+
# - detect_changes: reads git diff output
241+
# Count fopen/fread calls and compare against expected
242+
FOPEN_COUNT=$(grep -c 'fopen\|fread\|read_file' "$MCP_FILE" 2>/dev/null || echo "0")
243+
# Known count as of v0.5.5: update this when legitimate reads are added
244+
EXPECTED_MAX=12
245+
if [ "$FOPEN_COUNT" -gt "$EXPECTED_MAX" ]; then
246+
echo "REVIEW: src/mcp/mcp.c has $FOPEN_COUNT file read operations (expected max $EXPECTED_MAX)"
247+
echo " New file reads in MCP tool handlers must be reviewed for data exfiltration risk."
248+
MCP_READS_OK=false
249+
fi
250+
fi
251+
252+
if $MCP_READS_OK; then
253+
echo "OK: MCP tool handler file reads within expected count."
254+
fi
255+
187256
# ── Summary ──────────────────────────────────────────────────────
188257

189258
echo ""

0 commit comments

Comments
 (0)