larksuite / larksuite/channel-sdk-python

webhook: case-sensitive signature-header lookup 500s behind ASGI; strict encrypted pre-verify deadlocks url_verification handshake

Open
#12 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
16
Forks
8
Avg merge
3d 12h
Merged PRs (30d)
2

Description

Two concrete webhook bugs observed on 1.2.0 behind ASGI servers

Related to #11 but these are straight bugs rather than hardening gaps, so filing separately.

1. _verify_sign header lookup is case-sensitive → TypeError/500 behind ASGI

Starlette/FastAPI (per the ASGI spec) hand the application lowercase header names. _verify_sign looks up X-Lark-Request-Timestamp / X-Lark-Request-Nonce / X-Lark-Signature case-sensitively, gets None, and then None + None + encrypt_key raises TypeError: unsupported operand type(s) for +: 'NoneType' and 'NoneType' → every legitimately signed request 500s.

Reproduced with the real SDK (no mocks) in our test suite: passing lowercase headers reproduces the 500; re-canonicalizing the three header names before calling the SDK makes the same request pass. Suggested fix: case-insensitive header lookup (e.g. normalize to lower on both sides).

2. strict-mode encrypted pre-verification rejects Feishu's own url_verification handshake

The "save request URL" challenge that the Feishu console sends during first-time webhook configuration is not signed (platform behavior). With an encrypt key configured, the strict-mode encrypted pre-verification rejects the encrypted-but-unsigned handshake before the url_verification branch is reached — so an integrator using strict mode + encryption can never complete the console's URL-verification step. First-time webhook setup deadlocks.

Our workaround is to detect the handshake (plaintext and encrypted forms, both the legacy flat body and the v2/p2 schema), validate verification_token, and answer the challenge ourselves without forwarding it to the SDK. Suggested fix: exempt url_verification from the signature requirement (it carries the verification token as its own proof), or provide a documented hook for it.

Both behaviors reproduced on lark-channel-sdk==1.2.0; happy to share the test cases.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Locate _verify_sign and the url_verification branch, then reproduce the reported cases in the test suite with lowercase headers and encrypted, unsigned handshake payloads. Done means legitimately signed ASGI requests no longer 500 and plaintext or encrypted url_verification requests validate their token and complete the challenge.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
api, backend
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
58/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.