mirror of
https://github.com/DeusData/codebase-memory-mcp.git
synced 2026-10-21 05:59:35 +08:00
Add Explore, Galaxy, Architecture, Agents, and System workspaces with a persistent, resizable local chat dock. Attach exact source selections and graph context, render Markdown, and offer pinned opt-in browser models. Keep the galaxy visible below chat and focused on the active file or code selection. Restore hierarchy root selection, resolve projection identities by symbol, and retain loaded search matches after an empty index reply. Expose process measurement units, embed browser runtime MJS/WASM assets, and constrain binary-audit exceptions to reviewed dependency strings. Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
300 lines
12 KiB
Bash
Executable File
300 lines
12 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
# Layer 2: Binary string audit — post-build check on the production binary.
|
|
#
|
|
# Scans extracted strings for:
|
|
# 1. Unauthorized URLs (only github.com + localhost allowed)
|
|
# 2. Suspiciously long base64-encoded payloads
|
|
# 3. Dangerous command names (wget, nc, netcat, telnet, ssh, /dev/tcp)
|
|
# 4. Credential patterns (password=, secret=, api_key=)
|
|
#
|
|
# Usage: scripts/security-strings.sh <binary-path>
|
|
|
|
BINARY="${1:?usage: security-strings.sh <binary-path>}"
|
|
|
|
if [[ ! -f "$BINARY" ]]; then
|
|
echo "FAIL: binary not found: $BINARY"
|
|
exit 1
|
|
fi
|
|
|
|
FAIL=0
|
|
|
|
# Detect file type. Shell scripts and other text files extract poorly via
|
|
# `strings` (the entire content becomes the "strings"), and rules tuned for
|
|
# compiled binaries (URL allowlist, wget/telnet detection) produce false
|
|
# positives — install.sh legitimately uses `wget` as a curl fallback, and
|
|
# `case` glob patterns like `https://*` look like unauthorized URLs.
|
|
#
|
|
# Strategy: for non-binary files we still run credential and base64 audits
|
|
# (those are universally meaningful), but skip the URL and dangerous-command
|
|
# audits which are designed for compiled artifacts. Script content is
|
|
# reviewed in PRs and scanned end-to-end by VirusTotal in the same pipeline.
|
|
IS_SCRIPT=false
|
|
# Structured-text artifacts by EXTENSION first: `file` reports JSON as
|
|
# "JSON data" / "JSON text data", which matched none of the text patterns
|
|
# below, so an .mcpb bundle manifest was audited as if it were a compiled
|
|
# binary and its own homepage/documentation URLs were BLOCKED as unauthorized.
|
|
# The extension check also covers hosts where file(1) is absent, where the
|
|
# `command -v` guard below silently leaves every artifact classified as binary.
|
|
case "$BINARY" in
|
|
*.json|*.jsonc|*.yaml|*.yml|*.toml|*.md|*.txt) IS_SCRIPT=true ;;
|
|
esac
|
|
if [ "$IS_SCRIPT" = false ] && command -v file &>/dev/null; then
|
|
FILE_TYPE=$(file -b "$BINARY" 2>/dev/null || echo "")
|
|
case "$FILE_TYPE" in
|
|
*"shell script"*|*"ASCII text"*|*"UTF-8 Unicode text"*|*"Unicode text"*|*"a /usr/bin/env"*|\
|
|
*"JSON"*|*"XML"*)
|
|
IS_SCRIPT=true
|
|
;;
|
|
esac
|
|
fi
|
|
|
|
if $IS_SCRIPT; then
|
|
echo "=== Layer 2: Script Content Audit ==="
|
|
else
|
|
echo "=== Layer 2: Binary String Audit ==="
|
|
fi
|
|
echo "File: $BINARY"
|
|
echo ""
|
|
|
|
# Check for strings command (needs binutils on some MSYS2 setups)
|
|
if ! command -v strings &>/dev/null; then
|
|
echo "SKIP: 'strings' command not available"
|
|
exit 0
|
|
fi
|
|
|
|
# Extract all printable strings (min length 4)
|
|
STRINGS_FILE=$(mktemp)
|
|
SEC_CMDS=$(mktemp)
|
|
SEC_CREDS=$(mktemp)
|
|
trap 'rm -f "$STRINGS_FILE" "$SEC_CMDS" "$SEC_CREDS"' EXIT
|
|
strings -n 4 "$BINARY" | sort -u > "$STRINGS_FILE"
|
|
|
|
# Remove only byte-for-byte reviewed strings from the named detector candidates.
|
|
# Hash the entire extracted line, excluding its line terminator, without trimming
|
|
# or normalizing. A rebuilt dependency that changes even one byte requires review.
|
|
# Never filter STRINGS_FILE: URL and base64 checks must still inspect these lines.
|
|
filter_reviewed_lines() {
|
|
local candidates="$1"; shift
|
|
local line digest expected allowed
|
|
local -a hash_command
|
|
if command -v sha256sum &>/dev/null; then
|
|
hash_command=(sha256sum)
|
|
elif command -v shasum &>/dev/null; then
|
|
hash_command=(shasum -a 256)
|
|
else
|
|
echo "FAIL: SHA-256 utility required to verify reviewed binary strings" >&2
|
|
return 1
|
|
fi
|
|
while IFS= read -r line; do
|
|
digest=$(printf '%s' "$line" | "${hash_command[@]}")
|
|
digest=${digest%% *}
|
|
allowed=false
|
|
for expected in "$@"; do
|
|
if [[ "$digest" == "$expected" ]]; then
|
|
allowed=true
|
|
break
|
|
fi
|
|
done
|
|
if ! $allowed; then
|
|
printf '%s\n' "$line"
|
|
fi
|
|
done < "$candidates" > "${candidates}.tmp"
|
|
mv "${candidates}.tmp" "$candidates"
|
|
}
|
|
|
|
# ── 1. URL audit (binary only — scripts handled via VT + PR review) ────
|
|
|
|
if $IS_SCRIPT; then
|
|
echo "--- URL audit (skipped — script file) ---"
|
|
else
|
|
echo "--- URL audit ---"
|
|
|
|
# Allowed URL prefixes
|
|
ALLOWED_URLS=(
|
|
"https://api.github.com/repos/DeusData/codebase-memory-mcp"
|
|
"https://github.com/DeusData/codebase-memory-mcp"
|
|
# Our own org root and documentation site: the .mcpb bundle manifest carries
|
|
# them as homepage/documentation fields, and the graph UI links the docs.
|
|
"https://github.com/DeusData"
|
|
"https://deusdata.github.io/codebase-memory-mcp"
|
|
"http://127.0.0.1"
|
|
"http://localhost"
|
|
# SQLite internal URLs (part of vendored sqlite3 strings)
|
|
"https://sqlite.org"
|
|
"https://www.sqlite.org"
|
|
# Toolchain URLs embedded by compiler/linker in static builds
|
|
"https://bugs.launchpad.net"
|
|
"https://gcc.gnu.org"
|
|
"https://sourceware.org"
|
|
# MSYS2 CLANG64 toolchain (libc++/compiler-rt) package-tracker URL, baked
|
|
# into the static Windows .exe — Windows-only, hence Linux smoke stays clean.
|
|
"https://github.com/msys2/MINGW-packages"
|
|
# W3C XML namespace URIs (SVG, MathML, XLink — used in UI bundle)
|
|
"http://www.w3.org/"
|
|
# UI bundle: React, Three.js, Tailwind, Google Fonts, bundled libraries
|
|
"https://react.dev"
|
|
"https://fonts.googleapis.com"
|
|
"https://fonts.gstatic.com"
|
|
"https://tailwindcss.com"
|
|
"https://cdn.jsdelivr.net"
|
|
"https://docs.pmnd.rs"
|
|
"https://jcgt.org"
|
|
"https://github.com/pmndrs"
|
|
"https://github.com/react-spring"
|
|
"https://github.com/101arrowz"
|
|
"https://github.com/arty-name"
|
|
"https://github.com/fredli74"
|
|
"https://github.com/lojjic"
|
|
)
|
|
|
|
# Exact documentation/license/example tokens embedded by pinned UI dependencies:
|
|
# Monaco 0.56.0, Transformers.js 4.2.0, ONNX Runtime, and the Markdown renderer.
|
|
# The URL extractor retains closing Markdown punctuation; keep those exact bytes
|
|
# too. These are references in diagnostics, editor help, and operator schemas,
|
|
# not download-host permissions. No sibling path or hostname inherits an entry.
|
|
ALLOWED_UI_REFERENCE_URLS=(
|
|
"https://web.dev/cross-origin-isolation-guide/"
|
|
"https://code.visualstudio.com/docs/editor/codebasics#_multicursor-modifier)."
|
|
"https://developer.mozilla.org/en-US/docs/Web/API/Cache"
|
|
"https://github.com/huggingface/transformers.js/issues/new/choose"
|
|
"https://github.com/microsoft/vscode/issues/103170"
|
|
"https://github.com/markedjs/marked."
|
|
# Numerical-overflow reference in the ONNX attention schema.
|
|
"https://tinyurl.com/sudb9s96),"
|
|
"https://ieeexplore.ieee.org/document/1163711"
|
|
"https://code.visualstudio.com/docs/editor/codebasics#_find-and-replace)"
|
|
# Sample link insertion text in the Monaco Markdown editor.
|
|
"https://microsoft.com)"
|
|
"https://github.com/syntax-tree/hast-util-to-jsx-runtime"
|
|
"https://github.com/microsoft/vscode/issues/new"
|
|
"https://github.com/microsoft/vscode/blob/main/LICENSE.txt"
|
|
"https://github.com/microsoft/monaco-editor#faq"
|
|
"https://gist.github.com/hollance/42e32852f24243b748ae6bc1f985b13a"
|
|
"https://github.com/remarkjs/react-markdown/blob/main/changelog.md"
|
|
"https://docs.nvidia.com/cuda/cublas/index.html#cublasLtOrder_t"
|
|
"https://arxiv.org/abs/1502.03167."
|
|
)
|
|
|
|
while IFS= read -r url; do
|
|
# Skip short false positives from binary data (e.g. "https://H9")
|
|
if [[ ${#url} -lt 15 ]]; then
|
|
continue
|
|
fi
|
|
allowed=false
|
|
# The pinned, opt-in browser model uses these two verified download hosts.
|
|
# Match host boundaries; a similar hostname must not inherit permission.
|
|
case "$url" in
|
|
"https://huggingface.co"|"https://huggingface.co/"*|"https://huggingface.co;"|\
|
|
"https://us.aws.cdn.hf.co"|"https://us.aws.cdn.hf.co/"*|"https://us.aws.cdn.hf.co;")
|
|
allowed=true
|
|
;;
|
|
esac
|
|
for reference in "${ALLOWED_UI_REFERENCE_URLS[@]}"; do
|
|
if [[ "$url" == "$reference" ]]; then
|
|
allowed=true
|
|
break
|
|
fi
|
|
done
|
|
for prefix in "${ALLOWED_URLS[@]}"; do
|
|
if [[ "$url" == "$prefix"* ]]; then
|
|
allowed=true
|
|
break
|
|
fi
|
|
done
|
|
if ! $allowed; then
|
|
echo "BLOCKED: Unauthorized URL in binary: $url"
|
|
FAIL=1
|
|
fi
|
|
done < <(grep -oE 'https?://[a-zA-Z0-9._/~:@!$&()*+,;=?#%[-]+' "$STRINGS_FILE" || true)
|
|
|
|
if [[ $FAIL -eq 0 ]]; then
|
|
echo "OK: All URLs are authorized."
|
|
fi
|
|
fi # end !IS_SCRIPT URL audit
|
|
|
|
# ── 2. Base64 payload detection ──────────────────────────────────
|
|
|
|
echo ""
|
|
echo "--- Base64 payload detection ---"
|
|
|
|
# Look for base64-like strings longer than 100 chars (potential encoded payloads)
|
|
B64_COUNT=$(grep -cE '^[A-Za-z0-9+/]{100,}={0,2}$' "$STRINGS_FILE" || true)
|
|
if [[ "$B64_COUNT" -gt 0 ]]; then
|
|
echo "WARNING: Found $B64_COUNT potential base64-encoded strings > 100 chars"
|
|
grep -E '^[A-Za-z0-9+/]{100,}={0,2}$' "$STRINGS_FILE" | head -5 | while IFS= read -r s; do
|
|
echo " ${s:0:80}..."
|
|
done
|
|
# Warning only — tree-sitter grammar data can look like base64
|
|
else
|
|
echo "OK: No suspicious base64 payloads found."
|
|
fi
|
|
|
|
# ── 3. Dangerous command detection (binary only) ─────────────────
|
|
|
|
echo ""
|
|
if $IS_SCRIPT; then
|
|
echo "--- Dangerous command detection (skipped — script file) ---"
|
|
DANGEROUS_CMDS=''
|
|
else
|
|
echo "--- Dangerous command detection ---"
|
|
|
|
DANGEROUS_CMDS='wget|netcat|ncat|/dev/tcp|telnet'
|
|
# Known-benign matches (vendored grammar URI scheme tables, etc.). Each entry
|
|
# is a regex matched against the full line; matches are stripped before
|
|
# evaluation. Document the source so reviewers can verify the false positive.
|
|
ALLOWED_DANGEROUS=(
|
|
'^telnet$' # rst tree-sitter grammar: valid_schemas[] in vendored/grammars/rst/tree_sitter_rst/chars.c
|
|
)
|
|
if grep -wE "$DANGEROUS_CMDS" "$STRINGS_FILE" > "$SEC_CMDS" 2>/dev/null && [ -s "$SEC_CMDS" ]; then
|
|
for allow in "${ALLOWED_DANGEROUS[@]}"; do
|
|
grep -vE "$allow" "$SEC_CMDS" > "${SEC_CMDS}.tmp" || true
|
|
mv "${SEC_CMDS}.tmp" "$SEC_CMDS"
|
|
done
|
|
# Monaco 0.56.0 shell tokenizer: wget/telnet occur in its command keyword
|
|
# array. Reviewed full line: assets/shell-DiJ1NA_G.js:1 (2,934 bytes).
|
|
filter_reviewed_lines "$SEC_CMDS" \
|
|
0d9431238bb1665cc08548a02889077577f6a5e2f7f945ccc8c5128cefa7d688
|
|
fi
|
|
if [ -s "$SEC_CMDS" ]; then
|
|
echo "BLOCKED: Dangerous commands found in binary:"
|
|
cat "$SEC_CMDS"
|
|
FAIL=1
|
|
else
|
|
echo "OK: No dangerous commands found."
|
|
fi
|
|
fi # end !IS_SCRIPT dangerous-cmd audit
|
|
|
|
# ── 4. Credential pattern detection ──────────────────────────────
|
|
|
|
echo ""
|
|
echo "--- Credential pattern detection ---"
|
|
|
|
CRED_PATTERNS='password=|secret=|api_key=|apikey=|auth_token=|private_key='
|
|
if grep -iE "$CRED_PATTERNS" "$STRINGS_FILE" > "$SEC_CREDS" 2>/dev/null; then
|
|
# Monaco 0.56.0 quick-input password mode is a boolean/UI property, not a
|
|
# credential. Reviewed full lines: assets/index-B4p3fUhm.js:938 (15,643
|
|
# bytes) and :940 (72,461 bytes). These hashes exempt no command or URL.
|
|
filter_reviewed_lines "$SEC_CREDS" \
|
|
91e70ce96dc9392c3091e0e06a838ad43a0c625b007e9e2ff6256a6d4824e9f2 \
|
|
6e393242a92967b3d1bd03420d0bdfc42b80f18407ef393652580483d2177633
|
|
fi
|
|
if [ -s "$SEC_CREDS" ]; then
|
|
echo "BLOCKED: Credential patterns found in binary:"
|
|
cat "$SEC_CREDS"
|
|
FAIL=1
|
|
else
|
|
echo "OK: No credential patterns found."
|
|
fi
|
|
|
|
# ── Summary ──────────────────────────────────────────────────────
|
|
|
|
echo ""
|
|
if [[ $FAIL -ne 0 ]]; then
|
|
echo "=== BINARY STRING AUDIT FAILED ==="
|
|
exit 1
|
|
fi
|
|
|
|
echo "=== Binary string audit passed ==="
|