Skip to content

🔐 Missing Webhook Signature Verification (Security) #6

Description

@IvyGain

Description

The webhook endpoint (/webhook/event) does not verify the request signature from Lark, making it vulnerable to spoofed requests.

Problem

In remote_server.py lines 431-449, the webhook handler processes all incoming requests without verifying they actually came from Lark:

@app.post("/webhook/event")
async def webhook_event(request: Request):
    # ...
    body = await request.json()
    logger.info(f"Webhook received: {json.dumps(body, ensure_ascii=False)[:100]}...")
    
    # URL検証(初回設定時)
    if body.get("type") == "url_verification":
        challenge = body.get("challenge", "")
        return JSONResponse(content={"challenge": challenge})
    
    # ❌ No signature verification before processing events!

Security Risk

Without signature verification, anyone can send fake webhook requests to trigger bot actions or extract information.

Solution

  1. Store the Verification Token and Encrypt Key from Lark Open Platform console
  2. Verify the signature in the webhook handler:
import hashlib
import hmac

def verify_signature(timestamp: str, nonce: str, body: str, signature: str, encrypt_key: str) -> bool:
    """Verify Lark webhook signature."""
    concat = timestamp + nonce + encrypt_key + body
    expected = hashlib.sha256(concat.encode()).hexdigest()
    return hmac.compare_digest(expected, signature)

@app.post("/webhook/event")
async def webhook_event(request: Request):
    # Get headers
    timestamp = request.headers.get("X-Lark-Request-Timestamp", "")
    nonce = request.headers.get("X-Lark-Request-Nonce", "")
    signature = request.headers.get("X-Lark-Signature", "")
    
    body_bytes = await request.body()
    body_str = body_bytes.decode()
    
    if not verify_signature(timestamp, nonce, body_str, signature, ENCRYPT_KEY):
        raise HTTPException(status_code=403, detail="Invalid signature")
    
    # Continue processing...

References

Priority

HIGH - Security vulnerability

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions