Skip to content

fix(feishu): suppress stale missing-scope grant notices#31870

Merged
Takhoffman merged 1 commit intoopenclaw:mainfrom
liuxiaopai-ai:codex/feishu-ignore-stale-scope-31761
Mar 2, 2026
Merged

fix(feishu): suppress stale missing-scope grant notices#31870
Takhoffman merged 1 commit intoopenclaw:mainfrom
liuxiaopai-ai:codex/feishu-ignore-stale-scope-31761

Conversation

@liuxiaopai-ai
Copy link

Summary

Describe the problem and fix in 2–5 bullets:

  • Problem: Feishu sender-name lookup permission errors for stale scope contact:contact.base:readonly triggered repeated user-facing grant notices.
  • Why it matters: this scope is non-existent/stale and creates false permission prompts, confusing users while message handling should continue.
  • What changed: added a targeted suppressor for this stale scope token during best-effort sender-name lookup, so messages continue without injecting misleading permission notices.
  • What did NOT change (scope boundary): valid Feishu permission errors still surface as before.

Change Type (select all)

  • Bug fix
  • Feature
  • Refactor
  • Docs
  • Security hardening
  • Chore/infra

Scope (select all touched areas)

  • Gateway / orchestration
  • Skills / tool execution
  • Auth / tokens
  • Memory / storage
  • Integrations
  • API / contracts
  • UI / DX
  • CI/CD / infra

Linked Issue/PR

User-visible / Behavior Changes

  • Feishu inbound messages no longer include false permission grant prompts when the lookup error references stale scope contact:contact.base:readonly.

Security Impact (required)

  • New permissions/capabilities? (No)
  • Secrets/tokens handling changed? (No)
  • New/changed network calls? (No)
  • Command/tool execution surface changed? (No)
  • Data access scope changed? (No)
  • If any Yes, explain risk + mitigation:

Repro + Verification

Environment

  • OS: macOS
  • Runtime/container: Node local test run
  • Model/provider: N/A
  • Integration/channel (if any): Feishu inbound sender-name lookup path
  • Relevant config (redacted): Feishu app credentials + group chat event

Steps

  1. Simulate Feishu contact.user.get returning permission error code 99991672 with message containing contact:contact.base:readonly.
  2. Dispatch a Feishu group message event.
  3. Inspect finalized body used for agent dispatch.

Expected

  • Message dispatch continues.
  • No user-facing "Permission grant URL" notice is injected for stale scope errors.

Actual

  • Before fix: stale scope errors appended permission grant notice to body.
  • After fix: stale scope errors are ignored for notification purposes; regular body remains.

Evidence

Attach at least one:

  • Failing test/log before + passing after
  • Trace/log snippets
  • Screenshot/recording
  • Perf numbers (if relevant)

pnpm test extensions/feishu/src/bot.test.ts

  • Passed: 1 file, 29 tests
  • Added regression test: ignores stale non-existent contact scope permission errors

Human Verification (required)

What you personally verified (not just CI), and how:

  • Verified scenarios:
    • stale scope permission error no longer injects grant notice.
    • normal message body remains and dispatch still occurs exactly once.
    • existing Feishu bot tests remain green.
  • Edge cases checked:
    • suppression is token-based and scoped to known stale scope string.
  • What you did not verify:
    • live Feishu tenant behavior against production APIs.

Compatibility / Migration

  • Backward compatible? (Yes)
  • Config/env changes? (No)
  • Migration needed? (No)
  • If yes, exact upgrade steps:

Failure Recovery (if this breaks)

  • How to disable/revert this change quickly: revert commit 6594d461a.
  • Files/config to restore:
    • extensions/feishu/src/bot.ts
    • extensions/feishu/src/bot.test.ts
  • Known bad symptoms reviewers should watch for:
    • legitimate permission errors being over-suppressed (guarded by narrow stale-token match).

Risks and Mitigations

List only real risks for this PR. Add/remove entries as needed. If none, write None.

  • Risk: suppression pattern could hide future real errors if they reuse the same stale token text.
    • Mitigation: suppression is intentionally narrow and leaves all other permission errors unchanged.

@aisle-research-bot
Copy link

aisle-research-bot bot commented Mar 2, 2026

🔒 Aisle Security Analysis

We found 1 potential security issue(s) in this PR:

# Severity Title
1 🔵 Low Untrusted Feishu API error message logged verbatim (info leak + possible log forging)

1. 🔵 Untrusted Feishu API error message logged verbatim (info leak + possible log forging)

Property Value
Severity Low
CWE CWE-532
Location extensions/feishu/src/bot.ts:149-152

Description

In resolveFeishuSenderName, suppressed permission errors are now logged with permErr.message, which is taken directly from the Feishu API response (axiosErr.response.data.msg) without any sanitization.

This introduces two concrete risks:

  • Information disclosure (CWE-532): Feishu’s msg can include a permission grant URL and identifiers (e.g., app IDs / deployment domains / scopes). This data will be written to logs even when the code intentionally suppresses the user-facing notice.
  • Log injection / forging (CWE-117): Because msg is untrusted remote text, it may contain newlines/control characters. When runtime.log resolves to console.log (the default in several call sites), embedded newlines can create additional fake log lines and confuse downstream log parsing/alerting.

Vulnerable code:

if (shouldSuppressPermissionErrorNotice(permErr)) {
  log(`feishu: ignoring stale permission scope error: ${permErr.message}`);
  return {};
}

Data flow evidence:

  • Source: extractPermissionError() sets message: msg where msg = feishuErr.msg ?? "" from err.response.data (remote API response)
  • Sink: log(...) call interpolates permErr.message directly into output

Recommendation

Avoid logging the full remote error message, or sanitize it before logging.

Option A (preferred): log only stable/safe fields

if (shouldSuppressPermissionErrorNotice(permErr)) {
  log(`feishu: ignoring stale permission scope error: code=${permErr.code}`);
  return {};
}

Option B: sanitize + truncate before logging (if message is needed for debugging)

const sanitizeForLog = (value: string) =>
  value.replace(/[\r\n\t\0\u001b]/g, " ").slice(0, 200);

if (shouldSuppressPermissionErrorNotice(permErr)) {
  log(
    `feishu: ignoring stale permission scope error: code=${permErr.code} msg=${sanitizeForLog(permErr.message)}`,
  );
  return {};
}

Additionally consider redacting/omitting URLs in logs (e.g., replace https://... with <redacted_url>), since grant URLs and app identifiers may be sensitive in some deployments.


Analyzed PR: #31870 at commit 6594d46

Last updated on: 2026-03-02T16:17:05Z

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Mar 2, 2026

Greptile Summary

This PR adds a targeted suppressor for stale Feishu permission errors during sender name lookup. When the API returns error code 99991672 with the stale scope contact:contact.base:readonly, the error is suppressed and logged, allowing message dispatch to continue without injecting misleading permission grant prompts.

Key changes:

  • Added IGNORED_PERMISSION_SCOPE_TOKENS constant with the stale scope token
  • Implemented shouldSuppressPermissionErrorNotice() to check if permission errors should be suppressed based on message content
  • Modified resolveFeishuSenderName() to suppress errors matching stale scope tokens
  • Added comprehensive regression test verifying suppression works correctly while preserving normal message flow

Impact: Users will no longer see false permission grant prompts for the non-existent stale scope, improving the user experience while maintaining proper error handling for legitimate permission issues.

Confidence Score: 5/5

  • This PR is safe to merge with minimal risk
  • The change is a simple, well-tested bug fix with narrow scope. The suppression logic uses case-insensitive substring matching on a specific known stale scope token, includes proper logging, maintains backward compatibility for valid errors, and has comprehensive test coverage verifying the expected behavior.
  • No files require special attention

Last reviewed commit: 6594d46

@Takhoffman Takhoffman force-pushed the codex/feishu-ignore-stale-scope-31761 branch from 6594d46 to fe06b78 Compare March 2, 2026 23:33
@Takhoffman Takhoffman merged commit 55f0463 into openclaw:main Mar 2, 2026
9 checks passed
@Takhoffman
Copy link
Contributor

PR #31870 - fix(feishu): suppress stale missing-scope grant notices (#31870)

Merged after verification.

  • Merge commit: 55f0463
  • Verified: pnpm install --frozen-lockfile, pnpm build, pnpm check (with unrelated baseline lint failure in src/browser/chrome.ts)
  • Autoland updates:
    M\tCHANGELOG.md
    M\textensions/feishu/src/bot.test.ts
    M\textensions/feishu/src/bot.ts
  • Rationale:
    Rebased onto latest main and preserved stale-scope suppression behavior for sender-name lookup permission errors to reduce repeated false grant notices.
  • Changelog: CHANGELOG.md updated=true required=true opt_out=false

dawi369 pushed a commit to dawi369/davis that referenced this pull request Mar 3, 2026
…) thanks @liuxiaopai-ai

Verified:
- pnpm install --frozen-lockfile
- pnpm build
- pnpm check (fails on unrelated baseline lint in src/browser/chrome.ts)

Co-authored-by: liuxiaopai-ai <73659136+liuxiaopai-ai@users.noreply.github.com>
Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
OWALabuy pushed a commit to kcinzgg/openclaw that referenced this pull request Mar 4, 2026
…) thanks @liuxiaopai-ai

Verified:
- pnpm install --frozen-lockfile
- pnpm build
- pnpm check (fails on unrelated baseline lint in src/browser/chrome.ts)

Co-authored-by: liuxiaopai-ai <73659136+liuxiaopai-ai@users.noreply.github.com>
Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
zooqueen pushed a commit to hanzoai/bot that referenced this pull request Mar 6, 2026
…) thanks @liuxiaopai-ai

Verified:
- pnpm install --frozen-lockfile
- pnpm build
- pnpm check (fails on unrelated baseline lint in src/browser/chrome.ts)

Co-authored-by: liuxiaopai-ai <73659136+liuxiaopai-ai@users.noreply.github.com>
Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

channel: feishu Channel integration: feishu size: S

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feishu plugin checks non-existent scope contact:contact.base:readonly

2 participants