Skip to content

fix: address the two code scanning alerts - #25

Merged
mschmicking merged 2 commits into
mainfrom
fix/code-scanning-alerts
Aug 5, 2026
Merged

fix: address the two code scanning alerts#25
mschmicking merged 2 commits into
mainfrom
fix/code-scanning-alerts

Conversation

@mschmicking

Copy link
Copy Markdown
Owner

Two CodeQL alerts, with opposite conclusions.

test/fake-server.ts:143 — remote property injection (error)

Real dataflow. extendObject pulls partial out of a JSON-parsed websocket frame
and hands it to deepMerge, which writes dest[key] for every key in it, so a
frame carrying __proto__ would have rewritten the prototype rather than setting
a property.

Not a live exposure — the fake server exists only inside the test process and only
ever talks to this repo's own client — but the guard is one line, which beats a
suppression.

src/commands/types.ts:126 — network data written to file (warning)

I suggest dismissing this one as by-design. js/http-to-file-access flags any
remote data reaching the filesystem, and downloading javascript.d.ts into
.iobroker/types/ is precisely what iob-sync types is for. The URL is a
hardcoded HTTPS constant, the destination path is fixed, and a .d.ts is type
information tsc reads but never executes. There is no sanitizer for this rule, so
the alert will probably survive this PR.

It did point sideways at a real bug, though. res.ok is true for any 200 —
including the HTML login page a captive portal or corporate proxy serves. That page
was written straight over a working javascript.d.ts, and the failure surfaces
later as every script in the editor lighting up with TypeScript errors, with nothing
pointing back at iob-sync types.

So, three checks before the write: the announced content-length, the actual body
size, and whether the body contains a declaration at all. Each throws into the
existing catch, which already warns and keeps whatever copy is on disk — so a
portal response now leaves a good cached file intact instead of destroying it.

Known limit: the size cap bounds what reaches disk, not what reaches memory —
res.text() has already buffered the body by then. The content-length check
covers the honest-server case; a server lying about the length could still make the
process buffer a large body. Bounding that properly means streaming the response,
which seemed disproportionate here. Happy to add it if you disagree.

Tests

The download path had no coverage at all — the old file header said so outright. It
now has three cases against a stubbed fetch: the happy path, the portal case
asserting the good copy survives, and the oversize case asserting nothing is
written.

277 tests pass; ESLint and Prettier clean.

🤖 Generated with Claude Code

mschmicking and others added 2 commits August 5, 2026 11:19
The fake server's deepMerge copied every key of the incoming partial straight
onto the destination, and that partial is parsed off a websocket frame. A frame
carrying __proto__ would have rewritten the prototype instead of setting a
property.

Nothing can reach this but the tests themselves, so this is not a live exposure
-- but the guard is one line, which beats teaching CodeQL to ignore the write.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
`res.ok` is true for any 200, including the HTML login page a captive portal or
a corporate proxy serves. That page was written straight over a working
javascript.d.ts, and the damage surfaces later as every script in the editor
lighting up with TypeScript errors -- with nothing pointing back at
`iob-sync types`.

Check three things before the write: the announced content-length, the actual
body size, and that the body contains a declaration at all. Each throws into the
existing catch, which already warns and keeps the copy on disk, so a portal
response now leaves a good cached file intact.

The size cap bounds what reaches the disk, not what reaches memory -- res.text()
has already buffered the body by then. Bounding that too means streaming the
response, which is more than a hardcoded raw.githubusercontent.com URL warrants.

The download had no coverage before; it now has the happy path, the portal case,
and the oversize case, against a stubbed fetch.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@mschmicking
mschmicking merged commit 07ada65 into main Aug 5, 2026
7 checks passed
@mschmicking
mschmicking deleted the fix/code-scanning-alerts branch August 5, 2026 09:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant