From e63f86a603ebae0e7c66f94bfdea69905f36f80c Mon Sep 17 00:00:00 2001 From: Adam Soltys Date: Fri, 4 Sep 2026 19:04:41 -0700 Subject: pos: refuse to flash anything that is not a valid LittleFS image The flasher hex-encoded whatever the /flash endpoint returned, so a server error body was written to devices as the config partition. Check the response status, require a 128KB image with the LittleFS magic, and surface the error above the form instead. Co-Authored-By: Claude Fable 5.1 Claude-Session: https://claude.ai/code/session_014gVYGi29FjTeLdNTiutkZx --- src/routes/(app)/pos/+page.server.ts | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'src/routes/(app)/pos/+page.server.ts') diff --git a/src/routes/(app)/pos/+page.server.ts b/src/routes/(app)/pos/+page.server.ts index 1df1bb33..1e3e1e99 100644 --- a/src/routes/(app)/pos/+page.server.ts +++ b/src/routes/(app)/pos/+page.server.ts @@ -1,6 +1,18 @@ import { PUBLIC_COINOS_URL } from "$env/static/public"; import { auth, fd, get } from "$lib/utils"; import { hex } from "@scure/base"; +import { fail } from "@sveltejs/kit"; + +const LITTLEFS_SIZE = 0x20000; +const LITTLEFS_MAGIC = "littlefs"; + +// A valid image is exactly one partition long and carries the LittleFS +// superblock magic at byte 8. Anything else (e.g. a JSON error body from +// the server) must never reach the flasher. +const isLittleFS = (buf: Uint8Array) => + buf.length === LITTLEFS_SIZE && + new TextDecoder().decode(buf.subarray(8, 8 + LITTLEFS_MAGIC.length)) === + LITTLEFS_MAGIC; export async function load({ cookies }) { let token; @@ -25,6 +37,22 @@ export const actions = { }); const buf = new Uint8Array(await res.arrayBuffer()); + + if (!res.ok) { + let message = `Config server returned ${res.status}`; + try { + message = JSON.parse(new TextDecoder().decode(buf)).message || message; + } catch (e) {} + return fail(res.status >= 400 && res.status < 600 ? res.status : 500, { + error: message, + }); + } + + if (!isLittleFS(buf)) + return fail(500, { + error: `Config server returned an invalid image (${buf.length} bytes)`, + }); + return { bytes: hex.encode(buf) }; }, }; -- cgit v1.2.3