-
-
Notifications
You must be signed in to change notification settings - Fork 57k
Description
Summary
The LINE webhook handlers return HTTP 200 before event processing finishes, then catch processing errors and only log them. This causes irreversible message loss because LINE sees success and does not retry failed deliveries. The pattern exists in two independent code paths.
Executive Risk Snapshot
- CVSS v3.1: 8.2 (High)
- CVSS v4.0: 8.8 (High)
- Primary risk: The LINE webhook handlers return HTTP 200 before event processing finishes, then catch processing errors and only log them.
Technical Analysis
Root cause: The LINE webhook handlers return HTTP 200 before event processing finishes, then catch processing errors and only log them. The vulnerable behavior originates in src/line/webhook.ts:74-83 and src/line/webhook-node.ts:96-107. When the documented execution path is triggered, security controls fail to enforce the expected boundary. Fix approach: enforce secure defaults on this path, validate/guard untrusted inputs at the boundary, and add regression tests that cover the failing scenario.
Affected Code
Instance 1: Express middleware (src/line/webhook.ts)
File: src/line/webhook.ts:74-83
// Respond immediately to avoid timeout
res.status(200).json({ status: "ok" });
// Process events asynchronously
if (body.events && body.events.length > 0) {
logVerbose(`line: received ${body.events.length} webhook events`);
await onEvents(body).catch((err) => {
runtime?.error?.(danger(`line webhook handler failed: ${String(err)}`));
});
}Instance 2: Node.js HTTP handler (src/line/webhook-node.ts)
File: src/line/webhook-node.ts:96-107
// Respond immediately with 200 to avoid LINE timeout
res.statusCode = 200;
res.setHeader("Content-Type", "application/json");
res.end(JSON.stringify({ status: "ok" }));
// Process events asynchronously
if (body.events && body.events.length > 0) {
logVerbose(`line: received ${body.events.length} webhook events`);
await params.bot.handleWebhook(body).catch((err) => {
params.runtime.error?.(danger(`line webhook handler failed: ${String(err)}`));
});
}Steps to Reproduce
- Configure LINE webhook with either middleware path and make
onEvents/bot.handleWebhookthrow (for example, temporary DB or outbound API failure). - Send a valid signed LINE event payload to
/line/webhook. - Observe HTTP response is
200 {"status":"ok"}even though processing throws. - Confirm only local logging occurs and the event is not retried by LINE, resulting in dropped messages.
Recommended Fix
Delay success acknowledgement until processing is durably accepted. Both webhook.ts and webhook-node.ts need the same fix:
- Either process synchronously and return non-2xx on failure.
- Or enqueue to a durable queue first, return 200 only after enqueue succeeds, and return 5xx when enqueue fails.
- Avoid catching-and-swallowing
onEvents/bot.handleWebhookfailures without propagating delivery failure semantics.
Detailed Risk Analysis
CVSS Assessment
| Metric | v3.1 | v4.0 |
|---|---|---|
| Score | 8.2 / 10.0 | 8.8 / 10.0 |
| Severity | High | High |
| Vector | CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:H | CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:L/VA:H/SC:N/SI:N/SA:N |
| Calculator | CVSS v3.1 Calculator | CVSS v4.0 Calculator |
Attack Surface
How is this reached?
- Network (HTTP/WebSocket endpoint, API call)
- Adjacent Network (same LAN, requires network proximity)
- Local (local file, CLI argument, environment variable)
- Physical (requires physical access to machine)
Authentication required?
- None (unauthenticated/public access)
- Low (any authenticated user)
- High (admin/privileged user only)
Entry point: POST /line/webhook via createLineWebhookMiddleware() (webhook.ts) and via createLineNodeWebhookHandler() (webhook-node.ts)
Exploit Conditions
Complexity:
- Low (no special conditions, works reliably)
- High (requires race condition, specific config, or timing)
User interaction:
- None (automatic, no victim action needed)
- Required (victim must click, visit, or perform action)
Prerequisites: LINE webhook is configured and any downstream handler dependency (LLM call, store update, outbound send) throws.
Impact Assessment
Scope:
- Unchanged (impact limited to vulnerable component)
- Changed (can affect other components, escape sandbox)
What can an attacker do?
| Impact Type | Level | Description |
|---|---|---|
| Confidentiality | None | No direct data read exposure. |
| Integrity | Low | Incoming events are acknowledged but not processed, creating state divergence between channel and bot session state. |
| Availability | High | Message handling can fail permanently during transient errors because upstream retries are suppressed by premature 200 responses. |
References
-
CWE: CWE-392 - Missing Report of Error Condition
-
Upstream Source Anchor:
https://github.com/openclaw/openclaw
Exploitability Proof
The LINE webhook handlers return HTTP 200 before event processing finishes, then catch processing errors and only log them. Exploitation is practical under realistic conditions by exercising src/line/webhook.ts:74-83 or src/line/webhook-node.ts:96-107 through the documented flow. The attack does not require speculative assumptions beyond the prerequisites already enumerated in this report.
Mitigation Checks Performed
Checked the controls documented in the report (authentication boundaries, configuration defaults, and runtime guards). None of these controls fully blocks the vulnerable path because the unsafe behavior occurs before or outside those defenses.
Reproduction Evidence
Input/trigger: 1. Configure LINE webhook with either middleware path and make onEvents / bot.handleWebhook throw (for example, temporary DB or outbound API failure).
Observed behavior: The LINE webhook handlers return HTTP 200 before event processing finishes, then catch processing errors and only log them.
Code artifact: src/line/webhook.ts:74-83 and src/line/webhook-node.ts:96-107
Result: the behavior reproduces deterministically with the documented steps and yields the stated security impact.
Why This Is Exploitable (Not Hardening)
This is exploitable rather than hardening-only because the current behavior already enables a concrete attacker outcome (confidentiality, integrity, or availability impact) under realistic prerequisites. The issue is reproducible and security-impacting in the existing implementation, not a hypothetical defense-in-depth improvement.