#!/usr/bin/env bash # Drives real security-boundary tests for Episode 21 ("Security Model"). # Requires the local MuseHub dev stack running. set -euo pipefail HUB="https://localhost:1337" REPO_ID="sha256:6a9b70085b05951c452133f4c499dde446e80689b5578a60d96660e988d73f2a" ENC_REPO=$(python3 -c "import urllib.parse; print(urllib.parse.quote('$REPO_ID', safe=''))") echo "=== Part 1: security headers, on a real live response ===" curl -sk -D - -o /dev/null "$HUB/gabriel/wire-episode17" | grep -iE "x-frame|x-content-type|strict-transport|content-security" echo echo "=== Part 2: SSRF protection -- webhook targeting the AWS metadata endpoint ===" echo "--- http scheme (blocked at the scheme layer) ---" BODY1='{"url":"http://169.254.169.254/latest/meta-data/","events":["push"]}' printf '%s' "$BODY1" > /tmp/ep21_ssrf1.json HEADER=$(muse sign header --method POST --path "/api/repos/$ENC_REPO/webhooks" --hub "$HUB" --body-file /tmp/ep21_ssrf1.json --json | python3 -c "import json,sys; print(json.load(sys.stdin)['header_value'])") curl -sk -X POST "$HUB/api/repos/$ENC_REPO/webhooks" -H "Authorization: $HEADER" -H "Content-Type: application/json" --data-binary @/tmp/ep21_ssrf1.json echo echo "--- https scheme (blocked at the IP-range layer) ---" BODY2='{"url":"https://169.254.169.254/latest/meta-data/","events":["push"]}' printf '%s' "$BODY2" > /tmp/ep21_ssrf2.json HEADER=$(muse sign header --method POST --path "/api/repos/$ENC_REPO/webhooks" --hub "$HUB" --body-file /tmp/ep21_ssrf2.json --json | python3 -c "import json,sys; print(json.load(sys.stdin)['header_value'])") curl -sk -X POST "$HUB/api/repos/$ENC_REPO/webhooks" -H "Authorization: $HEADER" -H "Content-Type: application/json" --data-binary @/tmp/ep21_ssrf2.json echo echo "=== Part 3: mist filename validation -- path traversal, separators, null bytes ===" python3 - <<'PY' import sys sys.path.insert(0, "/Users/gabriel/ecosystem/muse") from muse.plugins.mist.plugin import validate_mist_filename for name in ["validate_assignee.py", "../../../etc/passwd", "a/b.py", "a\x00b.py"]: try: validate_mist_filename(name) print(f"{name!r}: ACCEPTED") except Exception as e: print(f"{name!r}: REJECTED -- {type(e).__name__}: {e}") PY echo echo "=== Part 4: MSign replay -- the real, known, already-tracked gap ===" BODY3='{"title":"Replay test issue","body":"testing MSign replay behavior"}' printf '%s' "$BODY3" > /tmp/ep21_replay.json HEADER=$(muse sign header --method POST --path "/api/repos/$ENC_REPO/issues" --hub "$HUB" --body-file /tmp/ep21_replay.json --json | python3 -c "import json,sys; print(json.load(sys.stdin)['header_value'])") echo "signed header (will be reused verbatim): $HEADER" echo "--- request 1 ---" curl -sk -X POST "$HUB/api/repos/$ENC_REPO/issues" -H "Authorization: $HEADER" -H "Content-Type: application/json" --data-binary @/tmp/ep21_replay.json | python3 -c "import json,sys; d=json.load(sys.stdin); print('issue #', d['number'], d['issueId'])" echo "--- request 2: exact replay, same header, same body, same timestamp ---" curl -sk -X POST "$HUB/api/repos/$ENC_REPO/issues" -H "Authorization: $HEADER" -H "Content-Type: application/json" --data-binary @/tmp/ep21_replay.json | python3 -c "import json,sys; d=json.load(sys.stdin); print('issue #', d['number'], d['issueId'])" echo echo "=== Part 5: this exact finding is already known and tracked ===" muse -C ~/ecosystem/musehub hub issue read 178 --hub https://staging.musehub.ai --json | python3 -c " import json, sys d = json.load(sys.stdin) print('#' + str(d['number']), '--', d['title']) print('state:', d['state']) " rm -f /tmp/ep21_ssrf1.json /tmp/ep21_ssrf2.json /tmp/ep21_replay.json echo echo "Demo complete."