T09 · Insecure Skill Coding Practices
Error
- Location
- tracker_core.py:169
- Finding
- Webhook callbacks are accepted without valid signatures by default<![CDATA[ ## Vulnerability Details **File Location**: `tracker_core.py:169-174, 428-458`; `index.ts:42, 64, 173-206`; `README.md:61, 103-106` **Vulnerability Type**: Fail-open webhook authentication **Risk Level**: High ### Vulnerable Code ```python sig = raw.get("sign") or raw.get("signature") or raw.get("saltSign") if not sig: # If kuaidi100 didn't include sign, accept (token-in-path still gates ingress) return True, "no_signature_in_payload" ``` ```python ok, reason = _verify_push_signature(push_data) # Fail-closed option: require signature to be present and valid. # We treat "no_signature_in_payload" as failure in strict mode. if KUAIDI100_SIGNATURE_MODE == "strict" and (not ok or reason.startswith("no_signature")): return { "error": "signature_invalid", "signature_verified": bool(ok), "signature_reason": reason, } parsed = parse_push_payload(push_data) if not parsed: return {"error": "could_not_parse_push", "raw": push_data} parsed["signature_verified"] = bool(ok) parsed["signature_reason"] = reason number = parsed["number"] state = load_state() existing = state["packages"].get(number, {}) parsed["note"] = existing.get("note", "") parsed["subscribed"] = existing.get("subscribed", True) state["packages"][number] = parsed save_state(state) if parsed["today_delivery"] and not parsed["is_completed"]: cal_result = _do_sync_calendar(state) ``` ```typescript KUAIDI100_SIGNATURE_MODE: (webhook.signatureMode || "soft").trim(), ``` ### Technical Analysis Webhook authenticity verification is fail-open under the default `soft` signature mode. `_verify_push_signature` explicitly treats a missing signature as successful, while invalid signatures are only rejected when the administrator has selected `strict` mode. Consequently, callback data can proceed to parsing, persistent state replacement, and automatic Google Calendar synchronization even when its origin has not been cryptographically authentica ...[truncated 1972 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Change the default signature mode from `soft` to `strict`. 2. Reject every callback with a missing or invalid signature before parsing, persistence, or Calendar synchronization. 3. Require a non-empty, cryptographically random webhook token before registering a publicly reachable route. 4. Validate configuration at startup and refuse webhook activation if neither strict signature verification nor another strong authentication mechanism is available. 5. Return an appropriate `401` or `403` response for authentication failures rather than always acknowledging the callback as successful. 6. Use a dedicated callback salt rather than silently falling back to the path token. 7. Document secret rotation procedures and recommend high-entropy tokens. 8. Add tests covering missing signatures, malformed signatures, invalid salts, empty tokens, and unauthorized attempts to trigger Calendar synchronization. ]]>
