forked from c-fu/arah2
fix(03-04): HMAC data-check-string excludes only hash — signature field participates (real clients rejected as tampered; erratum M6)
This commit is contained in:
@@ -10,8 +10,14 @@
|
||||
* RED suite's node:crypto signing path, RFC-4231-pinned):
|
||||
* 1. parse `raw` as a Telegram-style querystring (values URL-decoded ONCE;
|
||||
* `+` stays literal — do NOT use URLSearchParams)
|
||||
* 2. dataCheckString = fields minus `hash`/`signature`, sorted by FIELD
|
||||
* 2. dataCheckString = fields minus `hash` ONLY, sorted by FIELD
|
||||
* NAME (byte order, JS default sort), `key=value`, joined with "\n"
|
||||
* (ERRATUM 2026-10-23, device-matrix round 6: the HMAC path must NOT
|
||||
* exclude `signature` — per core.telegram.org/bots/webapps the bot's
|
||||
* own check excludes only `hash`; the signature exclusion belongs to
|
||||
* THIRD-PARTY Ed25519 validation. Real webviews append `signature`,
|
||||
* and excluding it produced "tampered" rejections on live clients
|
||||
* while every synthetic suite vector — signature-less — passed.)
|
||||
* 3. secretKey bytes = HMAC-SHA256(message = utf8(botToken),
|
||||
* key = utf8(the salt constant, line 179))
|
||||
* checkHex = hex(HMAC-SHA256(message = utf8(dataCheckString),
|
||||
@@ -168,9 +174,11 @@ export async function validateInitData(
|
||||
return { ok: false, reason: "malformed" as const };
|
||||
}
|
||||
|
||||
// — data-check-string: hash/signature excluded, sorted by field name —
|
||||
// — data-check-string: hash excluded ONLY (signature participates — the
|
||||
// HMAC spec excludes just `hash`; excluding it broke real clients,
|
||||
// device-matrix round 6) — sorted by field name —
|
||||
const dataCheckString = [...fields.entries()]
|
||||
.filter(([key]) => key !== "hash" && key !== "signature")
|
||||
.filter(([key]) => key !== "hash")
|
||||
.sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0))
|
||||
.map(([key, value]) => `${key}=${value}`)
|
||||
.join("\n");
|
||||
|
||||
Reference in New Issue
Block a user