openclaw - 💡(How to fix) Fix Bug: QQBot plugin token/API requests blocked by SSRF guard in fake-IP proxy environments (Surge/Clash) [1 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
openclaw/openclaw#70310Fetched 2026-04-23 07:26:28
View on GitHub
Comments
0
Participants
1
Timeline
0
Reactions
0
Participants

Error Message

Error Log

[qqbot] [qqbot:default] Connection failed: Network error getting access_token: Blocked: resolves to private/internal/special-use IP address

Root Cause

In extensions/qqbot/api-*.js, the fetchWithSsrFGuard calls for token fetching and API requests are missing the ssrfPolicy parameter:

Fix Action

Workaround

Patching api-*.js to add ssrfPolicy to the two fetchWithSsrFGuard calls:

const guarded = await fetchWithSsrFGuard({
    url: TOKEN_URL,
    init: { ... },
    auditContext: "qqbot.token",
    policy: {
        hostnameAllowlist: ["*.qq.com"],
        allowRfc2544BenchmarkRange: true
    }
});

This works but will be overwritten on upgrade.

Code Example

[security] blocked URL fetch (qqbot.token) target=https://bots.qq.com/app/getAppAccessToken reason=Blocked: resolves to private/internal/special-use IP address
[qqbot] [qqbot:default] Connection failed: Network error getting access_token: Blocked: resolves to private/internal/special-use IP address

---

const guarded = await fetchWithSsrFGuard({
    url: TOKEN_URL,
    init: { method: "POST", headers, body },
    auditContext: "qqbot.token"
    // ❌ Missing: ssrfPolicy
});

---

const guarded = await fetchWithSsrFGuard({
    url,
    init: options,
    auditContext: `qqbot.api${path}`
    // ❌ Missing: ssrfPolicy
});

---

const QQBOT_MEDIA_SSRF_POLICY = {
    hostnameAllowlist: [
        "*.qpic.cn", "*.qq.com", "*.weiyun.com", "*.qq.com.cn",
        "*.ugcimg.cn", "*.myqcloud.com", "*.tencentcos.cn", "*.tencentcos.com"
    ],
    allowRfc2544BenchmarkRange: true  // ✅ Correctly handles fake-IP proxies
};

---

const guarded = await fetchWithSsrFGuard({
    url: TOKEN_URL,
    init: { ... },
    auditContext: "qqbot.token",
    policy: {
        hostnameAllowlist: ["*.qq.com"],
        allowRfc2544BenchmarkRange: true
    }
});
RAW_BUFFERClick to expand / collapse

Bug Description

QQBot plugin fails to obtain access tokens and make API requests when running behind a fake-IP proxy (e.g., Surge, Clash). The SSRF guard blocks requests because DNS resolves to the RFC 2544 benchmark range (198.18.0.0/15) used by fake-IP proxies.

Error Log

[security] blocked URL fetch (qqbot.token) target=https://bots.qq.com/app/getAppAccessToken reason=Blocked: resolves to private/internal/special-use IP address
[qqbot] [qqbot:default] Connection failed: Network error getting access_token: Blocked: resolves to private/internal/special-use IP address

This repeats every ~30s for all QQBot instances.

Root Cause

In extensions/qqbot/api-*.js, the fetchWithSsrFGuard calls for token fetching and API requests are missing the ssrfPolicy parameter:

Token request (doFetchToken):

const guarded = await fetchWithSsrFGuard({
    url: TOKEN_URL,
    init: { method: "POST", headers, body },
    auditContext: "qqbot.token"
    // ❌ Missing: ssrfPolicy
});

API request (apiRequest):

const guarded = await fetchWithSsrFGuard({
    url,
    init: options,
    auditContext: `qqbot.api${path}`
    // ❌ Missing: ssrfPolicy
});

Meanwhile, the media download path correctly includes SSRF policy with allowRfc2544BenchmarkRange: true:

const QQBOT_MEDIA_SSRF_POLICY = {
    hostnameAllowlist: [
        "*.qpic.cn", "*.qq.com", "*.weiyun.com", "*.qq.com.cn",
        "*.ugcimg.cn", "*.myqcloud.com", "*.tencentcos.cn", "*.tencentcos.com"
    ],
    allowRfc2544BenchmarkRange: true  // ✅ Correctly handles fake-IP proxies
};

Environment

  • macOS with Surge proxy (fake-ip mode)
  • dns.lookup("bots.qq.com") returns 198.18.35.155 (fake-IP)
  • dns.resolve4("bots.qq.com") returns 183.47.104.95 (real IP)
  • OpenClaw v2026.4.21

Workaround

Patching api-*.js to add ssrfPolicy to the two fetchWithSsrFGuard calls:

const guarded = await fetchWithSsrFGuard({
    url: TOKEN_URL,
    init: { ... },
    auditContext: "qqbot.token",
    policy: {
        hostnameAllowlist: ["*.qq.com"],
        allowRfc2544BenchmarkRange: true
    }
});

This works but will be overwritten on upgrade.

Expected Fix

Apply the same QQBOT_MEDIA_SSRF_POLICY (or a similar policy) to token and API requests in the QQBot plugin, since all QQBot API endpoints are under *.qq.com and need the same fake-IP proxy compatibility that media downloads already have.

Related

The Telegram plugin already handles this scenario via dangerouslyAllowPrivateNetwork. The QQBot plugin should have equivalent support for fake-IP proxy environments.

extent analysis

TL;DR

  • Add the ssrfPolicy parameter to fetchWithSsrFGuard calls in api-*.js to allow requests to pass through the SSRF guard when using a fake-IP proxy.

Guidance

  • Identify the fetchWithSsrFGuard calls in api-*.js that are missing the ssrfPolicy parameter and add it to allow requests to *.qq.com and enable allowRfc2544BenchmarkRange.
  • Verify that the ssrfPolicy is correctly applied by checking the request logs for successful requests to bots.qq.com.
  • Consider applying the same QQBOT_MEDIA_SSRF_POLICY to token and API requests in the QQBot plugin for consistency and to ensure fake-IP proxy compatibility.
  • Test the workaround by running the QQBot plugin behind a fake-IP proxy and verifying that access tokens are obtained and API requests are successful.

Example

const guarded = await fetchWithSsrFGuard({
    url: TOKEN_URL,
    init: { method: "POST", headers, body },
    auditContext: "qqbot.token",
    ssrfPolicy: {
        hostnameAllowlist: ["*.qq.com"],
        allowRfc2544BenchmarkRange: true
    }
});

Notes

  • The provided workaround will be overwritten on upgrade, so a permanent fix should be applied to the QQBot plugin.
  • The Telegram plugin's dangerouslyAllowPrivateNetwork setting may serve as a reference for implementing equivalent support in the QQBot plugin.

Recommendation

  • Apply the workaround by adding the ssrfPolicy parameter to fetchWithSsrFGuard calls in api-*.js to allow requests to pass through the SSRF guard when using a fake-IP proxy, as this provides a temporary solution until a permanent fix is implemented.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

openclaw - 💡(How to fix) Fix Bug: QQBot plugin token/API requests blocked by SSRF guard in fake-IP proxy environments (Surge/Clash) [1 participants]