#!/usr/bin/env bash
# output-exfiltration-scanner.sh -- PostToolUse hook
#
# Detects potential data exfiltration attempts in tool outputs:
#   - Encoded data (base64 blobs, hex dumps)
#   - Large data volumes in responses
#   - Sensitive patterns in outputs (credentials, tokens)
#   - Suspicious URL patterns in outputs
#
# T-048: Output exfiltration scanning.
#
# @connexum/ai-governance

set -euo pipefail

# Source shared utilities if available
HOOK_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
if [[ -f "$HOOK_DIR/hook-utils.sh" ]]; then
  source "$HOOK_DIR/hook-utils.sh"
fi

# Read input from stdin
INPUT="$(cat)"

# Extract tool name and output
TOOL_NAME=""
TOOL_OUTPUT=""

if command -v jq &>/dev/null; then
  TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name // empty' 2>/dev/null || true)
  # F-NEW-CRIT-37: Claude Code's PostToolUse payload uses .tool_response, NOT
  # .tool_output. Read .tool_response first, falling back to common subfields
  # (.content, .stdout) and to JSON-stringify when .tool_response is an object
  # without those fields. Preserve legacy .tool_output / .output for any caller
  # still using them.
  TOOL_OUTPUT=$(echo "$INPUT" | jq -r '
    (.tool_response // null) as $tr |
    if $tr == null then (.tool_output // .output // empty)
    elif ($tr | type) == "string" then $tr
    elif ($tr | type) == "object" then ($tr.content // $tr.stdout // ($tr | tojson))
    else (.tool_output // .output // empty)
    end
  ' 2>/dev/null || true)
fi

# Skip if no output to scan
if [[ -z "$TOOL_OUTPUT" ]]; then
  exit 0
fi

# --- Exfiltration Detection ---

VIOLATIONS=()

# 1. Large base64 blobs (>500 chars of continuous base64)
if echo "$TOOL_OUTPUT" | grep -qE '[A-Za-z0-9+/]{500,}={0,2}'; then
  VIOLATIONS+=("Large base64 blob detected in output (potential encoded data exfiltration)")
fi

# 2. Long hex dumps (>200 chars of continuous hex)
if echo "$TOOL_OUTPUT" | grep -qE '([0-9a-fA-F]{2}\s?){100,}'; then
  VIOLATIONS+=("Large hex dump in output (potential binary data exfiltration)")
fi

# 3. Credential patterns in output
if echo "$TOOL_OUTPUT" | grep -qEi '(api[_-]?key|secret[_-]?key|access[_-]?token|bearer|authorization)[[:space:]]*[:=][[:space:]]*[A-Za-z0-9+/_.=-]{20,}'; then
  VIOLATIONS+=("Credential/token pattern detected in output")
fi

# 4. AWS-style keys in output
if echo "$TOOL_OUTPUT" | grep -qE 'AKIA[0-9A-Z]{16}'; then
  VIOLATIONS+=("AWS access key detected in output")
fi

# 5. Private key material
if echo "$TOOL_OUTPUT" | grep -qE -e '-----BEGIN (RSA |EC |DSA |OPENSSH )?PRIVATE KEY-----'; then
  VIOLATIONS+=("Private key material detected in output")
fi

# 6. Connection strings with credentials
if echo "$TOOL_OUTPUT" | grep -qEi '(postgres|mysql|mongodb|redis)://[^:]+:[^@]+@'; then
  VIOLATIONS+=("Database connection string with credentials in output")
fi

# 7. JWT tokens (three base64 segments separated by dots)
if echo "$TOOL_OUTPUT" | grep -qE 'eyJ[A-Za-z0-9_-]{10,}\.eyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}'; then
  VIOLATIONS+=("JWT token detected in output")
fi

# --- Report Violations ---

LOG_DIR="${GOVERNANCE_LOG_DIR:-/tmp/governance/logs}"
mkdir -p "$LOG_DIR"
LOG_FILE="$LOG_DIR/exfiltration-scan.jsonl"

if [[ ${#VIOLATIONS[@]} -gt 0 ]]; then
  TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%SZ")

  for violation in "${VIOLATIONS[@]}"; do
    # Log the violation
    echo "{\"timestamp\":\"$TIMESTAMP\",\"tool\":\"$TOOL_NAME\",\"violation\":\"$violation\",\"action\":\"WARN\"}" >> "$LOG_FILE"

    # Write warning to stderr (visible to operator)
    echo "⚠ EXFILTRATION WARNING: $violation (tool: $TOOL_NAME)" >&2
  done

  # We WARN but don't block -- PostToolUse can't prevent output
  # that's already been generated. The warning creates an audit trail.
  exit 0
fi

exit 0
