Skip to content

Phase 0.5: S1 + S2 security hardening - #2

Merged
23Kev merged 2 commits into
mainfrom
fix/phase-0-5-security-hardening
May 13, 2026
Merged

Phase 0.5: S1 + S2 security hardening#2
23Kev merged 2 commits into
mainfrom
fix/phase-0-5-security-hardening

Conversation

@23Kev

@23Kev 23Kev commented May 13, 2026

Copy link
Copy Markdown
Owner

Summary

  • S1 — Allowlist Chromium switches in customSwitches (was free-form passthrough). Dropped names are logged.
  • S2 — Null-guard native SDK pointers (GetTelemetryData, GetTelemetryVarByIndex, GetTelemetryVar); tighten BroadcastMessage arg validation.

Refs docs/ARCHITECTURE_REVIEW.md findings S1 and S2.

Test plan

  • Vitest suite green (775/775)
  • Native addon rebuild + app launch (requires npm run package / forge rebuild)

🤖 Generated with Claude Code

23Kev and others added 2 commits May 13, 2026 05:44
The chromiumFlags storage previously accepted any free-form string in
the `customSwitches` field and replayed every line through
`app.commandLine.appendSwitch()` on next launch. A renderer-side
compromise (XSS, malicious widget, supply chain) could therefore
persist switches like `remote-debugging-port=9222`,
`disable-web-security`, `proxy-server`, `js-flags=--allow-natives-syntax`,
or `user-data-dir=<attacker-path>` that would weaken the security
posture of the next launch.

Fix: introduce CUSTOM_SWITCH_ALLOWLIST in storage/chromiumFlags.ts —
a narrow set of GPU, rendering, scaling, and safe-diagnostic switches
that have a legitimate troubleshooting use. Anything outside the list
is dropped at normalisation time (both save and load paths) and the
dropped names are logged via electron-log. Switches that affect
network behaviour, debugger exposure, JS-engine tuning, extension
loading, profile directories, or the same-origin policy are
deliberately excluded.

The parser is now exported from storage and used by overlayManager,
so the application path and the validation path share a single source
of truth for the syntax.

Addresses finding S1 in docs/ARCHITECTURE_REVIEW.md.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Several entry points in the native N-API addon dereference pointers
returned by the iRacing SDK without checking for NULL, and read
JS-supplied indices and Napi::Value slots without bounds-checking.
Any of these could be reached from JS by calling the wrapper before
iRacing is running, by passing an out-of-range integer, or by passing
a non-numeric argument — and would crash the Electron main process
rather than failing cleanly.

Fixes in this commit:

* GetTelemetryData: irsdk_getHeader() returns NULL until shared memory
  is mapped. The previous code dereferenced header->numVars unguarded.
  Now returns an empty object when the SDK has no header.
* GetTelemetryVarByIndex: irsdk_getVarHeaderEntry() returns NULL for
  indices outside [0, numVars) or when uninitialised; _data is NULL
  until the first telemetry read. Both are now checked. Also adds a
  bounds check on headerVar->type before indexing irsdk_VarTypeBytes.
* GetTelemetryVar (JS entry): fixes a pre-existing uninitialised-
  variable bug where the common numeric-arg path left varIndex with
  stack garbage that flowed into the index-based getter. Now
  initialised to 0 and overwritten from info[0] only when valid.
* GetTelemetryVar (string overload): rejects the -1 return from
  irsdk_varNameToIndex (unknown name / uninitialised SDK) instead of
  passing it to the index-based getter.
* BroadcastMessage: previous guard rejected length <= 2 but then read
  info[3] out of bounds for length-3 calls, and never type-checked
  info[1] or info[2]. Now requires length >= 3 with all three numeric;
  info[3] is read defensively and the two camera-switch variants
  reject when it's missing. Preserves the existing accepted call set
  (the 3-arg ChatCommand/PitCommand/FFBCommand variants in
  irsdk-node.ts still work).

Native code requires `npm run package` (or a forge rebuild) to take
effect — there is no separate electron-rebuild script.

Addresses finding S2 in docs/ARCHITECTURE_REVIEW.md.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@23Kev
23Kev merged commit 23b67f2 into main May 13, 2026
1 check failed
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