mirror of
https://github.com/BishopFox/otto-support.git
synced 2026-11-07 10:26:04 -10:00
105 lines
3.1 KiB
Bash
Executable File
105 lines
3.1 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
#
|
|
# compare-logs.sh — Side-by-side comparison of minimal vs audit logs.
|
|
#
|
|
# The MCP server writes BOTH minimal.log and audit.log regardless of the
|
|
# --log-mode flag, so you can run any attack (SSRF, support_override, agent
|
|
# against a malicious ticket, etc.) and then diff the two files to see what
|
|
# a default-logging profile *misses* vs. what a real audit trail captures.
|
|
#
|
|
# Usage:
|
|
# scripts/compare-logs.sh # show both logs
|
|
# scripts/compare-logs.sh clear # truncate both log files
|
|
# scripts/compare-logs.sh minimal # show only minimal.log
|
|
# scripts/compare-logs.sh audit # show only audit.log (pretty)
|
|
# LOG_DIR=/var/log/mcp scripts/compare-logs.sh
|
|
#
|
|
set -euo pipefail
|
|
|
|
LOG_DIR="${LOG_DIR:-logs}"
|
|
MIN_LOG="${LOG_DIR}/minimal.log"
|
|
AUDIT_LOG="${LOG_DIR}/audit.log"
|
|
|
|
die() { echo "error: $*" >&2; exit 1; }
|
|
rule() { printf '%s\n' "----------------------------------------------------------------------"; }
|
|
|
|
have_jq() { command -v jq >/dev/null 2>&1; }
|
|
|
|
pretty_audit() {
|
|
local f="$1"
|
|
[[ -s "$f" ]] || { echo "(empty)"; return; }
|
|
if have_jq; then
|
|
jq -c '.' < "$f"
|
|
else
|
|
cat "$f"
|
|
fi
|
|
}
|
|
|
|
case "${1:-compare}" in
|
|
clear)
|
|
: > "$MIN_LOG" 2>/dev/null || die "cannot truncate $MIN_LOG"
|
|
: > "$AUDIT_LOG" 2>/dev/null || die "cannot truncate $AUDIT_LOG"
|
|
echo "cleared: $MIN_LOG"
|
|
echo "cleared: $AUDIT_LOG"
|
|
exit 0
|
|
;;
|
|
|
|
minimal)
|
|
[[ -r "$MIN_LOG" ]] || die "missing $MIN_LOG — is the server running with --log-dir $LOG_DIR ?"
|
|
cat "$MIN_LOG"
|
|
exit 0
|
|
;;
|
|
|
|
audit)
|
|
[[ -r "$AUDIT_LOG" ]] || die "missing $AUDIT_LOG — is the server running with --log-dir $LOG_DIR ?"
|
|
pretty_audit "$AUDIT_LOG"
|
|
exit 0
|
|
;;
|
|
|
|
compare|"")
|
|
[[ -r "$MIN_LOG" && -r "$AUDIT_LOG" ]] || die "logs not found in $LOG_DIR (start the server with --log-dir $LOG_DIR)"
|
|
|
|
rule
|
|
echo " MINIMAL LOG ($MIN_LOG)"
|
|
echo " default profile — 'just give me timestamps and tool names'"
|
|
rule
|
|
if [[ -s "$MIN_LOG" ]]; then
|
|
cat "$MIN_LOG"
|
|
else
|
|
echo "(empty — no tool calls yet)"
|
|
fi
|
|
echo
|
|
|
|
rule
|
|
echo " AUDIT LOG ($AUDIT_LOG)"
|
|
echo " structured JSON — session, client, role, outbound host, forward_auth,"
|
|
echo " target_user, record kind/id, response digest, policy decision"
|
|
rule
|
|
if [[ -s "$AUDIT_LOG" ]]; then
|
|
pretty_audit "$AUDIT_LOG"
|
|
else
|
|
echo "(empty — no tool calls yet)"
|
|
fi
|
|
echo
|
|
|
|
rule
|
|
echo " WHAT THE MINIMAL LOG CANNOT ANSWER"
|
|
rule
|
|
cat <<'EOF'
|
|
- Which URL did web_fetch hit? (internal metadata? customer API?)
|
|
- Did it forward the caller's bearer token downstream?
|
|
- Which customer record did db_lookup read?
|
|
- Who did support_override mint a token for, and with which role?
|
|
- Did env_debug leak SESSION_SIGNING_KEY or LOCAL_SUPPORT_MASTER_KEY?
|
|
- Was the request allowed or denied by policy?
|
|
- What was the size / digest of the response that left the server?
|
|
|
|
All of the above are in the audit log. None are in the minimal log.
|
|
EOF
|
|
;;
|
|
|
|
*)
|
|
die "usage: $0 [compare|clear|minimal|audit]"
|
|
;;
|
|
esac
|