forked from DeusData/codebase-memory-mcp
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsecurity-network.sh
More file actions
executable file
·106 lines (88 loc) · 3.35 KB
/
Copy pathsecurity-network.sh
File metadata and controls
executable file
·106 lines (88 loc) · 3.35 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#!/usr/bin/env bash
set -euo pipefail
# Layer 3: Network egress test — monitors outbound connections during MCP session.
#
# Runs a full MCP session (initialize → index → search → EOF) under strace
# and verifies only expected connections are made.
#
# Linux only (strace required). macOS/Windows: skip with success.
#
# Usage: scripts/security-network.sh <binary-path>
BINARY="${1:?usage: security-network.sh <binary-path>}"
if [[ ! -f "$BINARY" ]]; then
echo "FAIL: binary not found: $BINARY"
exit 1
fi
echo "=== Layer 3: Network Egress Test ==="
# Skip on non-Linux (no strace)
if [[ "$(uname)" != "Linux" ]]; then
echo "SKIP: strace not available on $(uname) — covered by binary string audit"
exit 0
fi
if ! command -v strace &>/dev/null; then
echo "SKIP: strace not installed"
exit 0
fi
TMPDIR=$(mktemp -d)
trap 'rm -rf "$TMPDIR"' EXIT
# Create a minimal test project
mkdir -p "$TMPDIR/project/src"
cat > "$TMPDIR/project/src/main.py" << 'EOF'
def main():
print("hello")
EOF
# MCP session input (jsonrpc over stdio)
cat > "$TMPDIR/input.jsonl" << JSONL
{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}
{"jsonrpc":"2.0","method":"notifications/initialized"}
{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"index_repository","arguments":{"repo_path":"$TMPDIR/project"}}}
{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"search_graph","arguments":{"name_pattern":"main"}}}
JSONL
STRACE_LOG="$TMPDIR/strace.log"
echo "Running MCP session under strace..."
# Run binary with strace monitoring connect() syscalls
# -f: follow forks, -e trace=connect: only log connect() calls
timeout 30 strace -f -e trace=connect \
"$BINARY" < "$TMPDIR/input.jsonl" \
> "$TMPDIR/output.jsonl" 2> "$STRACE_LOG" || true
echo ""
echo "--- Connection log ---"
FAIL=0
# Parse strace output for connect() calls with AF_INET (IPv4 network)
# Format: connect(fd, {sa_family=AF_INET, sin_port=htons(443), sin_addr=inet_addr("x.x.x.x")}, ...)
if grep 'sa_family=AF_INET' "$STRACE_LOG" > "$TMPDIR/connections.log" 2>/dev/null; then
while IFS= read -r conn; do
# Extract destination IP and port
ip=$(echo "$conn" | grep -oP 'inet_addr\("\K[^"]+' || echo "unknown")
port=$(echo "$conn" | grep -oP 'htons\(\K[0-9]+' || echo "0")
# Allowed connections:
# - 127.0.0.1 (localhost, any port)
# - DNS (port 53, any IP)
case "$ip" in
127.0.0.1|0.0.0.0)
echo " OK: localhost:$port"
;;
*)
if [[ "$port" == "53" ]]; then
echo " OK: DNS lookup to $ip"
elif [[ "$port" == "443" ]]; then
echo " BLOCKED: Unexpected HTTPS connection to $ip:$port"
FAIL=1
else
echo " BLOCKED: Unexpected connection to $ip:$port"
FAIL=1
fi
;;
esac
done < "$TMPDIR/connections.log"
else
echo " No outbound connections detected."
fi
echo ""
if [[ $FAIL -ne 0 ]]; then
echo "=== NETWORK EGRESS TEST FAILED ==="
echo "Unexpected outbound connections detected. Full strace log:"
grep 'connect(' "$STRACE_LOG" || true
exit 1
fi
echo "=== Network egress test passed ==="