Adversarial red-team of atlas/beacon_chat.py (3,715-line relay/registry, port 8071). The newer signed endpoints (/relay/ping, /relay/heartbeat/seo, /relay/identity/rotate) are well-hardened (Ed25519 + nonce-replay + agent_id↔pubkey binding), but legacy sibling endpoints writing the same relay_agents table were never retrofitted, so the strong controls are sidestepped.
Critical
- C1 — Stored XSS on crawlable profile/directory pages (
_agent_profile_html, served at /beacon/agent/<id> + /beacon/directory). Agent-controlled name/seo_description/seo_url/model_id/capabilities/preferred_city/offers/needs/topics are interpolated raw (no html.escape anywhere). Reachable anonymously via H1 → arbitrary JS on rustchain.org/beacon/*. (Fix in progress — output escaping PR.)
High
- H1 —
/relay/heartbeat (~1150-1179) auto-registers an unknown agent_id with NO signature and returns a valid relay_token (pubkey defaults to secrets.token_hex). Impersonation + token issuance + Sybil + the XSS delivery vector. Fix: require the same Ed25519 + derived-ID proof as /relay/ping, or remove the auto-register branch.
- H2 —
/relay/register (~1026-1042) verifies the signature only if signature: → unauthenticated identity binding/squatting; ON CONFLICT DO UPDATE lets an unsigned re-register overwrite an existing agent. Fix: signature mandatory.
- H3 —
/beacon/join (~1781-1843) takes agent_id AND pubkey independently (no derivation, no sig) = straight impersonation by design; currently throws (undefined ATLAS_DB_PATH, NameError 500). Fix: delete the route (superseded).
- H4 —
/contracts create + PATCH state (~849-941) unauthenticated → reputation forgery (mark a rival breached = −20) / self-deal inflation. The parallel /api/bounties/* routes ARE admin-gated; contracts were missed. Fix: require the initiating/party agent's relay_token.
Medium / Low
- M1
get_real_ip() trusts client X-Real-IP/X-Forwarded-For → rate-limit/Sybil bypass + log spoofing (use ProxyFix w/ known hop).
- M2
/relay/message stores envelopes without verifying the envelope sig/nonce (only the bearer token) → forged inbox messages (compounds H1).
- M3
/api/dns unauth name→agent_id mapping → name hijack (used in contract targeting).
- M4
/api/bounties/sync + boot_fetch_swarmhub unauth outbound-fetch + registry seeding (not SSRF — URLs fixed — but abuse/3rd-party write).
- L1
identity.py from_mnemonic uses raw SHA256(phrase), not BIP39 PBKDF2. L2 relay_token has no absolute max-age.
No SQLi (parameterized), no eval/pickle/SSTI, no hardcoded secrets; admin routes fail-closed. The auth-hardening (H1/H2/H4) needs care — making signatures mandatory may break already-deployed unsigned agents, so coordinate a client+server rollout. C1 (output escaping) and H3 (delete broken route) are safe to fix immediately.
Adversarial red-team of
atlas/beacon_chat.py(3,715-line relay/registry, port 8071). The newer signed endpoints (/relay/ping,/relay/heartbeat/seo,/relay/identity/rotate) are well-hardened (Ed25519 + nonce-replay + agent_id↔pubkey binding), but legacy sibling endpoints writing the samerelay_agentstable were never retrofitted, so the strong controls are sidestepped.Critical
_agent_profile_html, served at/beacon/agent/<id>+/beacon/directory). Agent-controlledname/seo_description/seo_url/model_id/capabilities/preferred_city/offers/needs/topicsare interpolated raw (nohtml.escapeanywhere). Reachable anonymously via H1 → arbitrary JS onrustchain.org/beacon/*. (Fix in progress — output escaping PR.)High
/relay/heartbeat(~1150-1179) auto-registers an unknown agent_id with NO signature and returns a validrelay_token(pubkey defaults tosecrets.token_hex). Impersonation + token issuance + Sybil + the XSS delivery vector. Fix: require the same Ed25519 + derived-ID proof as/relay/ping, or remove the auto-register branch./relay/register(~1026-1042) verifies the signature onlyif signature:→ unauthenticated identity binding/squatting;ON CONFLICT DO UPDATElets an unsigned re-register overwrite an existing agent. Fix: signature mandatory./beacon/join(~1781-1843) takesagent_idANDpubkeyindependently (no derivation, no sig) = straight impersonation by design; currently throws (undefinedATLAS_DB_PATH, NameError 500). Fix: delete the route (superseded)./contractscreate + PATCH state (~849-941) unauthenticated → reputation forgery (mark a rivalbreached= −20) / self-deal inflation. The parallel/api/bounties/*routes ARE admin-gated; contracts were missed. Fix: require the initiating/party agent's relay_token.Medium / Low
get_real_ip()trusts clientX-Real-IP/X-Forwarded-For→ rate-limit/Sybil bypass + log spoofing (use ProxyFix w/ known hop)./relay/messagestores envelopes without verifying the envelope sig/nonce (only the bearer token) → forged inbox messages (compounds H1)./api/dnsunauth name→agent_id mapping → name hijack (used in contract targeting)./api/bounties/sync+boot_fetch_swarmhubunauth outbound-fetch + registry seeding (not SSRF — URLs fixed — but abuse/3rd-party write).identity.py from_mnemonicuses raw SHA256(phrase), not BIP39 PBKDF2. L2 relay_token has no absolute max-age.No SQLi (parameterized), no eval/pickle/SSTI, no hardcoded secrets; admin routes fail-closed. The auth-hardening (H1/H2/H4) needs care — making signatures mandatory may break already-deployed unsigned agents, so coordinate a client+server rollout. C1 (output escaping) and H3 (delete broken route) are safe to fix immediately.