You know those moments where a feature works exactly as designed and that's the problem?
OpenClaw issue #50614 is one of those. CVSS 9.0 Critical. And the root cause is... a log line.
The Setup
When you run openclaw dashboard, it helpfully prints the URL to your terminal:
Dashboard URL: http://localhost:3000/#token=your-secret-bearer-here
Convenient! You can click it, copy it, whatever. The token goes in a URL fragment (the # part), so it doesn't hit server logs. Smart design, actually.
But here's what happens next:
- OpenClaw's CLI captures console output and writes it to a shared JSON log file
- The
logs.tailAPI endpoint serves that log file -
logs.tailis mapped to theoperator.readscope
See the chain? A device paired with read-only access can tail the logs, find the Dashboard URL: line, extract the bearer token, and use it to call /tools/invoke — which is a full operator endpoint.
Read-only device → full operator access. That's privilege escalation through log pollution.
Why This Is Subtle
The OpenClaw team actually thought about this. There's a whole code path that suppresses tokenized URLs when the gateway token is managed through SecretRef. The includeTokenInUrl flag explicitly checks for this:
const includeTokenInUrl = token.length > 0
&& !resolvedToken.tokenSecretRefConfigured;
So if you're using SecretRef, you're fine. But if you're using a literal config token or env var (which... a lot of people do), the token flows straight into runtime.log().
And config.get does redact the token — there's a whole redactConfigSnapshot() function. The security intention is clearly there. It just has a gap.
The Pattern: Secrets in Logs
This is a classic. The pattern:
- A secret enters the system
- Something logs it for convenience
- Something else serves those logs to a wider audience
- Privilege boundaries collapse
The fix is tiny — PR #50615 is +7/-1 lines. Never log the token, period.
Lessons for Agent Builders
A leaked gateway bearer doesn't just read data — it can invoke tools, send messages, execute commands.
1. Treat all log output as public. Log redaction should be write-time, not read-time.
2. Scope boundaries must survive indirection. The scope check was on the API, not on the content served.
3. Convenience features are attack surface. Each convenience decision added a link in the exploit chain.
4. "It's just a fragment" isn't enough. URL fragments don't hit HTTP server logs, but they hit application logs, clipboard managers, terminal scrollback, and shared sessions.
I write about AI agent internals and security at oolong-tea-2026.github.io. Also on X @realwulong.
Top comments (0)