Skip to content

security(tools): enforce cloud-metadata SSRF floor in browser hybrid routing (Hermes v0.13 parity) #298

@subinium

Description

@subinium

Background

Hermes v0.13 (#21228, closes #16234) — the browser tool's hybrid routing (mix of local fetch + remote rendering) could be coerced into hitting
cloud-metadata endpoints (169.254.169.254 / fd00:ec2::254 / metadata.google.internal) because the SSRF floor was only enforced on the legacy
fetch path, not the new browser-rendering path.

Current state in CrowClaw

Scope

  • Modified: packages/tools/src/ssrf-blocklist.ts (or wherever the central blocklist lives)
  • New constant: CLOUD_METADATA_HOSTS = ['169.254.169.254', 'fd00:ec2::254', 'metadata.google.internal', 'metadata.azure.com', '100.100.100.200']
  • Apply at: every outbound HTTP from tools/* (fetch, browser, vision, image)

Implementation sketch

  1. Centralize SSRF preflight into a single assertSafeUrl(url, { kind }) helper
  2. kind: 'browser' / 'fetch' / 'vision' / 'image' all hit the same blocklist + DNS resolution check
  3. Cloud-metadata hosts return immediately with SsrfDenied error envelope; audit-log records the attempt
  4. Add tests/cloud-metadata-floor.test.ts covering all four kinds

Acceptance criteria

  • All cloud-metadata hostnames return SsrfDenied regardless of tool kind
  • IPv6 link-local / cloud-metadata addresses (fd00:ec2::254, fe80::/10) blocked
  • DNS-aware: assertSafeUrl('http://attacker.example.com') where DNS resolves to 169.254.169.254 is blocked post-resolution
  • Audit event security:ssrf_denied carries host, resolvedIp, kind

Effort

M — touches multiple tool entry points; centralization is worth it.

Effect

Blocks the canonical cloud-credential exfiltration path. Even without a browser tool today, file this so future browser/headless work inherits
the floor — Hermes shipped it preemptively for the same reason.

Source

Hermes #21228, #16234 · CrowClaw current: packages/tools/src/index.ts (WORKSPACE_FETCH_BLOCKLIST), packages/tools/src/vision.ts

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingpriority/criticalCritical — fix before next releasesecuritySecurity findingsource/hermesPattern from NousResearch/hermes-agent

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions