Closes#392 (uncontroversial part).
WeChat (`_handle_message`) and Feishu (`_handle_event`) gated their
signature/decryption checks behind a condition the REQUEST controls:
- WeChat: `if encrypt and self._crypto:` -- a POST with no `<Encrypt>`
element took the false branch and reached `_safe_process_message`
without any verification, even when `encoding_aes_key` + `token` were
configured.
- Feishu: `if self.config.encrypt_key and "encrypt" in body:` -- a
plaintext body skipped decryption entirely and was processed directly.
Since the webhook port is the channel's only inbound boundary, an
attacker could POST forged plaintext and reach the agent, spoofing
`sender_id` / `FromUserName` (and, with an empty allowlist, passing the
sender gate).
Fix: when encryption is configured, an inbound POST MUST carry the
encrypted field (`<Encrypt>` / `encrypt`) -- otherwise it is rejected
with 403 and never reaches the agent. Plaintext mode (no encryption
configured) is unchanged, so existing plaintext deployments are not
affected. The remaining fail-closed question (what to do when
credentials are entirely unset) is left for the maintainers to decide
as the policy part of the issue.
Regression tests (9 new):
- WeChat: plaintext rejected / missing Encrypt rejected / bad signature
rejected / valid signature decrypts and processes / plaintext still
accepted when no crypto.
- Feishu: plaintext rejected / non-dict body rejected / encrypted body
decrypts and processes / plaintext still accepted when no encrypt_key.
93 tests in the two channel files pass; full suite 3045 passed, 13
skipped; ruff clean.
Co-authored-by: Xi Zhang <106144707+X-iZhang@users.noreply.github.com>
- Fix RUF006: Implement background task tracking in Discord, iMessage, WeChat, and TUI to prevent premature GC of fire-and-forget tasks.
- Fix B904: Add explicit exception chaining (raise ... from) across all exception handlers.
- Fix RUF012: Annotate mutable class attributes with ClassVar for command arguments and media maps.
- Fix B008: Refactor Typer commands in cli/commands.py to use Annotated for argument and option defaults.
- Fix B023/B018: Resolve late-binding issues in lambdas and remove useless expressions.
- Fix syntax errors in retry.py docstrings and models.py lambda parameter ordering.
- Added blank lines for better separation of test cases in multiple test files.
- Reformatted event handling in tests for clarity and consistency.
- Ensured consistent use of multi-line formatting for dictionary arguments in event handling.
- Improved assertions and test descriptions for better understanding.
- Updated test cases across various modules including test_stream_state, test_stream_utils, test_summarization, test_thread_selector, test_tool_error_handler, test_tui_widgets, test_ui_runtime, and test_wechat_channel.